掘金 后端 ( ) • 2024-03-22 15:39

大家好, 我是Open, 是一位新进的掘金作家, 今天我带来的是Netty的教程, 如果大家感觉我写的不错可以点点赞👍, 好了我们废话不多说, 直接开始操作。

本次使用的版本如下:

  • SpringBoot: 2.5.17
  • Netty: 4.1.101

前提描述:

1、Netty提供了WebSocket的适配, 通过netty可以更好的完成websocket的工作, 但是我们应该如何对每次访问socket的部分信息添加权限内容呢, 如果缺失权限我们应该如何去做,我们应该如何添加权限呢, 这是我们这次需要考虑的。

2、本次讲解操作只使用与WebSocket协议, TCP与UDP权限需自己控制, OK让我们进下一步操作

3、先上图, 让我们来看一下WebSocket、TCP、UDP 的不同之处吧!!

171651535171730.png

此处图片引用地址为: https://www.cnblogs.com/ghj1976/p/4295346.html

171651564243242.png

4、说实话我其实不知道讲什么, 所以直接上代码吧!!!!!

Netty启动部分

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
    ServerBootstrap b = new ServerBootstrap();
    b.group(bossGroup, workerGroup)
     .channel(NioServerSocketChannel.class)
     .childHandler(new WebSocketServer(sslCtx));
    Channel ch = b.bind(PORT).sync().channel();

ChildHandler实现

private final SslContext sslCtx;

public WebSocketServer(SslContext sslCtx) {
    this.sslCtx = sslCtx;
}

@Override
public void initChannel(Channel ch) throws Exception {

    ChannelPipeline pipeline = ch.pipeline();
    if (sslCtx != null) {
        pipeline.addLast(sslCtx.newHandler(ch.alloc()));
    }
    pipeline.addLast(new HttpServerCodec());
    pipeline.addLast(new HttpObjectAggregator(65536));
    pipeline.addLast(new WebSocketHeadIndex());

    pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
    pipeline.addLast(new WebSocketHandler());

}

补充点

这里说明一下ChildHandler下的两个内容吧

1、WebSocketHeadIndex ---> 这个内容是一个处理器, 是处理首次连接时解析的信息

2、WebSocketHandler ---> 这个处理器是后续连接后, 要处理的内容

WebSocketHeadIndex实现

private final static AttributeKey<Object> TOKEN = AttributeKey.valueOf("TOKEN");

@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {

    ......忽略一下其他URL或Method
    
    // 获取Token并绑定到Channel中
    String token = ""; 
    ctx.channel().attr(TOKEN).set(token);
}

WebSocketHandler实现

private final static AttributeKey<Object> TOKEN = AttributeKey.valueOf("TOKEN");

@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
    String = ctx.channel().attr(MN_CODE).get();
}

扩展一下

1、 每次消息发送后, 建立消息工厂, 将消息发送到消息工厂对自己的Msg进行反序列

2、 再消息工厂后, 发布到每一个消息处理器中时, 再消息处理器方法上添加AOP注解, 对消息进行验证, 是否存在权限

3、 可以拆卸的消息体, 如果是部分内容, 可以做可拆卸的消息体

最后

我是Open, 这一次的讲解更多的是思路, 如果思路相通了, 那我们后续的工作就简单了, 这里建议大家去阅读一本书籍《Netty实战》, 该书籍中详细的讲解了4.+版本的所有内容。 像是如何处理粘包粘包, 如何拆卸处理器, 如何再Channel内锁定内容, 已经通道完成后的定时任务、 心跳机制等等。

最后的最后, 我推荐一下我的个人博客 www.openacloud.com ,后续的内容我会在我的博客中进行更新!