websocket服務器端,SpringBoot-Websocket

 2023-10-15 阅读 30 评论 0

摘要:本文描述在spring boot下如何使用Websocket得兩種方式,并以此文紀念我逝去的二抱和三抱 websocket服務器端。方式1:spring對javax的完全封裝,可適用于復雜場景,例如IM即時通訊系統 方式2:javax注解+spring注解,場景適用于智能

本文描述在spring boot下如何使用Websocket得兩種方式,并以此文紀念我逝去的二抱和三抱

websocket服務器端。方式1:spring對javax的完全封裝,可適用于復雜場景,例如IM即時通訊系統

方式2:javax注解+spring注解,場景適用于智能機器人客服,用戶給服務器機器人發消息,服務器直接回復消息,配置上相對方式1來說簡單一些

我個人覺得方式1更全面,所以我先闡述方式1

為了方便測試,首先我們自己建立一個HTML頁面,超級簡單,你可以新建一個文本文檔,將后綴改成.html,然后直接復制下面我寫好的代碼,用瀏覽器打開即可,請注意我的端口是8081,請改成你需要的

<html>
懷念二抱三抱
<script>
var websocket= new WebSocket("ws://127.0.0.1:8081/ws");websocket.onopen = function(event) {console.log("WebSocket握手");
};
websocket.onmessage = function(event) {console.log("WebSocket客戶端收到一條消息:",event.data);
};
websocket.onerror = function(event) {console.log("WebSocket發生錯誤 ");
};
websocket.onclose = function(event) {console.log("WebSocket已關閉");console.log(event);
}
function sendMsg(){   var v=document.getElementById("msg").value;console.log("WebSocket客戶端發一條送消息:"+v);websocket.send(v);
}
</script>
<body><input type="text" placeholder="請輸入要發送的信息" id="msg" /><input type="button" value="發送" onclick="sendMsg()" />
</body>
</html>

接下來開始寫服務端,首先pom文件添加依賴

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

方式1
首先建立一個接受消息的類

public class MyWebSocketHandler implements WebSocketHandler {@Overridepublic void afterConnectionEstablished(WebSocketSession session) {//連接成功之后,應該在這個方法中將session保存起來,通常都用//一個Map來保存,key是用戶ID(或其他唯一標識),這樣的話想//給哪個用戶發送消息,那么就直接拿到那個用戶的session,然后//調用session.sendMessage方法發送消息就可以了System.out.println("連接成功");}@Overridepublic void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {System.out.println("客戶端過來一條消息,內容是:" + message.getPayload().toString());TextMessage textMessage = new TextMessage("客戶端你好,我已經收到你的消息");session.sendMessage(textMessage);}@Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {System.out.println("錯誤處理");}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {System.out.println("連接關閉");}@Overridepublic boolean supportsPartialMessages() {return false;}
}

然后將上面的類注入到WebSocket相關配置中,啟動項目,刷新瀏覽器即可

@Component
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {//開始我沒設置setAllowedOrigins,排查了很久很久,JS就提示//failed,然后沒有任何原因,讓我很惱火registry.addHandler(new MyWebSocketHandler(), "/ws").setAllowedOrigins("*");}
}

至此方式演示完畢,使用上面的代碼就可以實現任何IM功能了,但是還有一個額外的小功能需要說一下,就是方式1的攔截器,如果設置了攔截器,WebSocket請求過來的時候會先走攔截器,這個時候spring會給咱們2個東西,一個是request,一個是Map
request:獲取當前請求所有信息,比如請求的URL
map:我們可以往這個map放參數,然后在上面的MyWebSocketHandler中獲取到

使用下面的代碼設置攔截器

public class MyHandShake implements HandshakeInterceptor {private static final Logger LOG = LoggerFactory.getLogger(HandShake.class);@Overridepublic boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,Map<String, Object> attributes) {attributes.put("name", "蘭博");return true;}@Overridepublic void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,Exception exception) {}
}

將攔截器注入到容器中,這需要對前文的代碼進行一個修改

@Component
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {// 這行代碼比前文的多了一個.addInterceptors(new MyHandShake())registry.addHandler(new MyWebSocketHandler(), "/ws").addInterceptors(new HandShake()).setAllowedOrigins("*");}
}

上述完畢之后,就可以在獲取消息時,順便獲取攔截器中設置的name了,例如下面這樣

session.getAttributes().get("name").toString();

方式2:很簡單,只有這一個類,只要掃描到這類就可以了,不過不適用于多用戶聊天

import org.springframework.web.socket.server.standard.ServerEndpointExporter;
import org.springframework.context.annotation.Bean;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;@ServerEndpoint("/ws")
@Component
public class MyWebSocketHandler{@Beanpublic ServerEndpointExporter serverEndpoint() {return new ServerEndpointExporter();}@OnOpenpublic void onOpen(Session session) {System.out.println("連接成功");}@OnClosepublic void onClose(Session session) {System.out.println("連接關閉");}@OnMessagepublic String onMsg(String text) throws IOException {System.out.println("客戶端過來一條消息,內容是:" + text);return "客戶端你好,我已經收到你的消息";}
}

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/137133.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息