• Netty对WebSocket的支持


    WebSocket长连接

    一、创建服务端代码

    1、MyServer 类

    public class MyServer {
        public static void main(String[] args) throws  Exception{
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try{
    
                ServerBootstrap serverBootstrap = new ServerBootstrap();
                serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class)
                        .handler(new LoggingHandler(LogLevel.INFO)) //增加日志处理器
                        .childHandler(new WebSocketChannelInitializer());
    
                ChannelFuture channelFuture = serverBootstrap.bind(new InetSocketAddress(8899)).sync();
                channelFuture.channel().closeFuture().sync();
            }finally {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
    }
    

      

    2、WebSocketChannelInitializer 类

    public class WebSocketChannelInitializer extends ChannelInitializer<SocketChannel>{
    
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            ChannelPipeline pipeline = socketChannel.pipeline();
            pipeline.addLast(new HttpServerCodec());
            pipeline.addLast(new ChunkedWriteHandler());
            pipeline.addLast(new HttpObjectAggregator(8192));
            pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
            pipeline.addLast(new TextWebSocketFrameHandle());
        }
    }
    

      

    3、TextWebSocketFrameHandle 类

    public class TextWebSocketFrameHandle extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    
    
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
            CommonUtil.println("收到消息:" + msg.text());
            ctx.channel().writeAndFlush(new TextWebSocketFrame("服务器时间:" + LocalDateTime.now()));
        }
    
        @Override
        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
            CommonUtil.println("handlerAdded:" +ctx.channel().id().asLongText());
        }
    
        @Override
        public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
            CommonUtil.println("handlerRemoved:" +ctx.channel().id().asLongText());
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            CommonUtil.println("异常发生");
             ctx.close();
        }
    }
    

      

    二、编写客户端WebSocket代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>WebSocket</title>
    </head>
    <body>
    <script type="text/javascript">
    
        var socket;
    
        if(window.WebSocket){
            socket = new WebSocket("ws://localhost:8899/ws");
            socket.onmessage = function (event) {
                var ta = document.getElementById("responseText");
                ta.value = ta.value + "
    " + event.data;
            }
            socket.onopen = function (event) {
                var ta = document.getElementById("responseText");
                ta.value = "连接开启";
    
            }
    
            socket.onclose = function (event) {
                var ta = document.getElementById("responseText");
                ta.value = ta.value + "
    " + "连接关闭!";
            }
    
        }else {
            alert("浏览器不支持WebSocket")
        }
    
        function  send(message) {
            if(!window.WebSocket){
                return;
            }
            if(socket.readyState == WebSocket.OPEN){
                socket.send(message);
            }else{
                alert("连接尚未开启");
            }
        }
    
    </script>
    <form onsubmit="return false">
        <textarea name="message" style=" 400px ; height:  200px;" ></textarea>
    
        <input type="button" value="发送数据" onclick="send(this.form.message.value)">
    
        <h3>服务端输出:</h3>
    
        <textarea id="responseText" style=" 400px ; height: 300px;" ></textarea>
    
        <input type="button" value="清空内容" onclick="javascript: document.getElementById('responseText').value=''">
    </form>
    </body>
    </html>
    

      

    三、测试

    1、启动服务端

    2、打开页面 http://localhost:7080/test.html

    可以看到,连接开启。

    服务端输出如下图:

    四、进入页面的开发者模式

    可以发现,

    1、Status Code:101 Switching Protocols。 原来是Http的,切换成Socket

    2、请求头: Upgrade:websocket

    虽然请求发送的ws,但是要先发送的http请求建立连接,连接建立好后,将http升级到websockent协议上

    五、测试发送消息

    整个请求建立在webSocket协议之上。

    六、连接关闭

    当服务端停掉后,可以收到连接关闭。

    七、websocket的请求和接收

    如下图: Hello是请求, 服务器时间是接收

  • 相关阅读:
    Delphi中解析Xml的控件-SimDesign NativeXml
    DELPHI判断是否64位操作系统
    几个获取Windows系统信息的Delphi程序
    delphi假死线程堵塞解决办法
    Delphi ADO数据操作封装类
    Delphi的时间与字符串函数代码示例
    【BZOJ2132】圈地计划 最小割
    【BZOJ3544】[ONTAK2010]Creative Accounting 前缀和+set
    【BZOJ4281】[ONTAK2015]Związek Harcerstwa Bajtockiego LCA
    【BZOJ2083】[Poi2010]Intelligence test 二分
  • 原文地址:https://www.cnblogs.com/linlf03/p/11300051.html
Copyright © 2020-2023  润新知