AI工具人
提示词工程师

用Netty实现WebSocket网络聊天室

在这里插入图片描述

  最近学习Netty,学习到WebSocket一章节,将Netty中WebSocket的样例代码做了一些简单的改造,实现了一个简易的WebSocket网络聊天室,源码并非完全自己实现,只是将一些别人的代码做了下整合改造,今分享至此,希望对大家学习Netty有所帮助。
  首先介绍下什么是WebSocket,这就不得不先提到HTTP协议了。众所周知,在HTTP/2发布前,所有HTTP请求都是 请求-应答的 模式,这就意味着客户端只能向服务器要数据,然后服务端被动应答,而服务器无法主动将数据推送给客户端。这就导致一些高时效性的场景用HTTP就会有些问题,就拿实时聊天举例吧,客户端想知道近期有没有人说过话,就只能不断问服务器 有没有人发了消息? 有的话服务器就返回,没有就不返回,这种行为被称为轮询。 轮询的问题在于如果询问的时间间隔太长,消息的及时性无法得到保证,但如果时间太短,对服务器的压力就会大幅提升(因为不断要请求响应)。 有没有可能服务器有消息的时候,主动推送给客户端?
  WebSocket因此而诞生,它允许客户端和服务端之间在HTTP之上建立一个全双工的TCP长连接,这里的关键点在于全双工,意味着服务端也能通过这个连接给客户端发送即时消息,从而解决了轮询的性能和时效性矛盾的问题。了解过Socket编程的同学应该很容易理解了,WebSocket其实本质上就是Socket,只不过WebSocket是建立在HTTP协议之上的。
  回到我们的正题,如何用Netty+WebSocket写一个网络聊天室? 其实Netty里已经封装好了HTTP和WebSocket的实现,我们只需要实现部分聊天室的功能即可,接下来看下我实现的完整代码:
首先是ServerBootstrap的部分,这里是Netty的启动入口。

@Service
public class WebSocketServer {

    static final String WEBSOCKET_PATH = "/ws";

    private ChannelFuture f;

    @Resource
    private WebSocketFrameHandler webSocketFrameHandler;

    @PostConstruct
    private void init() {
        bind(Constant.SOCKET_PORT);
    }

    public static voud bind(int port) {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new HttpServerCodec());  // netty中http协议的编解码
                            pipeline.addLast(new HttpObjectAggregator(65536));  
                            pipeline.addLast(new WebSocketServerCompressionHandler());
                            pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
                            pipeline.addLast(new WebSocketIndexPageHandler(WEBSOCKET_PATH));  // demo页面的handler,这个是非必须的,可以换成其他第三方的WebSocket客户端工具  
                            pipeline.addLast(webSocketFrameHandler); // 聊天室的主要逻辑
                        }
                    });
            Channel f = b.bind(port).sync().channel();
            f.closeFuture().sync();
        } catch (Exception e) {

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

  因为HttpServerCodec HttpObjectAggregator WebSocketServerCompressionHandler WebSocketServerProtocolHandler是Netty组件中提供的组件,其作用就是完成Http和WebSocket协议数据到Java对象的相互转换,这里就不再展开了,我们直接看下剩下的两个Handler。
  首先是WebSocketIndexPageHandler,这个也是我直接从Netty样例中Copy出来的,它的作用就是构建一个Http首页,这个首页实现了一个简单的WebSocket网页客户端,如果你不需要这个网页客户端,你也可直接删掉。

赞(0) 打赏
未经允许不得转载:XINDOO » 用Netty实现WebSocket网络聊天室
描述文字

评论 抢沙发

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫