介绍Android端如何接入实时消息(Real-Time Messaging,RTM)功能。
简介
实时消息具有低延时、高并发、高可靠性等特点,可用于直播聊天互动、语聊房等场景。
DingRTC的实时消息能力依托于会议,使用前需先成功入会。
相关概念
会话(Session):实时消息会话,由sessionId唯一标识。Session支持join/leave/close操作,收发实时消息前,需先创建Session并加入。DingRTC支持创建多个不同sessionId的会话,各Session之间互不干扰。
广播消息:对Session里的所有其他成员发送消息。
点对点消息:对Session里的指定UserID的用户发送消息。
集成方法
入会前,从RtcEngine获取DingRtmClient实例:
DingRtmClient rtmClient = rtcEngine.getRtmClient();
给DingRtmClient实例设置回调监听器:
rtmClient.setListener(new DingRtmEventListener() { @Override public void onRtmServerStateChanged(DingRtmClient.DingRtmServerState state, int errorCode) { //只有收到状态为DingRtmServerState.Available的通知后,才可进行一些列RTM接口调用,否则会返回调用失败。 } @Override public void onJoinSessionResult(String sessionId, int result) { } @Override public void onLeaveSessionResult(String sessionId, int reason) { } @Override public void onCloseSessionResult(String sessionId, int result) { } @Override public void onRemovedFromSession(String sessionId, int reason) { } @Override public void onSessionCreate(String sessionId) { } @Override public void onSessionClose(String sessionId) { } @Override public void onSessionRemoteUserJoin(String sessionId, String uid) { } @Override public void onSessionRemoteUserLeave(String sessionId, String uid) { } @Override public void onMessage(String sessionId, String fromUid, boolean broadcast, byte[] data) { } });
入会成功后,会话发起者创建并加入Session:
rtmClient.joinSession(sessionId); // Session不存在时调用joinSession会先创建Session然后加入
会中其他成员会收到onSessionCreate事件通知,然后加入相同Session:
rtmClient.joinSession(sessionId); // Session存在时调用joinSession直接加入
加入Session(如果Session有其他成员)或者是中途有其他成员加入Session,都会收到onSessionRemoteUserJoin事件通知。如有点对点发送实时消息的需求,需要应用层维护Session的成员列表:
@Override public void onSessionRemoteUserJoin(String sessionId, String uid) { activity.runOnUiThread(() -> { // addSessionUser方法由应用层实现,用来添加Session新加入的User。 addSessionUser(sessionId, uid); }); }
同时在别人离开Session时,会收到onSessionRemoteUserLeave事件通知,按需做好Session成员列表的维护:
@Override public void onSessionRemoteUserLeave(String sessionId, String uid) { activity.runOnUiThread(() -> { // removeSessionUser方法由应用层实现,用来移除Session离开的User。 removeSessionUser(sessionId, uid); }); }
SDK支持收发UTF-8编码的字符串和二进制数据,Android端统一用byte数组作为参数来传递消息。 发送广播消息:
String msg = "test123"; byte[] byteMsg = msg.getBytes(StandardCharsets.UTF_8); rtmClient.broadcastData(sessionId, byteMsg);
发送点对点消息:
String msg = "test123"; byte[] byteMsg = msg.getBytes(StandardCharsets.UTF_8); rtmClient.sendData(sessionId, uid, byteMsg);
接收消息:
@Override public void onMessage(String sessionId, String fromUid, boolean broadcast, byte[] data) { activity.runOnUiThread(() -> { // 前提是对方发送的是字符串格式消息。 String msg = new String(data, StandardCharsets.UTF_8); Log.d(TAG, "Receive rtm msg, session: " + sessionId + ", from: " + fromUid + ", msg: " + msg); }); }
如果本端不再使用实时消息功能,可以离开Session:
rtmClient.leaveSession(sessionId);
离开Session后,将收不到该Session里其他成员发送的广播消息,该Session里其他成员也无法给您发送点对点消息。
如果不再使用某个Session,可以关闭Session:
rtmClient.closeSession(sessionId);
关闭Session后,Session的所有成员(包括自己)都会收到onSessionClose事件通知,该Session不再可用。
注意事项
尽量在joinChannel前获取DingRtmClient实例并设置监听器,否则可能丢失部分RTM消息。
离会时,SDK内部会清空所有Session信息,实时消息功能不再可用。
远端用户不调leaveSession直接leaveChannel时,有可能收不到他的onSessionRemoteUserLeave事件通知,应用层需要在收到他的onRemoteUserOffLineNotify事件通知后,主动将该用户从所有Session的成员列表里移除。