| | |
| | | package com.ycl.websocket; |
| | | |
| | | import com.ycl.websocket.handler.HeartBeatHandler; |
| | | import com.ycl.websocket.handler.WebSocketHandler; |
| | | import io.netty.bootstrap.ServerBootstrap; |
| | | import io.netty.channel.ChannelFuture; |
| | | import io.netty.channel.ChannelInitializer; |
| | |
| | | import io.netty.channel.socket.nio.NioServerSocketChannel; |
| | | import io.netty.handler.codec.http.HttpServerCodec; |
| | | import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; |
| | | import io.netty.handler.codec.serialization.ObjectEncoder; |
| | | import io.netty.handler.stream.ChunkedWriteHandler; |
| | | import io.netty.handler.timeout.IdleStateHandler; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * webscoket 服务 |
| | |
| | | * @author:xp |
| | | * @date:2024/4/11 17:47 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | @RequiredArgsConstructor |
| | | public class WebsocketServer { |
| | | |
| | | public static void runWebsocket() throws Exception { |
| | | private final WebSocketHandler webSocketHandler; |
| | | |
| | | public void runWebsocket() throws Exception { |
| | | // 处理 I/O 操作的多线程事件循环组(线程池)。bossGroup用于接收传入的连接,workerGroup用于处理IO操作 |
| | | EventLoopGroup bossGroup = new NioEventLoopGroup(); |
| | | EventLoopGroup workerGroup = new NioEventLoopGroup(); |
| | |
| | | // websocket的握手阶段是使用的Http,所以需要添处理http请求: |
| | | // 用于将 HTTP 请求和响应转换为字节流以及将字节流转换为 HTTP 请求和响应 |
| | | ch.pipeline().addLast(new HttpServerCodec()); |
| | | ch.pipeline().addLast(new WebSocketServerProtocolHandler("/ws", null, true, 6000)); |
| | | ch.pipeline().addLast(new WebSocketHandler()); |
| | | ch.pipeline().addLast(new ObjectEncoder()); |
| | | // 以块的方式来写的处理器 |
| | | ch.pipeline().addLast(new ChunkedWriteHandler()); |
| | | // ch.pipeline().addLast(new NettyWebSocketParamHandler(secret)); |
| | | // 针对客户端,若10s内无读事件则触发心跳处理方法HeartBeatHandler#userEventTriggered |
| | | ch.pipeline().addLast(new IdleStateHandler(60 , 60 , 60)); |
| | | // 自定义空闲状态检测(自定义心跳检测handler) |
| | | ch.pipeline().addLast(new HeartBeatHandler()); |
| | | ch.pipeline().addLast(new WebSocketServerProtocolHandler("/ws", "WebSocket", true, 65536 * 10)); |
| | | ch.pipeline().addLast(webSocketHandler); |
| | | } |
| | | }) |
| | | // 设置服务器通道(主通道)的选项,此处是设置连接请求队列的最大长度是128 |
| | | .option(ChannelOption.SO_BACKLOG, 128); |
| | | |
| | | // 绑定服务器到指定的端口,并且等待绑定操作完成。 |
| | | ChannelFuture f = b.bind(8084).sync(); |
| | | |
| | | ChannelFuture f = b.bind(8044).sync(); |
| | | log.info("websocket启动成功"); |
| | | log.info("程序启动成功"); |
| | | // 等待服务器的通道关闭。 |
| | | f.channel().closeFuture().sync(); |
| | | } finally { |
| | | workerGroup.shutdownGracefully(); |
| | | bossGroup.shutdownGracefully(); |
| | | log.error("websocket关闭"); |
| | | } |
| | | } |
| | | |