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


    因为想开发聊天的相关内容,所以学习一下t-io的知识

    服务器端  pom.xml主要加入


                org.t-io
                tio-websocket-server
                3.7.0.v20201010-RELEASE
           

    服务器端首先实现消息处理

    public class ShowcaseWsMsgHandler implements IWsMsgHandler {
        private static Logger log = LoggerFactory.getLogger(ShowcaseWsMsgHandler.class);

        public static final ShowcaseWsMsgHandler me = new ShowcaseWsMsgHandler();

        private ShowcaseWsMsgHandler() {

        }

        /**
         * 握手时走这个方法,业务可以在这里获取cookie,request参数等
         */
        @Override
        public HttpResponse handshake(HttpRequest request, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
            String clientip = request.getClientIp();
            String myname = request.getParam("name");
            
            Tio.bindUser(channelContext, myname);
    //        channelContext.setUserid(myname);
            log.info("收到来自{}的ws握手包\r\n{}", clientip, request.toString());
            return httpResponse;
        }

        /** 
         * @param httpRequest
         * @param httpResponse
         * @param channelContext
         * @throws Exception
         * @author tanyaowu
         */
        @Override
        public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
            //绑定到群组,后面会有群发
            Tio.bindGroup(channelContext, Const.GROUP_ID);
            int count = Tio.getAll(channelContext.tioConfig).getObj().size();

            String msg = "{name:'admin',message:'" + channelContext.userid + " 进来了,共【" + count + "】人在线" + "'}";
            //用tio-websocket,服务器发送到客户端的Packet都是WsResponse
            WsResponse wsResponse = WsResponse.fromText(msg, ShowcaseServerConfig.CHARSET);
            //群发
            Tio.sendToGroup(channelContext.tioConfig, Const.GROUP_ID, wsResponse);
        }

        /**
         * 字节消息(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)过来后会走这个方法
         */
        @Override
        public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) throws Exception {
            WsSessionContext wsSessionContext = (WsSessionContext) channelContext.get();
            HttpRequest httpRequest = wsSessionContext.getHandshakeRequest();//获取websocket握手包
            if (log.isDebugEnabled()) {
                log.debug("握手包:{}", httpRequest);
            }

    //        log.info("收到ws消息:{}", text);

            if (Objects.equals("心跳内容", text)) {
                return null;
            }
            //channelContext.getToken()
            //String msg = channelContext.getClientNode().toString() + " 说:" + text;
            String msg = "{name:'" + channelContext.userid + "',message:'" + text + "'}";
            //用tio-websocket,服务器发送到客户端的Packet都是WsResponse
            WsResponse wsResponse = WsResponse.fromText(msg, ShowcaseServerConfig.CHARSET);
            //群发
            Tio.sendToGroup(channelContext.tioConfig, Const.GROUP_ID, wsResponse);

            //返回值是要发送给客户端的内容,一般都是返回null
            return null;
        }

    }
     

    还有一个就是实现WsServerAioListener类

    public class ShowcaseServerAioListener extends WsServerAioListener {
        private static Logger log = LoggerFactory.getLogger(ShowcaseServerAioListener.class);

        public static final ShowcaseServerAioListener me = new ShowcaseServerAioListener();

        private ShowcaseServerAioListener() {

        }

        @Override
        public void onAfterConnected(ChannelContext channelContext, boolean isConnected, boolean isReconnect) throws Exception {
            super.onAfterConnected(channelContext, isConnected, isReconnect);
            if (log.isInfoEnabled()) {
                log.info("onAfterConnected\r\n{}", channelContext);
            }

        }

        @Override
        public void onAfterSent(ChannelContext channelContext, Packet packet, boolean isSentSuccess) throws Exception {
            super.onAfterSent(channelContext, packet, isSentSuccess);
            if (log.isInfoEnabled()) {
                log.info("onAfterSent\r\n{}\r\n{}", packet.logstr(), channelContext);
            }
        }

        @Override
        public void onBeforeClose(ChannelContext channelContext, Throwable throwable, String remark, boolean isRemove) throws Exception {
            super.onBeforeClose(channelContext, throwable, remark, isRemove);
            if (log.isInfoEnabled()) {
                log.info("onBeforeClose\r\n{}", channelContext);
            }

            WsSessionContext wsSessionContext = (WsSessionContext) channelContext.get();

            if (wsSessionContext != null && wsSessionContext.isHandshaked()) {
                
                int count = Tio.getAll(channelContext.tioConfig).getObj().size();

                String msg = channelContext.getClientNode().toString() + " 离开了,现在共有【" + count + "】人在线";
                //用tio-websocket,服务器发送到客户端的Packet都是WsResponse
                WsResponse wsResponse = WsResponse.fromText(msg, ShowcaseServerConfig.CHARSET);
                //群发
                Tio.sendToGroup(channelContext.tioConfig, Const.GROUP_ID, wsResponse);
            }
        }

        @Override
        public void onAfterDecoded(ChannelContext channelContext, Packet packet, int packetSize) throws Exception {
            super.onAfterDecoded(channelContext, packet, packetSize);
            if (log.isInfoEnabled()) {
                log.info("onAfterDecoded\r\n{}\r\n{}", packet.logstr(), channelContext);
            }
        }

        @Override
        public void onAfterReceivedBytes(ChannelContext channelContext, int receivedBytes) throws Exception {
            super.onAfterReceivedBytes(channelContext, receivedBytes);
            if (log.isInfoEnabled()) {
                log.info("onAfterReceivedBytes\r\n{}", channelContext);
            }
        }

        @Override
        public void onAfterHandled(ChannelContext channelContext, Packet packet, long cost) throws Exception {
            super.onAfterHandled(channelContext, packet, cost);
            if (log.isInfoEnabled()) {
                log.info("onAfterHandled\r\n{}\r\n{}", packet.logstr(), channelContext);
            }
        }

    }
     

    可以用官方的web客户端或websocketman进行测试,如下:

  • 相关阅读:
    2023江苏科技大学计算机考研信息汇总
    【linux内核中的双向链表-02】list_for_each_safe
    Appx代码签名指南
    Creo 9.0 基准特征:基准点
    智能家居的实用性设置有哪些?智汀小米的怎么样?
    UEC++ day6
    【内网穿透】公网远程访问本地硬盘文件
    C和指针 第15章 输入/输出函数 15.12 刷新和定位函数
    思维模型 正/反 木桶理论
    设备驱动理论详解,Linux操作系统原理与应用
  • 原文地址:https://blog.csdn.net/qq_40032778/article/details/126266547