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,因为我们是进行文本传输吗,所以这里使用了这个
测试一下
打开后,启动我们的springboot项目,然后链接进行测试
netty解决 tcp 粘包 自定义协议 https://blog.csdn.net/zbw18297786698/article/details/53691915