javascript
Netty与Spring WebSocket
剛開始的時候,我嘗試著用netty實現了websocket服務端的搭建。在netty里面,并沒有websocket session這樣的概念,與其類似的是channel,每一個客戶端連接都代表一個channel。前端的ws請求通過netty監聽的端口,走websocket協議進行ws握手連接之后,通過一些列的handler(責鏈模式)進行消息處理。與websocket session類似地,服務端在連接建立后有一個channel,我們可以通過channel進行與客戶端的通信
/*** TODO 根據服務器傳進來的id,分配到不同的group*/private static final ChannelGroup GROUP = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);@Overrideprotected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {//retain增加引用計數,防止接下來的調用引用失效System.out.println("服務器接收到來自 " + ctx.channel().id() + " 的消息: " + msg.text());//將消息發送給group里面的所有channel,也就是發送消息給客戶端GROUP.writeAndFlush(msg.retain());}那么,服務端用netty還是用spring websocket?以下我將從幾個方面列舉這兩種實現方式的優缺點
使用netty實現websocket
玩過netty的人都知道netty是的線程模型是nio模型,并發量非常高,spring5之前的網絡線程模型是servlet實現的,而servlet不是nio模型,所以在spring5之后,spring的底層網絡實現采用了netty。如果我們單獨使用netty來開發websocket服務端,速度快是絕對的,但是可能會遇到下列問題:
1.與系統的其他應用集成不方便,在rpc調用的時候,無法享受springcloud里feign服務調用的便利性
2.業務邏輯可能要重復實現
3.使用netty可能需要重復造輪子
4.怎么連接上服務注冊中心,也是一件麻煩的事情
5.restful服務與ws服務需要分開實現,如果在netty上實現restful服務,有多麻煩可想而知,用spring一站式restful開發相信很多人都習慣了。
使用spring websocket實現ws服務
spring websocket已經被springboot很好地集成了,所以在springboot上開發ws服務非常方便,做法非常簡單
第一步:添加依賴
第二步:添加配置類
@Configuration public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myHandler(), "/").setAllowedOrigins("*"); }@Beanpublic WebSocketHandler myHandler() {return new MessageHandler();} }第三步:實現消息監聽類
@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("接受到的數據" + map);clients.forEach(s -> {try {System.out.println("發送消息給: " + session.getId());s.sendMessage(new TextMessage("服務器返回收到的信息," + payload));} catch (Exception e) {e.printStackTrace();}});} }從這個demo中,使用spring websocket實現ws服務的便利性大家可想而知了。為了能更好地向spring cloud大家族看齊,我最終采用了spring websocket實現ws服務。
因此我的應用服務架構是這樣子的:一個應用既負責restful服務,也負責ws服務。沒有將ws服務模塊拆分是因為拆分出去要使用feign來進行服務調用。第一本人比較懶惰,第二拆分與不拆分相差在多了一層服務間的io調用,所以就沒有這么做了。
總結
以上是生活随笔為你收集整理的Netty与Spring WebSocket的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于WebSocket分布式实现的一种方
- 下一篇: Spring boot中最大连接数、最大