此文章爲工作備忘,與技術無關
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", ""));
}