Netty实战系列一之多协议并存

本文介绍如何使用Netty实现一个服务器进程同时处理HTTP、WebSocket和自定义TCP协议。通过动态添加处理器,实现对不同协议的支持。文章详细解释了协议选择器的工作原理,并提供了代码示例。

前言

前面写了好多关于源码的文章,我觉得还是要来点实战的,解决一些问题,最近想用Netty写个游戏服务器框架,已经写了一点了,我想让一个netty进程一个端口可以响应多个协议,比如我希望一个端口就可以响应HTTP,WebSocketTCP私有协议。如果对这些还不了解的可以看下我写的源码文章,基本都有讲了,至于私有协议,我这里也会给出例子。

解决问题的思路

  1. 开两个netty进程,一个进程相应一个。
  2. 一个进程绑定多个端口,不同的端口处理不同的协议。
  3. 一个进程一个端口,分析协议头来判断不同的协议,动态添加处理器。

前两个应该比较简单,我们来简单的实现下第三个吧。

主服务类

没别的设置,就是基本模板,但是只有一个处理器,叫ProtocolSelectorHandler,这个就是我们来解析不同协议做动态添加的关键。

public class MyTestServer {
   
   
    public static void main(String[] args) throws Exception{
   
   
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
   
   

            ServerBootstrap serverBootstrap = new ServerBootstrap();

            serverBootstrap.group(bossGroup, workerGroup);
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.childOption(ChannelOption.TCP_NODELAY,true);

            serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
   
   

                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
   
   
                    ChannelPipeline pipeline = ch.pipeline();
                    pipeline.addLast(new ProtocolSelectorDecoder());

                }
            });

            //启动服务器
            ChannelFuture channelFuture = serverBootstrap.bind(8080).sync();
            channelFuture.channel().closeFuture().sync();

        }finally {
   
   
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

ProtocolSelectorHandler协议选择器

这个就是实现动态协议的关键,其实也只是简单的判断前几个字节是什么,也就是要一些约定,比如说约定好WebSocket的话,URI就是/ws,如果看到GET /ws前缀的话,就说明要进行WebSocket握手了。我就添加WebSocket的处理器,重新来处理这个数据,然后把协议选择器删除,当然这里是简单的实现,可能期间出现问题,你把协议选择器删了就惨了,我们暂时不管哈哈。如果是自定义协议的话,我们一般不会传空格,所以我可以用空格来区别自定义协议和HTTP协议,HTTP请求行有空格嘛。当然我也只是简单的实现,如果要较真,还是把判断换行,然后看是不是HTTP协议比较好。

/**
 * 协议选择器,支持动态协议HTTP WEBSOCKET TCP私有协议
 * Author: wangwei
 */
public class ProtocolSelectorHandler extends ByteToMessageDecoder {
   
   
    /**
     * websocket定义请求行前缀
     */
    private static final String WEBSOCKET_LINE_PREFIX = "GET /ws";
    /**
     * websocket的uri
     */
    private static final String WEBSOCKET_PREFIX = "/ws";
    /**
     * 检查10个字节,没有空格就是自定义协议
     */
    private static final int SPACE_LENGTH = 10;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out
评论 17
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值