上一节我们通过自定义图片分段结构实现了从SocketIO服务器接收图片的功能,至此可以在单聊中发送文本和图片了。不过若想在群聊中发送文本和图片,还得构建一套群聊机制,把群成员发送的消息转发给其他的群成员。具体的群聊构建过程分为下列几个事件处理。

一、处理入群事件

每当一个新成员加入群聊时,该成员会发出join_group通知SocketIO服务器,表示自己已经入群了。然后SocketIO服务器轮询所有在线的群成员,向其他在线的群成员发出person_in_group通知,表示现有XXX新成员入群了。下面是处理入群事件的SocketIO服务端代码例子:

// 添加入群的事件监听器
server.addEventListener("join_group", String.class, (client, content, ackSender) -> {
  String sessionId = client.getSessionId().toString();
  JSONObject json = JSONObject.parseObject(content);
  JoinInfo info = (JoinInfo) JSONObject.toJavaObject(json, JoinInfo.class);
  if (!groupMap.containsKey(info.getGroup_name())) {
    groupMap.put(info.getGroup_name(), new HashMap<String, String>());
  }
  for (Map.Entry<String, Map<String, String>> group : groupMap.entrySet()) {
    if (info.getGroup_name().equals(group.getKey())) {
      group.getValue().put(sessionId, info.getUser_name());
      for (Map.Entry<String, String> user : group.getValue().entrySet()) {
        clientMap.get(user.getKey()).sendEvent("person_in_group", info.getUser_name().toString());
      }
    }
  }
});

对于鸿蒙App而言,入群的新成员通过以下代码向SocketIO服务器发送入群通知。

this.client.emit('join_group', msg)

而群聊的其他成员通过以下代码从SocketIO服务器接收入群通知。

this.client.on('person_in_group', (person_name: string) => {
  // 这里暂时省略群成员的入群提示处理
})

二、处理退群事件

每当一个群成员退出群聊时,该成员会发出leave_group通知SocketIO服务器,表示自己已经退群了。然后SocketIO服务器轮询所有在线的群成员,向其他在线的群成员发出person_out_group通知,表示原来的XXX成员退群了。处理退群事件的SocketIO服务端可参考上面的处理入群事件代码。
对于鸿蒙App而言,入群的新成员通过以下代码向SocketIO服务器发送退群通知。

this.client.emit('leave_group', msg)

而群聊的其他成员通过以下代码从SocketIO服务器接收退群通知。

this.client.on('person_out_group', (person_name: string) => {
  // 这里暂时省略群成员的退群提示处理
})

三、处理群文本消息的发送和接收

每当一个群成员发送聊天文本消息时,该成员会发出send_group_message通知SocketIO服务器,表示自己发表了某段文本。然后SocketIO服务器轮询所有在线的群成员,向其他在线的群成员发出receive_group_message通知,表示有成员发表了聊天文本消息。下面是处理群消息收发事件的SocketIO服务端代码例子:

// 添加群消息发送的事件监听器
server.addEventListener("send_group_message", String.class, (client, content, ackSender) -> {
  String sessionId = client.getSessionId().toString();
  JSONObject json = JSONObject.parseObject(content);
  MessageInfo message = (MessageInfo) JSONObject.toJavaObject(json, MessageInfo.class);
  for (Map.Entry<String, Map<String, String>> group : groupMap.entrySet()) {
    if (message.getTo().equals(group.getKey())) {
      for (Map.Entry<String, String> user : group.getValue().entrySet()) {
        if (!user.getValue().equals(message.getFrom())) {
          String resp = JSONObject.toJSONString(message);
          clientMap.get(user.getKey()).sendEvent("receive_group_message", resp.toString());
        }
      }
      break;
    }
  }
});

对于鸿蒙App而言,群成员通过以下代码从SocketIO服务器接收群文本消息。

this.client.on('receive_group_message', (data: string) => {
  // 这里暂时省略群文本消息的解析和展示处理
})

综合上述几个群聊事件处理,运行演示App观察到的仿微信群聊效果如下图所示,分别是甲、乙、丙成员的App界面截图。

至此,本系列的“仿微信聊天”App开发技术分享全部完结啦,各位小伙伴们,你们有没有得到什么收获呢?欢迎留言跟帖。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐