• t-io websocket的聊天功能学习记录(二)


    对于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 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 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 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);
        }
    }

  • 相关阅读:
    uniapp 小程序 身份证 和人脸视频拍摄
    【SpringMVC学习笔记】
    0基础学习VR全景平台篇第120篇:极坐标处理接缝 - PS教程
    2022 Windows上怎样删除提示无法删除的文件
    组态软件和人机界面与plc之间Profinet无线通讯
    Javaweb之request对象
    【C语言】深入理解KMP算法及C语言实现
    SpringBoot3整合SpringDoc实现在线接口文档
    阶段五-Day03-Ajax
    Spring注入和生命周期
  • 原文地址:https://blog.csdn.net/qq_40032778/article/details/126368454