Netty4.x下使用HTTP与WebSocket通讯协议

   

Netty4.x下使用HTTP与WebSocket通讯协议

由于公司需求,需要将Netty框架使用的通讯协议由HTTP转成WebSocket协议。由于初学Netty忙了一天,做了一下总结。首先介绍下两者:

HTTP协议

基于传统HTTP协议建立起的连接,大多数使用轮询的方式即客户端每隔1s向服务器端发送请求,服务器端接收到请求将数据返回给客户端。属于半双工通信,HTTP协议中的Header非常冗长,因此会占用很多的带宽和服务器资源。为弥补HTTP请求难以满足频繁请求,占用资源过多的不足,HTML5推出了WebSocket通信协议。

WebSocket协议

WebSocket属于全双工通信协议,即客户端与服务器端建立起链接之后随时可相互通讯传递数据。 在WebSocket API中,浏览器和服务器只需要一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道,两者就可以直接互相传送数据了。无消息头,Cookie和消息验证,无安开销,服务器端可以主动传数据给客户端,不需要客户端轮询。WebSocket基于TCP双向全双工协议,即在同一时刻,即可以发送消息,也可以接收消息,相比于HTTP协议,是一个性能上的提升。

二者异同

WebSocket 协议与HTTP协议同处于OSI模型的最高层(应用层),通过TCP/IP协议三次握手与浏览器建立起链接。WebSocket使用HTTPS建立起链接,二者不同之处在于连接之后的数据传输方式。

Netty使用流程

WebSocket的初始化流程

名称 职责
HttpServerCodec Http编码器。
HttpObjectAggregator Http消息聚合。
ChunkedWriteHandler 大数据处理,主要针对SSL加密解密。
HttpRequestHandler 用户自定义处理ws请求。
WebSocketServerProtocolHandler 处理除TextWebSocketFrame以外的消息事件。所有规定的WebSocket帧类型。
TextWebSocketFrameHandler 用户自定义处理TextWebSocketFrame的消息事件。
WebSocketServerCompressionHandler WebSocket数据压缩

Netty同时实现WebSocket与HTTP通讯协议

public class Netty4SocketServer {

    private static ServerBootstrap serverBootstrap;

    private static EventLoopGroup bossGroup;
    private static EventLoopGroup workerGroup;

    public void start() throws Exception {

        bossGroup = new NioEventLoopGroup();
        workerGroup = new NioEventLoopGroup();

        try {   
            serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
            .channel(NioServerSocketChannel.class)
            .childHandler(new ChannelInitializer() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
           socketChannel.pipeline.addLast(new HttpServerCodec());
           socketChannel.pipeline.addLast(new HttpObjectAggregator(65536));
           socketChannel.pipeline.addLast(new ChunkedWriteHandler());
           socketChannel.pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
           socketChannel.pipeline.addLast(new Netty4MessageHandler());
                        }
                    })
            .option(ChannelOption.SO_BACKLOG, 1024)         
            // 等待关闭事件
            cf.channel().closeFuture().sync();
            //阻塞处理,等待服务端链路关闭之后main函数才退出
        } finally {
            // 释放资源
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
    public static class Netty4MessageHandler extends SimpleChannelInboundHandler{
            @Override
          public void messageReceived(ChannelHandlerContext ctx, Object msg) {
              if (msg instanceof FullHttpRequest) {//如果是HTTP请求,进行HTTP操作
                  handleHttpRequest(ctx, (FullHttpRequest) msg);
              } else if (msg instanceof WebSocketFrame) {//如果是Websocket请求,则进行websocket操作
                  handleWebSocketFrame(ctx, (WebSocketFrame) msg);
              }
          }
          @Override
          public void channelReadComplete(ChannelHandlerContext ctx) {
              ctx.flush();
          }
          //处理HTTP的代码
          private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
              HttpMethod method=req.method();
              String uri=req.uri();
              diapathcer(method,uri);
          }
          private void diapathcer(HttpMethod method,String uri){
              if(method==HttpMethod.GET&&"/login".equals(uri)){
                  //....处理
              }else if(method==HttpMethod.POST&&"/register".equals(uri)){
                  //...处理
              }

          }
          //处理Websocket的代码
          private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
          }
          @Override
          public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
              cause.printStackTrace();
              ctx.close();
          }

    }
}

你可能感兴趣的:(游戏服务器开发)