Springboot + Netty 搭建websocket服务器 入门

Springboot + Netty 搭建websocket服务器 入门

废话少说直接贴代码,会用再说

导入pom

  <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.36.Final</version>
  </dependency>

我们需要1个NettyServer 建立服务端 

@Component
public class NettyServer {
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();

    @Value("9999")
    private int port;

    @Autowired
    private NettyWebSocketHandler nettyWebSocketHandler;

    @PostConstruct
    public void start() throws Exception {

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
        bootstrap.group(workerGroup, bossGroup)
                .channel(NioServerSocketChannel.class)
                .localAddress(this.port)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        System.out.println("收到新连接" + socketChannel.localAddress());
                        //websocket协议本身是基于http协议的,所以这边也要使用http解编码器
                        socketChannel.pipeline().addLast(new HttpServerCodec());
                        //以块的方式来写的处理器
                        socketChannel.pipeline().addLast(new ChunkedWriteHandler());
                        //netty是基于分段请求的,HttpObjectAggregator的作用是将请求分段再聚合,参数是聚合字节的最大长度
                        socketChannel.pipeline().addLast(new HttpObjectAggregator(1024 * 8));
                        socketChannel.pipeline().addLast(new WebSocketServerProtocolHandler("/tradexServer", "WebSocket", true, 65536 * 10));
                        // 自定义的处理器
                        socketChannel.pipeline().addLast(nettyWebSocketHandler);
                    }
                });
        // 服务器异步创建
        ChannelFuture future = bootstrap.bind(port).sync();
        // 关闭服务器通道 会 wait
        //future.channel().closeFuture().sync();

    }

    @PreDestroy
    public void destroy() throws InterruptedException {

        // 释放线程池资源
        workerGroup.shutdownGracefully().sync();
        bossGroup.shutdownGracefully().sync();
    }
}

实现1个自定义的消息处理器  NettyWebSocketHandler

@Component
@ChannelHandler.Sharable
public class NettyWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    private static final Logger log = LoggerFactory.getLogger(NettyWebSocketHandler.class);
    public static ChannelGroup channelGroup;

    static {
        channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    }

    /**
     * 客户端与服务器建立连接时触发
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("与客户端{}建立连接,通道开启...", ctx.channel().localAddress());
        channelGroup.add(ctx.channel());
        sendMessage(ctx, JSON.toJSONString( "连接成功"));
    }

    /**
     * 与客户端断开连接时触发
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("与客户端{}断开连接,通道关闭...", ctx.channel().localAddress());
        channelGroup.remove(ctx.channel());
    }

    /**
     * 服务器接受客户端的数据
     *
     * @param ctx
     * @param text
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame text) throws Exception {
        String clientMsg = text.text();
        log.error("收到客户端{}的消息为 {}", ctx.channel().localAddress(), clientMsg);
    }

    /**
     * 给固定的人发消息
     *
     * @param ctx
     */
    private void sendMessage(ChannelHandlerContext ctx, String message) {
        ctx.channel().writeAndFlush(new TextWebSocketFrame(message));
    }

    /**
     * 发送群消息,此时其他客户端也能收到群消息
     */
    public void sendMessage(String message) {
        channelGroup.writeAndFlush(new TextWebSocketFrame(message));
    }
}
TextWebSocketFrame 继承了 WebSocketFrame,因为我们是进行文本传输吗,所以这里使用了这个

 

测试一下

 websocket在线测试

打开后,启动我们的springboot项目,然后链接进行测试

 

 

 netty解决 tcp 粘包 自定义协议   https://blog.csdn.net/zbw18297786698/article/details/53691915

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值