对于t-io的消息处理主要通过下面的类来完成
其中
1、handshake 这个部分是握手,这里前端传入用户,根据用户进行tio的绑定与群组绑定;
2、onText 这个对于消息的处理,对心跳,正常消息等进行处理
代码如下:
@Component public class TioWsMsgHandler implements IWsMsgHandler { private static final Logger log = LoggerFactory.getLogger(TioWsMsgHandler.class); public static TioConfig tioConfig; @Resource private IImUserService imUserService; @Resource private IImMessageService iImMessageService; @Resource private IImThirdService iImThirdService; /** * 握手时走这个方法,业务可以在这里获取cookie,request参数等 * * @param request request * @param httpResponse httpResponse * @param channelContext channelContext * @return HttpResponse */ @Override public HttpResponse handshake(HttpRequest request, HttpResponse httpResponse, ChannelContext channelContext) { tioConfig = channelContext.tioConfig; String userName = request.getParam("name"); SysUser loginUser = iImThirdService.getUserByName(userName); if(Objects.isNull(loginUser)) { log.info("handshake:" + "无法获得登录用户信息!"); return httpResponse; } //String userName = loginUser.getUsername(); // 先关闭原先的连接 Tio.closeUser(tioConfig, userName, null); // 绑定用户 Tio.bindUser(channelContext, userName); // 在线用户绑定到上下文 用于发送在线消息 WsOnlineContext.bindUser(userName, channelContext); // 绑定群组 List<ImChatGroup> groups = imUserService.getChatGroups(userName); for (ImChatGroup group : groups) { Tio.bindGroup(channelContext, group.getId()); } return httpResponse; } /** * @param httpRequest httpRequest * @param httpResponse httpResponse * @param channelContext channelContext * @throws Exception Exception * @author tanyaowu tanyaowu */ @Override public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) throws Exception { } /** * 字节消息(binaryType = arraybuffer)过来后会走这个方法 */ @Override public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception { return null; } /** * 当客户端发close flag时,会走这个方法 */ @Override public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception { Tio.remove(channelContext, "receive close flag"); return null; } /** * 字符消息(binaryType = blob)过来后会走这个方法 * * @param wsRequest wsRequest * @param text text * @param channelContext channelContext * @return obj */ @Override public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) { try { ObjectMapper objectMapper = new ObjectMapper(); SendInfo sendInfo = objectMapper.readValue(text, SendInfo.class); System.out.println("onText " + text); //心跳检测包 if (ChatUtils.MSG_PING.equals(sendInfo.getCode())) { WsResponse wsResponse = WsResponse.fromText(text, TioServerConfig.CHARSET); Tio.send(channelContext, wsResponse); } //真正的消息 else if (ChatUtils.MSG_MESSAGE.equals(sendInfo.getCode())) { Message message = sendInfo.getMessage(); message.setMine(false); WsResponse wsResponse = WsResponse.fromText(objectMapper.writeValueAsString(sendInfo), TioServerConfig.CHARSET); //单聊 if (ChatUtils.MESSAGE_TYPE_FRIEND.equals(message.getType())) { SetWithLock<ChannelContext> channelContextSetWithLock = Tio.getByUserid(channelContext.tioConfig, message.getId()); //用户没有登录,存储到离线文件 if (channelContextSetWithLock == null || channelContextSetWithLock.size() == 0) { saveMessage(message, ChatUtils.READ_TYPE_UNREAD); } else { Tio.sendToUser(channelContext.tioConfig, message.getId(), wsResponse); //入库操作 saveMessage(message, ChatUtils.READ_TYPE_READ); } if("admin".equals(message.getId())){ SendInfo sendInfo1 = ObjectUtil.cloneByStream (sendInfo); Message message1 = sendInfo1.getMessage(); message1.setUsername("管理员"); message1.setAvatar("http://192.168.199.152:9010/nbcio/temp/nbcio_1660480947146.png"); message1.setMine(false); message1.setId(message.getFromname()); message1.setFromname("admin"); message1.setContent("欢迎使用NBCIO 亿事达企业管理平台!"); sendInfo1.setMessage(message1); WsResponse wsResponse1 = WsResponse.fromText(objectMapper.writeValueAsString(sendInfo1), TioServerConfig.CHARSET); Tio.sendToUser(channelContext.tioConfig, message.getFromname(), wsResponse1); } } else { Tio.sendToGroup(channelContext.tioConfig, message.getId(), wsResponse); //入库操作 saveMessage(message, ChatUtils.READ_TYPE_READ); } } //准备就绪,需要发送离线消息 else if (ChatUtils.MSG_READY.equals(sendInfo.getCode())) { //未读消息 sendOffLineMessage(channelContext, objectMapper); } } catch (IOException e) { e.printStackTrace(); } //返回值是要发送给客户端的内容,一般都是返回null return null; } /** * 未读消息 * * @param channelContext channelContext * @param objectMapper objectMapper * @throws IOException 抛出异常 */ private void sendOffLineMessage(ChannelContext channelContext, ObjectMapper objectMapper) throws IOException { List<ImMessage> imMessageList = iImMessageService.getUnReadMessage(channelContext.userid); for (ImMessage imMessage : imMessageList) { Message message = new Message(); message.setId(imMessage.getToName()); message.setMine(false); message.setType(imMessage.getType()); SysUser imUser = imUserService.getByName(imMessage.getFromName()); message.setUsername(imUser.getUsername()); message.setCid(String.valueOf(imMessage.getId())); message.setContent(imMessage.getContent()); message.setTimestamp(System.currentTimeMillis()); message.setFromname(imMessage.getFromName()); message.setAvatar(imUser.getAvatar()); SendInfo sendInfo1 = new SendInfo(); sendInfo1.setCode(ChatUtils.MSG_MESSAGE); sendInfo1.setMessage(message); WsResponse wsResponse = WsResponse.fromText(objectMapper.writeValueAsString(sendInfo1), TioServerConfig.CHARSET); Tio.sendToUser(channelContext.tioConfig, message.getId(), wsResponse); } } /** * 保存信息 * * @param message 信息 * @param readStatus 是否已读 */ private void saveMessage(Message message, String readStatus) { ImMessage imMessage = new ImMessage(); imMessage.setToName(message.getUsername()); imMessage.setFromName(message.getFromname()); imMessage.setSendTime(System.currentTimeMillis()); imMessage.setContent(message.getContent()); imMessage.setReadStatus(readStatus); imMessage.setType(message.getType()); iImMessageService.saveMessage(imMessage); } }