Java后台集成融云即时通讯IM

由于公司需求,需要使用融云开发一个客服和用户的单聊模式的聊天功能,看了一天的文档才摸清楚接入流程,这里记录一下用Java后台系统集成融云即时通讯IM的流程,以防以后用到忘记了。

不管是Web、Android、iOS、小程序,哪个端需要做出聊天功能,如果是一套完成的即时通讯项目,都需要后台服务端的支持,我的项目就是Java搭建的后台,直接上流程吧!!
很多同学私信我要源码,其实按照文章的步骤集成完成可以成功,如果需要源码的直接去下载吧demo_rongyun.rar
一:在融云注册一个账号,创建IM的应用,这是前提,只有创建了应用才有App Key、App Secret。
1.访问
https://developer.rongcloud.cn/signup


使用手机号注册账户。
2. 填写企业名称和邮箱地址。
3. 进行邮箱验证。
4. 在开发者后台点击 服务管理
5. 选择对应环境的 AppKey

二:有了appKey,appSecret之后,可以撸代码了。此步骤是搭建后台,提供获取token接口给各前端。
1.后台我的框架就是一个springboot项目,请自行创建项目,pom.xml里面引入融云的依赖包

<dependency><groupId>cn.rongcloud.im</groupId><artifactId>server-sdk-java</artifactId><version>3.1.6</version>
</dependency>

2.创建一个UserService类,主要作用是获取token,

生成用户在融云的唯一身份标识 Token,客户端在使用融云通讯能力前必须获取 Token,融云 SDK
每次连接服务器时,都需要向融云服务器提供 Token,以便验证身份。

意思就是各端通过SDK调用各种方法功能的时候,都需要token,才能调成功,所以我们后台需要写一个获取token的接口,供各端使用!(至于为什么各端不自己去获取token,这个问题,自己可以百度咨询,安全问题哈所以放在后台获取),

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import io.rong.RongCloud;
import io.rong.methods.user.User;
import io.rong.models.Result;
import io.rong.models.response.TokenResult;
import io.rong.models.response.UserResult;
import io.rong.models.user.UserModel;@Service
public class UserService {private static final Logger logger = LoggerFactory.getLogger(UserService.class);private static String appKey = "你刚才注册的appKey";private static String appSecret = "你刚才注册的appSecret";/*** 自定义api地址*/@SuppressWarnings("unused")private static String api = "http://api-cn.ronghub.com";/*** API 文档: http://www.rongcloud.cn/docs/server_sdk_api/user/user.html#register*  注册用户,生成用户在融云的唯一身份标识 Token* @param     userModel id、name、portrait三个参数必传* @return  Result*/public TokenResult getToken(UserModel userModel) throws Exception {RongCloud rongCloud;if(null == rongCloudIMProperties) {rongCloud = RongCloud.getInstance(appKey, appSecret);}else {rongCloud = RongCloud.getInstance(rongCloudIMProperties.getAppKey(), rongCloudIMProperties.getAppSecret());}// 自定义 api 地址方式// RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api);// 使用 百度 HTTPDNS 获取最快的 IP 地址进行连接// BaiduHttpDNSUtil.setHostTypeIp("account_id", "secret", rongCloud.getApiHostType());// 设置连接超时时间// rongCloud.getApiHostType().setConnectTimeout(10000);// 设置读取超时时间// rongCloud.getApiHostType().setReadTimeout(10000);// 获取备用域名List// List<HostType> hosttypes = rongCloud.getApiHostListBackUp();// 设置连接、读取超时时间// for (HostType hosttype : hosttypes) {//     hosttype.setConnectTimeout(10000);//     hosttype.setReadTimeout(10000);// }User user = rongCloud.user;TokenResult result = user.register(userModel);logger.info("getToken:  " + result.toString());return result;}}
/*** 融云IM配置映射类*/
@Component
@ConfigurationProperties(prefix = "rongcloud.im")
public class RongCloudIMProperties {private String appKey;private String appSecret;public String getAppKey() {return appKey;}public void setAppKey(String appKey) {this.appKey = appKey;}public String getAppSecret() {return appSecret;}public void setAppSecret(String appSecret) {this.appSecret = appSecret;}@Overridepublic String toString() {return "RongCloudIMProperties{" +"appKey:'" + appKey + '\'' +", appSecret:" + appSecret +'}';}
}

application.yml配置

rongcloud:im:appKey: ***********appSecret: *********

3.创建一个UserController类,供各端接口调用

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.rong.models.response.TokenResult;
import io.rong.models.user.UserModel;@RestController
@RequestMapping("/v1/api/user")
public class UserController extends BaseController {private static final Logger logger = LoggerFactory.getLogger(UserController.class);@Autowiredprivate UserService userService;/*** 根据userId,userName获取token* @param userId* @param userName* @return*/@GetMapping("/getToken")public String getToken(String userId,String userName) {logger.info("enter into getToken function......");logger.info("======userId:{}=======userName:{}", userId, userName);if(StringUtils.isEmpty(userId) || StringUtils.isEmpty(userName)) {return responseJson("99","userId、userName请求参数都不能为空",null);}UserModel userModel = new UserModel();userModel.setId(userId);userModel.setName(userName);userModel.setPortrait("http://www.rongcloud.cn/images/logo.png");TokenResult result;try {result = userService.getToken(userModel);} catch (Exception e) {logger.error("获取 Token 失败 ", e);return responseJson("999","获取 Token 失败",null);}return responseJson("00","请求成功",result);}public String responseJson(String code,String msg,Object obj){Map<String, Object> res = new HashMap<>();res.put("code", code);res.put("msg", msg);if (obj == null) {obj = new Object();}res.put("data", obj);String ret = JSONObject.toJSONString(res,SerializerFeature.WriteMapNullValue,SerializerFeature.DisableCircularReferenceDetect,SerializerFeature.PrettyFormat,SerializerFeature.SortField);logger.info("RESPONSE:" + ret);return ret;}
}

三: 前端开发,其实融云提供了各个端的demo代码,我这边主要是记录接入流程,简便为主,哈哈,用的H5+JQuery手工做了一个demo。
由于不是专业前端,所以demo没有样式可言,只是功能。我这边做了2个页面,模拟了一个客服聊天页面,一个用户聊天页面。

客服端页面:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="format-detection" content="telephone=no"/><meta name="apple-mobile-web-app-capable" content="yes"/><title>客服坐席端</title><script src="https://apps.bdimg.com/libs/jquery/1.11.3/jquery.min.js"></script><script src="http://cdn.ronghub.com/RongIMLib-3.0.5-dev.js"></script><script type="text/javascript">var connectflag = false;$(document).ready(function(){var im = RongIMLib.init({appkey: '你刚才注册的appKey'});var conversationList = []; // 当前已存在的会话列表im.watch({conversation: function(event){var updatedConversationList = event.updatedConversationList; // 更新的会话列表console.log('更新会话汇总:', updatedConversationList);console.log('最新会话列表:', im.Conversation.merge({conversationList,updatedConversationList}));},message: function(event){var message = event.message;console.log('收到新消息:', message);$('#jsmsg').val(message.content.content);},status: function(event){var status = event.status;console.log('连接状态码:', status);}});/* 开发者后台获取或 Server API */var user = {token: ''};$.ajax({url: "http://localhost:8080/v1/api/user/getToken",data:{"userId":'kyy_kf_1',"userName":'客服坐席1号'},type: "GET",error:function (data) {console.log(data);},success:function (data) {console.log(data);var code = data.code;if('00' == code){user.token = data.data.token;}}});im.connect(user).then(function(user) {console.log('链接成功, 链接用户 id 为: ', user.id);connectflag = true;}).catch(function(error) {console.log('链接失败: ', error.code, error.msg);});$('#send').click(function() {if(connectflag){var conversation = im.Conversation.get({targetId: 'kyy_yh_1',// 用户的suerIDtype: RongIMLib.CONVERSATION_TYPE.PRIVATE});conversation.send({messageType: RongIMLib.MESSAGE_TYPE.TEXT, // 'RC:TxtMsg'content: {content: $('#fsmsg').val() // 文本内容}}).then(function(message){console.log('发送文字消息成功', message);});}});});</script></head><body><h2>客服坐席聊天</h2>输入聊天消息:<input id="fsmsg" type="text" /><input id="send" type="button" value="发送"/><br/>接收到的消息:<input id="jsmsg" type="text" /></body>
</html>

用户端页面:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="format-detection" content="telephone=no"/><meta name="apple-mobile-web-app-capable" content="yes"/><title>用户端</title><script src="https://apps.bdimg.com/libs/jquery/1.11.3/jquery.min.js"></script><script src="http://cdn.ronghub.com/RongIMLib-3.0.5-dev.js"></script><script type="text/javascript">var connectflag = false;$(document).ready(function(){var im = RongIMLib.init({appkey: '你刚才注册的appKey'});var conversationList = []; // 当前已存在的会话列表im.watch({conversation: function(event){var updatedConversationList = event.updatedConversationList; // 更新的会话列表console.log('更新会话汇总:', updatedConversationList);console.log('最新会话列表:', im.Conversation.merge({conversationList,updatedConversationList}));},message: function(event){var message = event.message;console.log('收到新消息:', message);$('#jsmsg').val(message.content.content);},status: function(event){var status = event.status;console.log('连接状态码:', status);}});/* 开发者后台获取或 Server API */var user = {token: ''};$.ajax({url: "http://localhost:8080/v1/api/user/getToken",data:{"userId":'kyy_yh_1',"userName":'用户1号'},type: "GET",error:function (data) {console.log(data);},success:function (data) {console.log(data);var code = data.code;if('00' == code){user.token = data.data.token;}}});im.connect(user).then(function(user) {console.log('链接成功, 链接用户 id 为: ', user.id);connectflag = true;}).catch(function(error) {console.log('链接失败: ', error.code, error.msg);});$('#send').click(function() {if(connectflag){var conversation = im.Conversation.get({targetId: 'kyy_kf_1',// 客服坐席的userIDtype: RongIMLib.CONVERSATION_TYPE.PRIVATE});conversation.send({messageType: RongIMLib.MESSAGE_TYPE.TEXT, // 'RC:TxtMsg'content: {content: $('#fsmsg').val() // 文本内容}}).then(function(message){console.log('发送文字消息成功', message);});}});}); </script></head><body><h2>用户端聊天</h2>输入聊天消息:<input id="fsmsg" type="text" /><input id="send" type="button" value="发送"/><br/>接收到的消息:<input id="jsmsg" type="text" /></body>
</html>

四:页面开发好后,可以收发消息了,这些消息的数据,按理来说应该入库。
1.此时就需要再融云的控制台配置消息回调了。

我这里只配置了一个文本消息的回调,一切都是为了实现集成流程,真实项目里肯定是根据业务场景个性化配置。
2.后台创建IMCallBackApiController类,添加回调接口

import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.json.JSONObject;@Controller
@RequestMapping("/v1/api/im")
public class IMCallBackApiController {private static final Logger logger = LoggerFactory.getLogger(IMCallBackApiController.class);/*** 接收即时通讯IM消息回调* @param request* @param appKey       应用 App Key* @param fromUserId  发送用户 Id。* @param targetId      目标会话 Id,根据会话类型可能为单聊 Id、群聊 Id、聊天室 Id。* @param msgType        消息类型,文本消息 RC:TxtMsg 、 图片消息 RC:ImgMsg 其他消息类型请参见消息类型说明文档。* @param content     发送消息内容* @param channelType 会话类型,二人会话是 PERSON 、讨论组会话是 PERSONS 、群组会话是 GROUP 、聊天室会话是 TEMPGROUP 。* @param msgTimeStamp 服务端收到客户端发送消息时的服务器时间(1970年到现在的毫秒数)。* @param messageId     消息唯一标识。* @return JSONObject    { "pass": 1 }   1 表示正常下发此条消息,0 表示拒绝不下发此条消息。*/@PostMapping("/callBackEvent")@ResponseBodypublic JSONObject callBackEvent(HttpServletRequest request,String appKey,String fromUserId,String targetId,String msgType,String content,String channelType,String msgTimeStamp,String messageId) {logger.info("callBackEvent function startTime:{}", System.currentTimeMillis());logger.info("----------收到IM 给到的回调消息appKey={},  fromUserId={},targetId={},msgType={},content={},channelType={},msgTimeStamp={},messageId={}-----------", appKey, fromUserId, targetId, msgType, content, channelType, msgTimeStamp, messageId);JSONObject ret = new JSONObject() {{put("pass", 1);}};try {HandleCallBackMsg handleCallBackMsg = HandleCallBackMsg.builder().appKey(appKey).fromUserId(fromUserId).targetId(targetId).msgType(msgType).content(content).channelType(channelType).msgTimeStamp(msgTimeStamp).messageId(messageId).build();//TO-DO handleCallBackMsg 实体类里就是回调的所有数据,此时就是根据自己的项目 串行或者异步把消息入库或者别的业务逻辑} catch (Exception e) {logger.error(e.getMessage(), e);ret.put("pass", 0);}logger.info("callBackEvent function endTime:{}", System.currentTimeMillis());return ret;}}

3.HandleCallBackMsg实体类

import lombok.Builder;
import lombok.Data;
import lombok.experimental.Tolerate;@Data
@Builder
public class HandleCallBackMsg {/** 应用 App Key*/private String appKey;/** 发送用户 Id。*/private String fromUserId;/** 目标会话 Id,根据会话类型可能为单聊 Id、群聊 Id、聊天室 Id。*/private String targetId;/** 消息类型,文本消息 RC:TxtMsg 、 图片消息 RC:ImgMsg 其他消息类型请参见消息类型说明文档。*/private String msgType;/** 发送消息内容*/private String content;/** 会话类型,二人会话是 PERSON 、讨论组会话是 PERSONS 、群组会话是 GROUP 、聊天室会话是 TEMPGROUP 。*/private String channelType;/** 服务端收到客户端发送消息时的服务器时间(1970年到现在的毫秒数)。*/private String msgTimeStamp;/** 消息唯一标识。*/private String messageId;@Toleratepublic HandleCallBackMsg() {}
}

总结:
以上就完成了最基础的Web+后台集成融云IM单聊收发消息的功能,聊天的消息是各端直接调用SDK和融云交互,然后融云又通过异步的消息回调把消息推送给我们的后台系统,这样就实现了即时通讯的解耦,体现了用第三方插件完成实时通讯的业务需求。
看下效果吧



Java后台集成融云即时通讯IM相关推荐

  1. 项目中集成融云即时通讯

    http://blog.csdn.net/qq_28759359/article/details/52689948 项目中集成融云IM,能够单聊,离线能够收到消息,有聊天列表. 一我使用的是融云. I ...

  2. iOS集成融云即时通讯详细教程

    相关集成方法也可以直接参考官方文档http://www.rongcloud.cn/docs/ios.html.下面是我集成过程中的一些详细步骤. 1.准备工作:到官网http://www.rongcl ...

  3. iOS开发融云即时通讯集成详细步骤

    1.融云即时通讯iOS SDK下载地址   http://rongcloud.cn/downloads  选择iOS   SDK下载 2.进行应用开发之前,需要先在融云开发者平台创建应用,如果您已经注 ...

  4. 融云即时通讯SDK集成 – 定制UI(二) ——添加自定义表情库

    融云即时通讯SDK集成 – 定制UI(二) --添加自定义表情库 背景: 最近公司新上的app要加上即时通讯的功能, 自己快速实现一个当然是不可能的了(项目deadline也顶不住哇).就从各家成熟的 ...

  5. 融云即时通讯云平台获北京六局委新技术新产品认证

    近日,融云即时通讯云平台成功入选第七批北京市新技术新产品(服务)认证,成为本批次中即时通讯行业唯一入选企业.该证书是由北京市科学技术委员会.北京市发展改革委员会.北京市经济和信息化委员会.北京市住房和 ...

  6. 融云即时通讯之直播聊天室

    前言 做直播当然少不了聊天功能,融云直播聊天室支持消息类型包括文字.语音.图片.点赞.礼物.弹幕等,也支持通过自定义消息实现自已的业务逻辑:支持聊天室用户管理功能,包括创建.加入.销毁.禁言.查询.封 ...

  7. 记录一下融云即时通讯IM

    通过apicloud开发app,集成融云的sdk开发IM聊天系统 1初始化融云,显示聊天列表 var rong var header_h = 50 var footer_h = 45 var toUs ...

  8. iOS:融云即时通讯快速集成

    一.介绍 即时通讯在众多社交软件.生活软件以及教育软件中已经是必备的功能了,在当前国内,即时通讯SDK做的比较不错的有那么几家,例如环信SDK.融云SDK...,这两家做的都很不错,各有千秋吧,要是真 ...

  9. 融云即时通讯SDK集成 -- 定制UI(二) ——添加自定义表情库

    背景: 最近公司新上的app要加上即时通讯的功能, 自己快速实现一个当然是不可能的了(项目deadline也顶不住哇).就从各家成熟的SDK厂商选来选去的, 各有各的好也各有各的不足.最后点兵点将,选 ...

  10. 融云聊天 php_thinkphp整合系列之融云即时通讯在线聊天

    随着技术的发展:现代的网站:越来越趋于应用形式了: 不再是像以前那样需要用户刷新页面:获取数据了: 服务器端可以主动向用户推送数据:更加及时性了: 比较突出的就是即时通讯在线聊天: 今个:我们要打造的 ...

最新文章

  1. 超详细单机版搭建hadoop环境图文解析
  2. smartform四联纸跳页问题
  3. 读阿里许令波老师晋升评审有感
  4. 从零单排学Redis【白银】
  5. 解决fatal: 不是一个 git 仓库(或者任何父目录)的方法
  6. 突破边界局限,阿里云神龙负责人张献涛分享15年虚拟化之路
  7. Kali Linux 2019.4用U盘安装以及解决Kali Linux 2019.4中文乱码问题
  8. python文件处理,将DNA序列转换为RNA序列
  9. linux shell脚本 main,Linux shell启动Java Main函数脚本
  10. Tableau如何动态显示销售数据排名
  11. 本台计算机控制网速,笔记本网速限制(笔记本电脑限制网速怎么设置)
  12. PPT动画教程:修改幻灯片母板
  13. 黄金分割点(java)
  14. Python爬取斗鱼弹幕——多房间同时抓取实现(一)
  15. 个人网站真能转成商业网站,你能么?
  16. Clark变换与Park
  17. Halide(win10vs2019环境搭建)小试牛刀
  18. cuda8.0+ubuntu14.04+GTX970驱动 安装
  19. 如何关闭“若要接收后续 google chrome 更新,您需使用 windows 10 或更高版本”
  20. lg g5 h868 android 7,LG G5 (H868)全网通智能手机

热门文章

  1. 树莓派开机自动运行_树莓派程序开机自启动方法总结
  2. DM8168 开机自动运行程序
  3. (转载)人工智能在围棋程序中的应用——复旦大学附属中学(施遥)
  4. 在linux系统下忘记了root密码,教你在Linux系统中解决忘记root口令密码的方法
  5. 原来安卓手机安装谷歌服务框架这么简单!
  6. 六维空间等IPV6资源上不去的一种解决方法
  7. 艺术签名软件 3.0 绿色版
  8. 清洁机器人--屏幕显示LCD方案之MCU SPI 接口驱动ST7789 LCD显示
  9. 仿vista桌面小工具
  10. 重邮学报和计算机工程与应用,重庆邮电大学学报