From ac92608ba4d4a2bbeffc124ee25d5f2778617e0e Mon Sep 17 00:00:00 2001 From: xiangpei <xiangpei@timesnew.cn> Date: 星期四, 11 四月 2024 18:09:30 +0800 Subject: [PATCH] netty实现websocket --- ycl-server/src/main/java/com/ycl/websocket/WebsocketServer.java | 57 +++++++++++++++++++ ycl-server/pom.xml | 8 ++ ycl-server/src/main/java/com/ycl/PlatformApplication.java | 7 ++ ycl-server/src/main/java/com/ycl/websocket/WebSocketHandler.java | 67 ++++++++++++++++++++++ 4 files changed, 139 insertions(+), 0 deletions(-) diff --git a/ycl-server/pom.xml b/ycl-server/pom.xml index 931bb3f..3a4c1b9 100644 --- a/ycl-server/pom.xml +++ b/ycl-server/pom.xml @@ -17,6 +17,14 @@ </properties> <dependencies> + + <!--netty--> + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-all</artifactId> + </dependency> + + <!-- 浠g爜鐢熸垚--> <dependency> <groupId>com.ycl</groupId> diff --git a/ycl-server/src/main/java/com/ycl/PlatformApplication.java b/ycl-server/src/main/java/com/ycl/PlatformApplication.java index fe80f2e..73a10aa 100644 --- a/ycl-server/src/main/java/com/ycl/PlatformApplication.java +++ b/ycl-server/src/main/java/com/ycl/PlatformApplication.java @@ -1,5 +1,6 @@ package com.ycl; +import com.ycl.websocket.WebsocketServer; import lombok.extern.slf4j.Slf4j; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; @@ -15,5 +16,11 @@ public static void main(String[] args) { SpringApplication.run(PlatformApplication.class, args); log.info("(鈾モ棤鈥库棤)锞夛緸 鑷础杩愮淮骞冲彴鍚姩鎴愬姛 醿�(麓凇`醿�)锞�"); + try { + WebsocketServer.runWebsocket(); + log.info("websocket鍚姩鎴愬姛"); + } catch (Exception e) { + log.info("websocket鍚姩澶辫触"); + } } } diff --git a/ycl-server/src/main/java/com/ycl/websocket/WebSocketHandler.java b/ycl-server/src/main/java/com/ycl/websocket/WebSocketHandler.java new file mode 100644 index 0000000..351bf42 --- /dev/null +++ b/ycl-server/src/main/java/com/ycl/websocket/WebSocketHandler.java @@ -0,0 +1,67 @@ +package com.ycl.websocket; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.group.ChannelGroup; +import io.netty.channel.group.DefaultChannelGroup; +import io.netty.handler.codec.http.websocketx.*; +import io.netty.util.concurrent.GlobalEventExecutor; + +import java.util.Objects; + + +public class WebSocketHandler extends SimpleChannelInboundHandler { + + public static ChannelGroup connects = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Object o) throws Exception { + if(Objects.nonNull(o) && o instanceof WebSocketFrame){ + this.handleWebSocketFrame(ctx, (WebSocketFrame) o); + } + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + System.out.println("鏈夋柊鐨勫鎴风杩炴帴涓婁簡"); + connects.add(ctx.channel()); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + System.out.println("鏈夊鎴风鏂紑杩炴帴浜�"); + connects.remove(ctx.channel()); + } + + // 澶勭悊ws鏁版嵁 + private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { + // 澶勭悊鍏抽棴杩炴帴 + if (frame instanceof CloseWebSocketFrame) { + connects.remove(ctx.channel()); + ctx.close(); + return; + } + if (frame instanceof TextWebSocketFrame) { + // 澶勭悊鏂囨湰娑堟伅 + String text = ((TextWebSocketFrame) frame).text(); + System.out.println("鏈嶅姟鍣ㄦ敹鍒板鎴风鏁版嵁锛�" +text); + // 姝ゅ涓虹兢鍙戯紝鍗曠嫭鍙戝彲浣跨敤connects.find(ctx.channel().id()).writeAndFlush()鍙戦�� + connects.writeAndFlush(new TextWebSocketFrame("浣犲ソ瀹㈡埛绔�")); + // ... + } else if (frame instanceof BinaryWebSocketFrame) { + // 澶勭悊浜岃繘鍒舵秷鎭� + // ... + } else if (frame instanceof PingWebSocketFrame) { + // 澶勭悊 Ping 娑堟伅 + // 鏀跺埌 Ping 娑堟伅锛屽洖搴斾竴涓� Pong 娑堟伅锛堣〃鏄庢垜杩樻椿鐫�锛� + ctx.channel().writeAndFlush(new PongWebSocketFrame(frame.content().retain())); + } else if (frame instanceof PongWebSocketFrame) { + // 澶勭悊 Pong 娑堟伅 + // pong娑堟伅濡傛灉娌℃湁鐗瑰畾闇�姹傦紝涓嶇敤澶勭悊 + } else if (frame instanceof ContinuationWebSocketFrame) { + // 澶勭悊杩炵画甯ф秷鎭紙姣旇緝澶х殑鏁版嵁锛屽垎鐗囷級 + // ... + } + } + +} diff --git a/ycl-server/src/main/java/com/ycl/websocket/WebsocketServer.java b/ycl-server/src/main/java/com/ycl/websocket/WebsocketServer.java new file mode 100644 index 0000000..25acb1f --- /dev/null +++ b/ycl-server/src/main/java/com/ycl/websocket/WebsocketServer.java @@ -0,0 +1,57 @@ +package com.ycl.websocket; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.HttpServerCodec; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; + +/** + * webscoket 鏈嶅姟 + * + * @author锛歺p + * @date锛�2024/4/11 17:47 + */ +public class WebsocketServer { + + public static void runWebsocket() throws Exception { + // 澶勭悊 I/O 鎿嶄綔鐨勫绾跨▼浜嬩欢寰幆缁勶紙绾跨▼姹狅級銆俠ossGroup鐢ㄤ簬鎺ユ敹浼犲叆鐨勮繛鎺ワ紝workerGroup鐢ㄤ簬澶勭悊IO鎿嶄綔 + EventLoopGroup bossGroup = new NioEventLoopGroup(); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + // 鏈嶅姟鍣ㄥ紩瀵�(鍚姩)绫伙紝鎻愪緵浜嗕竴浜涙柟娉曚娇寮�鍙戣�呰兘澶熺畝鍗曠殑鍚姩鏈嶅姟绔� + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup) + // 鎸囧畾鏈嶅姟鍣ㄩ�氶亾(涓汇�佸瓙閫氶亾)鐨勫疄鐜扮被 + .channel(NioServerSocketChannel.class) + // 璁剧疆閫氶亾鍒濆鍖栧櫒(ChannelInitializer)锛屾瘡娆″垱寤虹殑閫氶亾閮芥寜杩欎釜鍒濆鍖� + .childHandler(new ChannelInitializer<SocketChannel>() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + // websocket鐨勬彙鎵嬮樁娈垫槸浣跨敤鐨凥ttp锛屾墍浠ラ渶瑕佹坊澶勭悊http璇锋眰锛� + // 鐢ㄤ簬灏� HTTP 璇锋眰鍜屽搷搴旇浆鎹负瀛楄妭娴佷互鍙婂皢瀛楄妭娴佽浆鎹负 HTTP 璇锋眰鍜屽搷搴� + ch.pipeline().addLast(new HttpServerCodec()); + ch.pipeline().addLast(new WebSocketServerProtocolHandler("/ws", null, true, 6000)); + ch.pipeline().addLast(new WebSocketHandler()); + } + }) + // 璁剧疆鏈嶅姟鍣ㄩ�氶亾(涓婚�氶亾)鐨勯�夐」锛屾澶勬槸璁剧疆杩炴帴璇锋眰闃熷垪鐨勬渶澶ч暱搴︽槸128 + .option(ChannelOption.SO_BACKLOG, 128); + + // 缁戝畾鏈嶅姟鍣ㄥ埌鎸囧畾鐨勭鍙o紝骞朵笖绛夊緟缁戝畾鎿嶄綔瀹屾垚銆� + ChannelFuture f = b.bind(8084).sync(); + + // 绛夊緟鏈嶅姟鍣ㄧ殑閫氶亾鍏抽棴銆� + f.channel().closeFuture().sync(); + } finally { + workerGroup.shutdownGracefully(); + bossGroup.shutdownGracefully(); + } + } + +} -- Gitblit v1.8.0