类似于斗鱼直播间的聊天
直播.png
接入第三方IM,大部分功能实现依赖于前端。后端侧重于创建群组的时机,以及考虑群组解散的时机(如果有合理的退群机制和定期清理群人数的机制,当我没说,不用考虑解散群组机制。因为对腾讯IM来说一个人只能同时加入200个群组限制)。如果后端需要对聊天的内容和群组变化记录入库,就需要用到腾讯云IM的回调机制。对于直播间人数获取,可以获取IM群组人数,不过还是要设计好严格的退群加群机制,才能保证人数正确。
对于正确的退群机制,后端要注意IM文档中回调机制:在线状态相关回调
文档中该回调介绍为:
客户端 kill 后台进程,云服务器检测到客户端网络断开后触发下线回调。
客户端心跳超时,包括客户端 Crash、关闭网络 400 秒后,云服务器检测到客户端的心跳超时触发下线回调
通俗讲:也就是客户端用户无法正确执行quitGroup操作时,通过IM回调服务端接口来实现用户退群操作。
本文主要介绍建群和解散群组的实现方式
web直播间群组的创建是和主播进行绑定,一个主播对应一个群组,同时主播也是该群组的管理员,拥有授权,禁言,踢人等操作。当一个普通用户升级为主播的那一刻,后端就创建了一个IM群组,同时授权管理员是该主播。
用户加入IM群组的前提是必须先登录腾讯的IM系统。就好比你要加QQ群聊天,就必须先登录QQ一样,因此对于腾讯IM群组的private/public/chatroom的群组模式是没有不登录这个概念的。这也就解释了,为什么直播发言必须要求用户登录账号(同时也登录了IM系统,同步web的账号信息到IM系统中的账号)。而不登录web的用户要想看到群组的内容,也必须登录IM系统,只是此刻以游客的身份进行登录,也就是随机的账号登录IM系统,只是不能进行发言,这需要前端进行限制操作。
登录IM系统需要账号密码:
对于登录web的用户来说,IM的账号就是web体系的用户ID或者其他唯一标识,而密码则需要调用后端接口getUserSig获取(参考腾讯userSig机制)
在IM文档中可以获取到
Base64URL和GenUserSig,该加密用来生成IM密码
public class Base64URL {
public static byte[] base64EncodeUrl(byte[] input){
byte[] base64 = new BASE64Encoder().encode(input).getBytes();
for (int i = 0; i < base64.length; ++i)
switch (base64[i]) {
case '+':
base64[i] = '*';
break;
case '/':
base64[i] = '-';
break;
case '=':
base64[i] = '_';
break;
default:
break;
}
return base64;
}
public static byte[] base64DecodeUrl(byte[] input) throws IOException {
byte[] base64 = input.clone();
for (int i = 0; i < base64.length; ++i)
switch (base64[i]) {
case '*':
base64[i] = '+';
break;
case '-':
base64[i] = '/';
break;
case '_':
base64[i] = '=';
break;
default:
break;
}
return new BASE64Decoder().decodeBuffer(base64.toString());
}
}
public class TXGenUserSig {
private long sdkappid;
private String key;
public TXGenUserSig(long sdkappid, String key) {
this.sdkappid = sdkappid;
this.key = key;
}
private String hmacsha256(String identifier, long currTime, long expire, String base64Userbuf) {
String contentToBeSigned = "TLS.identifier:" + identifier + "\n"
+ "TLS.sdkappid:" + sdkappid + "\n"
+ "TLS.time:" + currTime + "\n"
+ "TLS.expire:" + expire + "\n";
if (null != base64Userbuf) {
contentToBeSigned += "TLS.userbuf:" + base64Userbuf + "\n";
}
try {
byte[] byteKey = key.getBytes("UTF-8");
Mac hmac = Mac.getInstance("HmacSHA256");
S