SpringBoot整合websocket並區分不同頁面來源
阿新 • • 發佈:2018-11-28
首先web.xml新增支援
<!-- 新增websocket支援 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
配置socket
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
建立socket
import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; @ServerEndpoint(value = "/websocket/{user}") @Component public class MyWebSocket { /** * 靜態變數,用來記錄當前線上連線數。應該把它設計成執行緒安全的。 */ private static int onlineCount = 0; /** * concurrent包的執行緒安全Set,用來存放每個客戶端對應的MyWebSocket物件。 */ public static ConcurrentHashMap<String,MyWebSocket> webSocketSet = new ConcurrentHashMap<String,MyWebSocket>(); /** * 與某個客戶端的連線會話,需要通過它來給客戶端傳送資料 */ private Session session; /** * 傳過來的使用者 */ private String user = ""; /** * 連線建立成功呼叫的方法*/ @OnOpen public void onOpen(@PathParam(value = "user") String param, Session session) { //接收到傳送訊息的人員編號 user = param; this.session = session; /**加入set中*/ webSocketSet.put(param,this); /**線上數加1*/ addOnlineCount(); System.out.println("有新連線加入!當前線上人數為" + getOnlineCount()); try { sendMessage("-連線已建立-"); } catch (IOException e) { System.out.println("IO異常"); } } /** * 連線關閉呼叫的方法 */ @OnClose public void onClose() { if (!user.equals("")) { /** 從set中刪除 */ webSocketSet.remove(user); /** 線上數減1 */ subOnlineCount(); System.out.println("有一連線關閉!當前線上人數為" + getOnlineCount()); } } /** * 收到客戶端訊息後呼叫的方法 * * @param message 客戶端傳送過來的訊息*/ @OnMessage public void onMessage(String message, Session session) { System.out.println("來自客戶端的訊息:" + message); try { this.sendMessage(message); String sendUserno = message.split("[;]")[0]; // String sendMessage = message.split("[;]")[1]; // webSocketSet.get(sendUserno).sendMessage(message); } catch (IOException e) { e.printStackTrace(); } catch (MqttException e) { e.printStackTrace(); } // //群發訊息 // for (MyWebSocket item : webSocketSet) { // try { // item.sendMessage(message); // } catch (IOException e) { // e.printStackTrace(); // } // } } /** * 發生錯誤時呼叫 * **/ @OnError public void onError(Session session, Throwable error) { System.out.println("發生錯誤"); error.printStackTrace(); } public void sendMessage(String message) throws IOException { synchronized (session) { session.getBasicRemote().sendText(message); } } /** * 給指定的人傳送訊息 * @param message */ private void sendToUser(String message) { String sendUserno = message.split("[;]")[0]; String sendMessage = message.split("[;]")[1]; try { if (webSocketSet.get(sendUserno) != null) { webSocketSet.get(sendUserno).sendMessage( "使用者" + user + "發來訊息:" + " <br/> " + sendMessage); } else { System.out.println("當前使用者不線上"); } } catch (IOException e) { e.printStackTrace(); } } /** * 群發自定義訊息 * */ public static void sendInfo(String message) throws IOException { for (MyWebSocket item : webSocketSet.values()) { try { item.sendMessage(message); } catch (IOException e) { continue; } } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { MyWebSocket.onlineCount++; } public static synchronized void subOnlineCount() { MyWebSocket.onlineCount--; } }
html頁面
<!DOCTYPE HTML>
<html>
<head>
<title> WebSocket</title>
<style>
body{padding: 20px;background: #f5f5f5;}
#message{border: 1px dashed skyblue;padding: 20px;min-height: 300px;background: white;}
p{border-bottom: 1px dashed cornflowerblue;;}
</style>
</head>
<br />
<body>
<div>
<b>WebSocket</b><br />
<input id="text" type="text" placeholder="請輸入內容"/><button id="con" onclick="send()">傳送</button> <button id="con" onclick="connect()">連線socke</button>
<button class="btn btn-info btn-sm" onclick="closeWebSocket()">關閉連線</button>
<button class="btn btn-warning btn-sm" onclick="clearMsg()">清屏</button>
<br /><br />
</div>
<div id="message">
</div>
</body>
<div th:include="include/footer_js::footer"></div>
<script type="text/javascript">
var websocket = null;
var user=new Date().getTime();
//判斷當前瀏覽器是否支援WebSocket
function connect(){
if('WebSocket' in window){
websocket = new WebSocket("ws://localhost:8099/websocket/"+user);
$("#con").attr("disabled","disabled");
}
else{
alert('Not support websocket')
}
//連線發生錯誤的回撥方法
websocket.onerror = function(){
setMessageInnerHTML("error");
};
//連線成功建立的回撥方法
websocket.onopen = function(event){
setMessageInnerHTML("連線成功!");
}
//接收到訊息的回撥方法
websocket.onmessage = function(event){
setMessageInnerHTML("<p>"+event.data+"</p>");
}
//連線關閉的回撥方法
websocket.onclose = function(){
setMessageInnerHTML("close");
$("#con").removeAttr("disabled");
}
//監聽視窗關閉事件,當視窗關閉時,主動去關閉websocket連線,防止連線還沒斷開就關閉視窗,server端會拋異常。
window.onbeforeunload = function(){
websocket.close();
}
}
//將訊息顯示在網頁上
function setMessageInnerHTML(innerHTML){
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
//關閉連線
function closeWebSocket(){
websocket.close();
setMessageInnerHTML("已關閉!");
}
function clearMsg(){
$('#message').empty();
}
//傳送訊息
function send(){
var message = document.getElementById('text').value;
message=user+";"+message;
websocket.send(message);
}
</script>
</html>
針對於多個終端,所以在初始化和發訊息時,傳遞一個值作為使用者標識。