Netty构建WebSocket服务器(服务器端)

 

public class WSServer {
      public static void main(String[] args) throws Exception{
           
           EventLoopGroup mainGroup = new NioEventLoopGroup();
           EventLoopGroup subGroup = new NioEventLoopGroup();
           
           try {
                 ServerBootstrap server = new ServerBootstrap();
                 server.group(mainGroup, subGroup)
                      .channel(NioServerSocketChannel.class)
                      .childHandler(new WSServerInitializer());
                 
                 ChannelFuture future = server.bind(8088).sync();
                 
                 future.channel().closeFuture().sync();
           } finally {
                 mainGroup.shutdownGracefully();
                 subGroup.shutdownGracefully();
           }
           
      }
}

 

public class WSServerInitializer extends ChannelInitializer<SocketChannel>{
      @Override
      protected void initChannel(SocketChannel ch) throws Exception {
           ChannelPipeline pipeline = ch.pipeline();
           
           // websocket 基于http协议, 所以要有http编解码器
           pipeline.addLast(new HttpServerCodec());
           // 对写大数据流的支持
           pipeline.addLast(new ChunkedWriteHandler());
           // 对HttpMessage进行聚合,聚合成FullHttpRequest或FullHttpResponse
           // 几乎在netty中的编程都会使用到此handler
           pipeline.addLast(new HttpObjectAggregator(1024*64));
           
           //===============以上用于支持http协议===========================
           
           /**
            * websocket服务器处理的协议,用于指定给客户端连接访问的路由: /ws
            * 此handler会处理一些繁重复杂的事情
            * 握手: handshaking(close,ping,pong)
            * 对于websocket,都是以frames进行传输的,不同的数据类型对应的frames也不同
            */
           pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
           
           // 自定义handler

           pipeline.addLast(new ChatHandler());
      }
}

 

/**
 *
 * @author Edward
 * 处理消息的handler
 * TextWebSocketFrame:在netty中,是用于为websocket专门处理文本的对象,frame是消息的载体
 */

public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame>{
      
      // 用于记录和管理所有客户端的channel
      private static ChannelGroup clients =
                 new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
      @Override
      protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg)
                 throws Exception {
           // 获取客户端传输过来的消息
           String content = msg.text();
           System.out.println("接收到的数据:" + content);
           
           for(Channel channel : clients) {
                 channel.writeAndFlush(
                            new TextWebSocketFrame("[服务器在]" + LocalDateTime.now() + "接收到的消息为:" + content));
           }
           // 与上面的for循环功能一致
//         clients.writeAndFlush(
//                    new TextWebSocketFrame("[服务器在]" + LocalDateTime.now() + "接收到的消息为:" + content));
      }
      /**
       *  当客户端连接服务端之后(打开连接)
       *  获取客户端的channel,并且放到ChannelGroup中进行管理
       */
      @Override
      public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
           clients.add(ctx.channel());
      }
      @Override
      public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
           // 当触发handlerRemoved,ChannelGroup会自动移除对应客户端的channel
           // clients.remove(ctx.channel());
           System.out.println("客户端断开,channel对应的长ID为:" + ctx.channel().id().asLongText());
           System.out.println("客户端断开,channel对应的短ID为:" + ctx.channel().id().asShortText());
      }
}

 

相关推荐:

如何在Python Flask中实现敏感词过滤_构建自定义中间件

Flask中不能直接在路由里做敏感词过滤,因重复代码多、易漏检、难统一响应格式,且无法覆盖所有入口;应使用WSGI中间件或before_request钩子在请求进入视图前拦截,中间件更底层可靠,职责仅为阻断而非清洗。 Flask中为什么不能直接在路由里做敏感词过滤 因为重复代码多、易漏检、难统一响应...

为什么Python Flask在生产环境不建议使用flask-run_改用WSGI服务器

Flaskrun仅限开发环境,因其基于Werkzeug的单线程同步服务器,无进程管理、连接池、优雅重启和超时控制;并发超50即丢包,异常会直接崩溃进程;而Gunicorn和uWSGI通过多进程/协程、信号处理、Nginx协同等实现生产级稳定性与安全性。 flaskrun为什么只能用于开发环境 因为f...

Python3如何通过SSH批量巡检数百台Linux服务器

能,但需并发控制、连接复用和错误隔离:paramiko默认不复用连接,易触发socket和MaxStartups限制;exec_command()易截断输出;单点故障会导致全局阻塞;应使用invoke_shell()模拟终端、设超时、限流线程池、妥善处理密钥权限与认证。 能,但直接用paramiko...

文本分类在Python里怎么应对新词与未登录词_使用Subword与BPE算法构建分词器

结论:subword/BPE并非解决未登录词,而是让模型无需认识整词——靠子词拼合;关键在训练与下游任务的tokenization逻辑对齐。 直接说结论:用subword或BPE不是“解决”未登录词,而是让模型根本不需要“认识”整词——它靠子词拼出来。关键不在分词器本身多聪明,而在训练时是否对齐了s...