SpringBoot整合Netty實(shí)現(xiàn)WebSocket的示例代碼
一、pom.xml依賴配置
<!-- netty --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.50.Final</version> </dependency>
二、代碼
2.1、NettyServer 類
package com.wangjing.socket.server; import com.wangjing.socket.handler.CoordinationSocketHandler; 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.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.stream.ChunkedWriteHandler; public class CoordinationNettyServer { private final int port; public CoordinationNettyServer(int port) { this.port = port; } public void start() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap sb = new ServerBootstrap(); sb.option(ChannelOption.SO_BACKLOG, 1024); sb.group(group, bossGroup) // 綁定線程池 .channel(NioServerSocketChannel.class) // 指定使用的channel .localAddress(this.port)// 綁定監(jiān)聽端口 .childHandler(new ChannelInitializer<SocketChannel>() { // 綁定客戶端連接時(shí)候觸發(fā)操作 @Override protected void initChannel(SocketChannel ch) throws Exception { //websocket協(xié)議本身是基于http協(xié)議的,所以這邊也要使用http解編碼器 ch.pipeline().addLast(new HttpServerCodec()); //以塊的方式來寫的處理器 ch.pipeline().addLast(new ChunkedWriteHandler()); ch.pipeline().addLast(new HttpObjectAggregator(8192)); ch.pipeline().addLast(new WebSocketServerProtocolHandler("/ws", "WebSocket", true, 65536 * 10)); ch.pipeline().addLast(new CoordinationSocketHandler());//自定義消息處理類 } }); ChannelFuture cf = sb.bind().sync(); // 服務(wù)器異步創(chuàng)建綁定 System.out.println(CoordinationNettyServer.class + "已啟動,正在監(jiān)聽: " + cf.channel().localAddress()); cf.channel().closeFuture().sync(); // 關(guān)閉服務(wù)器通道 } finally { group.shutdownGracefully().sync(); // 釋放線程池資源 bossGroup.shutdownGracefully().sync(); } } }
2.2、SocketHandler 類
package com.wangjing.socket.handler; import com.wangjing.socket.pool.CoordinationChannelHandlerPool; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; public class CoordinationSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("與客戶端建立連接,通道開啟!"); //添加到channelGroup通道組 CoordinationChannelHandlerPool.channelGroup.add(ctx.channel()); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println("與客戶端斷開連接,通道關(guān)閉!"); //從channelGroup通道組刪除 CoordinationChannelHandlerPool.channelGroup.remove(ctx.channel()); } @Override protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception { //接收的消息 System.out.println(String.format("收到客戶端%s的數(shù)據(jù):%s", ctx.channel().id(), msg.text())); // 單獨(dú)發(fā)消息 // sendMessage(ctx); // 群發(fā)消息 sendAllMessage(); } private void sendMessage(ChannelHandlerContext ctx) throws InterruptedException { String message = "我是服務(wù)器,你好呀"; ctx.writeAndFlush(new TextWebSocketFrame("hello")); } private void sendAllMessage() { String message = "我是服務(wù)器,這是群發(fā)消息"; CoordinationChannelHandlerPool.channelGroup.writeAndFlush(new TextWebSocketFrame(message)); } }
2.3、ChannelHandlerPool 類
package com.wangjing.socket.pool; import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; import io.netty.util.concurrent.GlobalEventExecutor; public class CoordinationChannelHandlerPool { public CoordinationChannelHandlerPool() { } //可以存儲userId與ChannelId的映射表 // public static ConcurrentHashMap<String, ChannelId> channelIdMap = new ConcurrentHashMap<>(); //channelGroup通道組 public static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); }
2.4、Application啟動類
package com.wangjing.socket; import com.wangjing.socket.server.CoordinationNettyServer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication(scanBasePackages = "com.wangjing") public class SocketApplication { public static void main(String[] args) { SpringApplication.run(SocketApplication.class, args); try { new CoordinationNettyServer(8804).start(); } catch (Exception e) { System.out.println("NettyServerError:" + e.getMessage()); } } }
三、測試
websocket 在線測試推薦:在線websocket測試-online tool-postjson
到此這篇關(guān)于SpringBoot整合Netty實(shí)現(xiàn)WebSocket的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot整合Netty實(shí)現(xiàn)WebSocket內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot+WebSocket+Netty實(shí)現(xiàn)在線聊天/群聊系統(tǒng)
- Java基于websocket協(xié)議與netty實(shí)時(shí)視頻彈幕交互實(shí)現(xiàn)
- Springboot+Netty+Websocket實(shí)現(xiàn)消息推送實(shí)例
- SpringBoot+Netty+WebSocket實(shí)現(xiàn)消息發(fā)送的示例代碼
- SpringBoot+WebSocket+Netty實(shí)現(xiàn)消息推送的示例代碼
- Netty搭建WebSocket服務(wù)器實(shí)戰(zhàn)教程
相關(guān)文章
Java實(shí)現(xiàn)將導(dǎo)出帶格式的Excel數(shù)據(jù)到Word表格
在Word中制作報(bào)表時(shí),我們經(jīng)常需要將Excel中的數(shù)據(jù)復(fù)制粘貼到Word中,這樣則可以直接在Word文檔中查看數(shù)據(jù)而無需打開另一個(gè)Excel文件。本文將通過Java應(yīng)用程序詳細(xì)介紹如何把帶格式的Excel數(shù)據(jù)導(dǎo)入Word表格。希望這篇文章能對大家有所幫助2022-11-11Mybatis中ResultMap解決屬性名和數(shù)據(jù)庫字段名不一致問題
我們Pojo類的屬性名和數(shù)據(jù)庫中的字段名不一致的現(xiàn)象時(shí)有發(fā)生,本文就詳細(xì)的介紹一下Mybatis中ResultMap解決屬性名和數(shù)據(jù)庫字段名不一致問題,感興趣的可以了解一下2021-10-10基于FeignClient調(diào)用超時(shí)的處理方案
這篇文章主要介紹了基于FeignClient調(diào)用超時(shí)的處理方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07SpringBoot整合OpenCV的實(shí)現(xiàn)示例
這篇文章主要介紹了SpringBoot整合OpenCV的實(shí)現(xiàn)示例。文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12