日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Netty与Spring WebSocket

發(fā)布時(shí)間:2024/4/13 javascript 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Netty与Spring WebSocket 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

剛開始的時(shí)候,我嘗試著用netty實(shí)現(xiàn)了websocket服務(wù)端的搭建。在netty里面,并沒有websocket session這樣的概念,與其類似的是channel,每一個(gè)客戶端連接都代表一個(gè)channel。前端的ws請(qǐng)求通過netty監(jiān)聽的端口,走websocket協(xié)議進(jìn)行ws握手連接之后,通過一些列的handler(責(zé)鏈模式)進(jìn)行消息處理。與websocket session類似地,服務(wù)端在連接建立后有一個(gè)channel,我們可以通過channel進(jìn)行與客戶端的通信

/*** TODO 根據(jù)服務(wù)器傳進(jìn)來的id,分配到不同的group*/private static final ChannelGroup GROUP = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);@Overrideprotected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {//retain增加引用計(jì)數(shù),防止接下來的調(diào)用引用失效System.out.println("服務(wù)器接收到來自 " + ctx.channel().id() + " 的消息: " + msg.text());//將消息發(fā)送給group里面的所有channel,也就是發(fā)送消息給客戶端GROUP.writeAndFlush(msg.retain());}

那么,服務(wù)端用netty還是用spring websocket?以下我將從幾個(gè)方面列舉這兩種實(shí)現(xiàn)方式的優(yōu)缺點(diǎn)

使用netty實(shí)現(xiàn)websocket

玩過netty的人都知道netty是的線程模型是nio模型,并發(fā)量非常高,spring5之前的網(wǎng)絡(luò)線程模型是servlet實(shí)現(xiàn)的,而servlet不是nio模型,所以在spring5之后,spring的底層網(wǎng)絡(luò)實(shí)現(xiàn)采用了netty。如果我們單獨(dú)使用netty來開發(fā)websocket服務(wù)端,速度快是絕對(duì)的,但是可能會(huì)遇到下列問題:
1.與系統(tǒng)的其他應(yīng)用集成不方便,在rpc調(diào)用的時(shí)候,無(wú)法享受springcloud里feign服務(wù)調(diào)用的便利性
2.業(yè)務(wù)邏輯可能要重復(fù)實(shí)現(xiàn)
3.使用netty可能需要重復(fù)造輪子
4.怎么連接上服務(wù)注冊(cè)中心,也是一件麻煩的事情
5.restful服務(wù)與ws服務(wù)需要分開實(shí)現(xiàn),如果在netty上實(shí)現(xiàn)restful服務(wù),有多麻煩可想而知,用spring一站式restful開發(fā)相信很多人都習(xí)慣了。

使用spring websocket實(shí)現(xiàn)ws服務(wù)

spring websocket已經(jīng)被springboot很好地集成了,所以在springboot上開發(fā)ws服務(wù)非常方便,做法非常簡(jiǎn)單
第一步:添加依賴

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency>

第二步:添加配置類

@Configuration public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myHandler(), "/").setAllowedOrigins("*"); }@Beanpublic WebSocketHandler myHandler() {return new MessageHandler();} }

第三步:實(shí)現(xiàn)消息監(jiān)聽類

@Component @SuppressWarnings("unchecked") public class MessageHandler extends TextWebSocketHandler {private List<WebSocketSession> clients = new ArrayList<>();@Overridepublic void afterConnectionEstablished(WebSocketSession session) {clients.add(session);System.out.println("uri :" + session.getUri());System.out.println("連接建立: " + session.getId());System.out.println("current seesion: " + clients.size());}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) {clients.remove(session);System.out.println("斷開連接: " + session.getId());}@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) {String payload = message.getPayload();Map<String, String> map = JSONObject.parseObject(payload, HashMap.class);System.out.println("接受到的數(shù)據(jù)" + map);clients.forEach(s -> {try {System.out.println("發(fā)送消息給: " + session.getId());s.sendMessage(new TextMessage("服務(wù)器返回收到的信息," + payload));} catch (Exception e) {e.printStackTrace();}});} }

從這個(gè)demo中,使用spring websocket實(shí)現(xiàn)ws服務(wù)的便利性大家可想而知了。為了能更好地向spring cloud大家族看齊,我最終采用了spring websocket實(shí)現(xiàn)ws服務(wù)。
因此我的應(yīng)用服務(wù)架構(gòu)是這樣子的:一個(gè)應(yīng)用既負(fù)責(zé)restful服務(wù),也負(fù)責(zé)ws服務(wù)。沒有將ws服務(wù)模塊拆分是因?yàn)椴鸱殖鋈ヒ褂胒eign來進(jìn)行服務(wù)調(diào)用。第一本人比較懶惰,第二拆分與不拆分相差在多了一層服務(wù)間的io調(diào)用,所以就沒有這么做了。

總結(jié)

以上是生活随笔為你收集整理的Netty与Spring WebSocket的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。