此文章为工作备忘,与技术无关
1.首先贴出声网文档地址:
2.目前所遇到的问题
针对声网音频直播上下麦逻辑问题(逻辑如下):
上麦一般有两种逻辑。
第一种:
用户A给服务器发上麦申请,服务器告知主播B用户A的上麦申请,主播B告知服务器通过A的上麦请求,服务器通知用户A上麦请求通过。A上麦成功,然后A发送上麦成功消息给服务器,服务器发送A上麦成功消息给主播B。
第二种:
1、用户A发送上麦请求(比如5号麦)给房主B:我要上5号麦;
2、房主B同意A上麦,发送同意的消息给用户A:我允许你上5号麦;
3、A收到消息后,执行上麦动作,上麦后发送消息给房主B和服务器:我上5号麦成功了;
4、房主B收到上麦成功的消息后,发消息给服务器:5号麦已经给B了,你记录一下麦位信息;
5、房主B或者服务器发一条广播消息给频道里面的其他人:B上了5号麦,你们注意更新一下UI。
我们注意到所有操作他人(用户B)的操作。都是通过通知到用户B,然后让他自行操作, 如果用户B是下麦操作。此时网络异常,B无法操作。那么就是去了对B的操作权。。
鉴于此
我们可以通过离线消息来控制B。当B一网络正常。接收到离线消息。继续执行之前的操作。
3.具体思路
思路1
正常用户我们不干预,还是之前socket通知用户,用户执行操作。
当用户网络异常时候。服务端在规定时间内(10S)没有检测到用户执行操作,认定该用户异常。发送Rtm消息。通知网络正常时候执行操作。
优点:
之前的方案是成熟的,只需要考虑 网络异常用户即可
缺点:
服务端处理麻烦
思路2
统一采用Rtm离线消息
优点:
一种技术。双方处理都简洁
缺点:
兼容之前版本复杂
最终采用方案2
解决办法
1.兼容工作
后台配置是否开启rtm。在未开启之前采用之前socket操作,当各平台都上线Rtm版本后。再开启Rtm。
/**
* 是否开启rtm(下麦,退出房间操作)
* <p>
* 如果不开启 false: 启用原先socket操作
* 开启 true: socket 下麦,退出房间操作 直接return
*
* @param context
* @return
*/
public static boolean isOpenRtm(Context context) {
String chat_push_type = getSystemInfo(context, "chat_push_type", null, 100);
chat_push_type = LXUtils.getIntentString(chat_push_type);
boolean isOpenRtm = "rtm".equals(chat_push_type);
return isOpenRtm;
}
原先的socket加入判断。
//踢出房间
if (SOCKET_CHAT_BE_KICK.equals(operation)) {
if (LxStorageUtils.isOpenRtm(myContext)) {
return;
}
LXUtils.kickRoom(true);
EventBus.getDefault().post(jsonObject);
}
新加的rtm也加入判断
//请求成功
if (object.getInteger("status") == 0) {
if (LxStorageUtils.isOpenRtm(ChatRoomActivity.this)) {
//是否发送Rtm
RtmUtils.get().sendP2PMessage(RTM_LEAVE, be_account_id);
}
}
2.收到rtm进行处理
//踢人下麦(别人踢你下麦)
if (RTM_LEAVE.equals(type)) {
//下麦操作
LXUtils.downRoom();
ToastUtils.toastShort("您已被抱下麦!");
//通知该页面进行刷新
EventBus.getDefault().post(new IEvent("refresh_room", ""));
}
参数约定
2、参数约定
socket:
• 通知下麦:chat-be_leave_chat_send_rtm
• 通知退出房间:chat-be_kick_send_rtm
rtm字段:
{
"type":"约定性key",
"message":"提示语"
}
rtm约定性type:
• 通知下麦:rtm_be_room_kick
• 通知退出房间:rtm_be_sequence_leave