美文网首页程序员Java 杂谈
netty 对websocket 支持

netty 对websocket 支持

作者: 持续进步者 | 来源:发表于2017-08-26 08:42 被阅读285次

    WebSocket

    WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信————允许服务器主动发送信息给客户端。
    

    WebSocket解决了那些问题

    • 1,http 是无状态,基于请求/响应模型,导致了不识别用户,每次请求都是一个新的用户,
      这就产生了cookie,session 记录用户的状态的技术。

    • 2,http1.1 进行网络请求可以重用既有的连接, WebSocket只需进行连接一次。

    • 3,向客户端推送数据 http轮询:http的轮询实现是客户端每个一段时间就进行网络请求,
      如果服务器端没有数据返回也就表示这次请求是无效的,多次这样的网络请求会影响网络带宽,WebSocket是基于tcp全双工通信,只要连接通道建立,服务器可以向客户端推送数据。

    • 4,http 请求包括header 和 要返回的结果返回给客户端,往往header大于内容的容量,
      websoket 浏览器和服务器端会建立长连接,双方式对等的,只要发送数据本省,不在需要任何header的信息 。

    netty 服务器端

    • 1,MyServer.java
    public class MyServer {
        public static void main(String ...arg) throws Exception{
    
            // 负责接收客户端连接
            NioEventLoopGroup bossGroup = new NioEventLoopGroup();
            // 负责处理连接
            NioEventLoopGroup wokerGroup = new NioEventLoopGroup();
    
            try{
                ServerBootstrap serverBootstrap = new ServerBootstrap();
                serverBootstrap.group(bossGroup,wokerGroup)
                        .handler(new LoggingHandler(LogLevel.INFO))
                        .channel(NioServerSocketChannel.class)
                        .childHandler(new WebSocketChannelInitializer());
    
                ChannelFuture channelFuture = serverBootstrap.bind(9999).sync();
                channelFuture.channel().closeFuture().sync();
    
    
            } finally {
                bossGroup.shutdownGracefully();
                wokerGroup.shutdownGracefully();
            }
    
        }
    }
    
    
    • 2,WebSocketChannelInitializer.java
    public class WebSocketChannelInitializer extends ChannelInitializer<SocketChannel> {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pipeline = ch.pipeline();
    
            pipeline.addLast(new HttpServerCodec());
            pipeline.addLast(new ChunkedWriteHandler());
            pipeline.addLast(new HttpObjectAggregator(8192));
            //websocket 请求路径
            pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
    
            pipeline.addLast(new TextWebSocketFrameHandler());
    
        }
    }
    
    
    
    • 3,TextWebSocketFrameHandler.java
    public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
            System.out.println("服务器收到:"+msg.text());
            ctx.channel().writeAndFlush(new TextWebSocketFrame("服务器时间:"+ LocalDateTime.now()));
    
        }
    
        @Override
        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
            //每个channel 都有一个唯一的id
            System.out.println("handlerAdded: "+ctx.channel().id().asLongText());
        }
    
        @Override
        public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
            System.out.println("handlerRemoved: "+ctx.channel().id().asLongText());
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    }
    
    
    
    

    WebSocket js 使用

    • 1,创建对象
    var ws = new WebSocket(url,name);
    
    
    • 2,发送文本消息
    ws.send(msg);
    
    
    • 3,接收消息
    ws.onmessage = (function(){...})();
    
    
    • 4,错误处理
    ws.onerror = (function(){...})();
    
    
    • 5,关闭连接
    ws.close();
    

    客户端端

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

    相关文章

      网友评论

        本文标题:netty 对websocket 支持

        本文链接:https://www.haomeiwen.com/subject/xelmdxtx.html