在写这篇文章之前想说几句,之前在网上搜了看了很多博客,发现并没有什么用,主要是看了很多人写的逻辑都没有
简直是浪费时间,也不知道他们到底在写什么,没办法,公司要求要用融云来开发聊天,只有自己慢慢去研究开发文档了
还有一点就是作为新手看开发文档根本看不懂,融云平台文档描述得我只想说太恶心了。研究了很久,决定写下这篇文章
希望能帮到大家,有什么错的也希望大家指点一下
代码比较多,我只是说一下思路:如果需要代码的可以去我空间下载,里面包含整个聊天页面和聊天代码
我们先来看看我自己做的效果吧
这个页面是聊天会话页面
点击会话进去后
当然也有表情这些了
任意选择一个发送
对方就可以接受到消息
好了,基本功能就是这样,下面来开始讲解吧。
1.先自己去融云平台注册登录融云,获取appkey
2.下面就开始代码了,因为我做的是java后台,比如app端和我们聊天,或者电脑对电脑聊天:这里先说一下思路
如果对方和我聊天,他首先要得到我的ID(id是唯一的)才能发消息给我,我回对方消息也要得到对方id,其实ID就是
我们数据库中存放用户的主键ID。所有我们还有在后台服务写一个获取token的方法
A:先导入荣云的jar包或者依赖,我这里是maven项目,所有直接依赖
<!--融云 -->
<dependency>
<groupId>cn.rongcloud.im</groupId>
<artifactId>server-sdk-java</artifactId>
<version>3.0.2</version>
</dependency>
B:在后台写用户注册获取token的方法 appKey ,appSecret 不能写错了,这个是你注册上面的
/**
* 此处替换成您的appKey
* */
private static final String appKey = "p5tvi9dsph3i4";
/**
* 此处替换成您的appSecret
* */
private static final String appSecret = "XZURH7ezOdx";
/**
* 自定义api地址 可有可无
* */
private static final String api = "http://api.cn.ronghub.com";
//测试用户注册
@SuppressWarnings("unchecked")
@RequestMapping(value = "/admin/testGetToken",method = { RequestMethod.GET,RequestMethod.POST })
@ResponseBody
public WebResult testGetToken(HttpServletRequest request,HttpSession session,
@RequestParam(value = "userid", defaultValue = "") String userid,//APP用户ID 也就是你登录是你的ID或者对方用户id
@RequestParam(value = "username", defaultValue = "") String username,//APP用户姓名 也就是你登录是你的姓名或者对 方用户姓名
@RequestParam(value = "portrait", defaultValue = "") String portrait //APP用户头像 你的头像,或者对方的头像,没有就随便传就行了
)
throws Exception {
String managerid= session.getAttribute("managerid").toString();
WebResult webResult=null;
TblManagerInfo managerInfo=null;//这个是我自己存放用户的表
Map<String, Object> map=WebUtil.getHashMap();//得到map集合
try {
RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret);
//自定义 api 地址方式
// RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api);
User User = rongCloud.user;
/**
* API 文档: http://www.rongcloud.cn/docs/server_sdk_api/user/user.html#register
*
* 注册用户,生成用户在融云的唯一身份标识 Token
*/
//得到用户实体,生成token 注意:如果是对方和你聊天他获取根据自己的基本信息获取token之后还要返回你
自己的id给他,才能发消息给你的。如果是你先找对方聊天那么就返回对方的ID给你,这里的逻辑自己去处理了
managerInfo=(TblManagerInfo) baseService.findById(TblManagerInfo.class, Long.valueOf(managerid));
if(StringUtils.isEmpty(portrait))portrait="1.jpg";//如果头像为空,则设置为默认的头像
UserModel user = new UserModel()
.setId(managerid)
.setName(managerInfo.getLinkman())
.setPortrait(portrait);
TokenResult result = User.register(user);
System.out.println(result.toString());
map.put("token", result.getToken());//返回的token
map.put("sellerid", 1);//返回的你自己的id 或对方的ID
return WebResult.success("请求成功", map);
} catch (Exception e) {
e.printStackTrace();
webResult=WebResult.error("服务正忙", null);
}
return webResult;
}
3.现在开始前端的代码吧,先引入融云js,不然什么效果都没有
<!--引入表情js -->
<script src="http://cdn.ronghub.com/RongEmoji-2.2.7.min.js"></script>
<!-- 引入融云js -->
<script src="http://cdn.ronghub.com/RongIMLib-2.2.5.min.js"></script>
A:一开始加载页面时就要去获取token,才能链接上融云,得到token之后我们再去初始化融云链接融云
B:看一下init()初始化方法,绿色的部分是直接复制就可以用的,和开发文档上面的一样,主要是链接融云,和随时有对方给你发消息的监听,监听到消息之后你直接把监听到的消息显示在页面上就行了
/初始化连接融云
function init(token){
RongIMLib.RongIMClient.init('p5tvi9dsph3i4');// p5tvi9dsph3i4是你自己注册在融云的appkey,上面已经介绍过了
// 连接状态监听器
RongIMClient.setConnectionStatusListener({
onChanged: function (status) {
// status 标识当前连接状态
switch (status) {
case RongIMLib.ConnectionStatus.CONNECTED:
console.log('链接成功');
break;
case RongIMLib.ConnectionStatus.CONNECTING:
console.log('正在链接');
break;
case RongIMLib.ConnectionStatus.DISCONNECTED:
console.log('断开连接');
break;
case RongIMLib.ConnectionStatus.KICKED_OFFLINE_BY_OTHER_CLIENT:
console.log('其他设备登录');
break;
case RongIMLib.ConnectionStatus.DOMAIN_INCORRECT:
console.log('域名不正确');
break;
case RongIMLib.ConnectionStatus.NETWORK_UNAVAILABLE:
console.log('网络不可用');
break;
}
}
});
RongIMClient.connect(token, {
onSuccess: function(userId) {
console.log('Connect successfully. ' + userId);
getConversationList();//连接成功之后我们要去获取会话列表,也就是获取所有会话聊天的消息,此方法在下面有
},
onTokenIncorrect: function() {
console.log('token 无效');
},
onError: function(errorCode){
var info = '';
switch (errorCode) {
case RongIMLib.ErrorCode.TIMEOUT:
info = '超时';
break;
case RongIMLib.ConnectionState.UNACCEPTABLE_PAROTOCOL_VERSION:
info = '不可接受的协议版本';
break;
case RongIMLib.ConnectionState.IDENTIFIER_REJECTED:
info = 'appkey不正确';
break;
case RongIMLib.ConnectionState.SERVER_UNAVAILABLE:
info = '服务器不可用';
break;
}
console.log(info);
}
});
//消息监听器
RongIMClient.setOnReceiveMessageListener({
// 接收到的消息
onReceived: function (message) {
// 判断消息类型
switch(message.messageType){
case RongIMClient.MessageType.TextMessage:
massagecount++;
massagecontent=message.content.content;
massagetargetId=message.targetId;
//$("#"+massagetargetId).html("");
// message.content.content => 文字内容
console.log("消息监听:"+JSON.stringify(message));
console.log("消息监听:"+message.content.content);
break;
case RongIMClient.MessageType.VoiceMessage:
// message.content.content => 格式为 AMR 的音频 base64
console.log("消息监听:"+message.content.content);
break;
case RongIMClient.MessageType.ImageMessage:
console.log("消息监听:"+message.content.content);
// message.content.content => 图片缩略图 base64
// message.content.imageUri => 原图 URL
break;
case RongIMClient.MessageType.LocationMessage:
console.log("消息监听:"+message.content.content);
// message.content.latiude => 纬度
// message.content.longitude => 经度
// message.content.content => 位置图片 base64
break;
case RongIMClient.MessageType.RichContentMessage:
console.log("消息监听:"+message.content.content);
// message.content.content => 文本消息内容
// message.content.imageUri => 图片 base64
// message.content.url => 原图 URL
break;
case RongIMClient.MessageType.InformationNotificationMessage:
console.log("消息监听1:");
// do something
break;
case RongIMClient.MessageType.ContactNotificationMessage:
console.log("消息监听2:");
// do something
break;
case RongIMClient.MessageType.ProfileNotificationMessage:
console.log("消息监听3:");
// do something
break;
case RongIMClient.MessageType.CommandNotificationMessage:
console.log("消息监听4:");
// do something
break;
case RongIMClient.MessageType.CommandMessage:
console.log("消息监听5:");
// do something
break;
case RongIMClient.MessageType.UnknownMessage:
console.log("消息监听6:");
// do something
break;
default:
console.log("消息监听7:");
// do something
}
}
});
// 表情初始化
RongIMLib.RongIMEmoji.init();
var list = RongIMLib.RongIMEmoji.list;
initBiaoqing(list);
}
C:上面连接成功后开始获取会话 :注意,红色的是我自己页面的html,和文档无关,其它都是开发文档上面的
//获取会话列表
function getConversationList(){
$(".chatBox-list").html("");
RongIMClient.getInstance().getConversationList({
onSuccess: function(list) {
// list => 会话列表集合
//console.log("回话列表:"+JSON.stringify(list));
var i=1;
var name="持之以恒";
var icon="../massage/img/icon01.png";
var unreadMessageCountTotal=0;//总会话未读消息数量
$.each(list,function(index,item){
i++;
//name=item.latestMessage.content.user.name;//对方昵称
//icon=item.latestMessage.content.user.icon;//对方头像
//console.log(item.unreadMessageCount);//未读消息数"'+item.targetId+'"
//这里就开始循环添加会话去页面显示了
$(".chatBox-list").append('<div id="'+i+'" class=\"chat-list-people\" onclick="getHistoryMessages(\''+item.targetId+'\',\''+i+'\',\''+name+'\',\''+icon+'\');" >'
+'<div><img src=\"'+icon+'\"/></div>'
+'<div class=\"chat-name\">'
+' <div style=\"margin-top: 4%;font-weight:bold;"\>'+name+'</div>'
+' <div style=\"text-overflow:ellipsis;white-space:nowrap;overflow:hidden;\" class=\"'+item.targetId+'\" >'+RongIMLib.RongIMEmoji.symbolToHTML(item.latestMessage.content.content)+'</div>'
+'</div>'
//+'<div class=\"message-num\">'+item.unreadMessageCount+'</div>'
+'<div class=\"clear-massage\" ><img onclick="removeConversation(\''+item.targetId+'\');" src=\"../images/删除图标.jpg\" class=\"clear-img\" style=\" vertical-align:middle;\"/></div>'
+'</div>');
if(item.unreadMessageCount!=0){
$(".chat-name").after('<div class=\"message-num\">'+item.unreadMessageCount+'</div>');
}else{
$(".chat-name").after('<div class=\"message-num\">0</div>');
}
unreadMessageCountTotal+=item.unreadMessageCount;
})
$(".chat-message-num").html(unreadMessageCountTotal);//设置总未读消息提示
},
onError: function(error) {
// do something
}
}, null);
}
// 清除未读消息成功 上面说清除未读消息的方法
function clearUnreadCount(targetId){
var conversationType = RongIMLib.ConversationType.PRIVATE;//二人聊天 PRIVATE
var targetId = targetId;
RongIMClient.getInstance().clearUnreadCount(conversationType, targetId, {
onSuccess: function(){
// 清除未读消息成功
console.log("清除成功");
},
onError: function(error){
// error => 清除未读消息数错误码
console.log("清除失败:"+error);
}
});
}
4.得到会话之后。肯定有消息提示了,下一步就是我们点击会话进入聊天页面 targetId是对方的id
A:这是要获取两个人的聊天记录 getHistoryMessages(targetId,id,name,icon),改方法是上面循环会话是已经添加好的,点击会 话就执行这个方法得到两个人的聊天记录,点击进入之后要把未读消息数量清空为0
//单击回话列表获取二人历史消息targetId
var reflushHistoryMessagesId=1000;
function getHistoryMessages(targetId,id,name,icon){
$("#chatBox-content-demo").html("");
var conversationType = RongIMLib.ConversationType.PRIVATE; //PRIVATE 单聊, CUSTOMER_SERVICE客户会话 其他会话选择相应的消息类型即可
var targetId = targetId; // 想获取自己和谁的历史消息,targetId 赋值为对方的 Id
var timestrap = 0; // 默认传 null,若从头开始获取历史消息,请赋值为 0, timestrap = 0; 开始获取只能从 0开始,不然每次点击返回会话页面再到聊天页面都是循环获取历史消息
var count = 20; // 每次获取的历史消息条数,范围 0-20 条,可以多次获取
RongIMLib.RongIMClient.getInstance().getHistoryMessages(conversationType, targetId, timestrap, count, {
// list => Message 数组。
// hasMsg => 是否还有历史消息可以获取。
onSuccess: function(list, hasMsg) {
//console.log(JSON.stringify(list));
var html="";
//判断是否有历史消息获取
if(hasMsg){
html+='<div class="reflushHistoryMessages" id="'+reflushHistoryMessagesId+'" style="text-align: center;" onclick="reflushHistoryMessages(\''+targetId+'\',\''+id+'\',\''+name+'\',\''+icon+'\',\''+reflushHistoryMessagesId+'\');" ><a>查看历史消息</a></div>';
}if(!hasMsg){
//去掉查看历史消息div
$(".reflushHistoryMessages").remove();
html+='<div class="reflushHistoryMessages" style="text-align: center;" >暂无历史消息</div>';
}
var clearfloatid=-1000;
$.each(list,function(index,item){
clearfloatid++;
//拼接内容
//用户消息
//messageDirection 1 为发送的消息、2 为接收的消息。
//RongIMLib.RongIMEmoji.symbolToHTML如果是表情消息就显示表情
if(item.messageDirection=="2"){
html+='<div class=\"clearfloat\" >'
+' <div class="author-name">'
+' <small class="chat-date">'+transformTime(item.sentTime)+'</small>'
+' </div>'
+'<div class="left">'
+' <div class="chat-avatars"><img src=\"'+icon+'\" alt="头像"/></div>'
+' <div class="chat-message">'
+' '+RongIMLib.RongIMEmoji.symbolToHTML(item.content.content)+' '
+' </div>'
+' </div>'
+'</div>';
}//自己发的消息
else if (item.messageDirection=="1"){
html+='<div class="clearfloat" id="'+clearfloatid+'" onmousedown="chehui('+index+',\''+clearfloatid+'\',\''+item.messageUId+'\');">'
+' <div class="author-name">'
+' <small class="chat-date">'+transformTime(item.sentTime)+'</small>'
+' </div>'
+'<div class="right">'
+' <div class="chat-message">'+RongIMLib.RongIMEmoji.symbolToHTML(item.content.content)+'</div>'
+' <div class="chat-avatars"><img src="../massage/img/icon02.png" alt="头像"/></div>'
+' </div>'
+'</div>';
}
});
//显示两个聊天页面
$("#chatBox-content-demo").append(html);
html="";
//设置接收人sendtargetId
$("#sendtargetId").val(targetId);
var n = $("#"+id).index();
$(".chatBox-head-one").toggle();
$(".chatBox-head-two").toggle();
$(".chatBox-list").fadeToggle();
$(".chatBox-kuang").fadeToggle();
//传名字
$(".ChatInfoName").text(name);
//传头像
$(".ChatInfoHead>img").attr("src", icon);
//聊天框默认最底部
$(document).ready(function () {
$("#chatBox-content-demo").scrollTop($("#chatBox-content-demo")[0].scrollHeight);
});
//清除未读消息
clearUnreadCount(targetId);
},
onError: function(error) {
console.log('GetHistoryMessages, errorcode:' + error);
}
});
}
5.进入聊天页面之后,肯定就是发消息给对方了
//发送二人聊天消息 textContent:消息内容 targetId:对方ID
function sendmassage(textContent,targetId){
var msg = new RongIMLib.TextMessage({ content: textContent, extra: '附加信息' });
var conversationType = RongIMLib.ConversationType.PRIVATE; // 单聊 PRIVATE CUSTOMER_SERVICE客户会话, 其他会话选择相应的消息类型即可
var targetId = targetId; // 目标 Id
console.log("targetId--"+targetId+" textContent"+textContent);
var index=0;
var clearfloatid=1;
RongIMClient.getInstance().sendMessage(conversationType, targetId, msg, {
onSuccess: function (message) {
// message 为发送的消息对象并且包含服务器返回的消息唯一 Id 和发送消息时间戳
console.log('targetId:'+targetId+'--发送成功!');
//成功后追加消息在列表框
$(".chatBox-content-demo").append("<div class=\"clearfloat\" onmousedown='chehui("+index+",\""+clearfloatid+"\",\""+targetId+"\");' >" +
"<div class=\"author-name\"><small class=\"chat-date\">"+transformTime(new Date())+"</small> </div> " +
"<div class=\"right\"> <div class=\"chat-message\"> " +RongIMLib.RongIMEmoji.symbolToHTML(textContent) + " </div> " +
"<div class=\"chat-avatars\"><img src=\"../massageimg/icon01.png\" alt=\"头像\" /></div> </div> </div>");
//发送后清空输入框
$(".div-textarea").html("");
//聊天框默认最底部
$(document).ready(function () {
$("#chatBox-content-demo").scrollTop($("#chatBox-content-demo")[0].scrollHeight);
});
},
onError: function (errorCode, message) {
var info = '';
switch (errorCode) {
case RongIMLib.ErrorCode.TIMEOUT:
info = '超时';
break;
case RongIMLib.ErrorCode.UNKNOWN:
info = '未知错误';
break;
case RongIMLib.ErrorCode.REJECTED_BY_BLACKLIST:
info = '在黑名单中,无法向对方发送消息';
break;
case RongIMLib.ErrorCode.NOT_IN_DISCUSSION:
info = '不在讨论组中';
break;
case RongIMLib.ErrorCode.NOT_IN_GROUP:
info = '不在群组中';
break;
case RongIMLib.ErrorCode.NOT_IN_CHATROOM:
info = '不在聊天室中';
break;
}
console.log('发送失败: ' + info + errorCode);
alert('发送失败: ' + info + errorCode);
}
});
}
6.发送成功之后。对方会监听到消息,也就是我们开始链接融云,上面说的监听消息,监听到之后直接处理消息就行了