使用webSocket+springboot實現通訊(二)
阿新 • • 發佈:2018-12-20
步驟一:導包
<dependencies> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
步驟二:編寫類 class WebSocketConfig implements WebSocketConfigurer
package com.qf.websocket; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { /** * 註冊websock 處理器,其實就是誰最後來處理請求 * * @param webSocketHandlerRegistry */ @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) { //註冊websock的地址為/websocket/* 並添加了一個攔截器, 攔截器中會將請求地址中的最後一部分放入到map中傳遞到我們的handler中,.我們要求了最後一部分就是標記 webSocketHandlerRegistry.addHandler(new ChatMessageHandler(), "/websocket/*").addInterceptors(new ChatInterceptors()); } }
步驟三:編寫類 ChatInterceptors extends HttpSessionHandshakeInterceptor
package com.qf.websocket; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; import java.util.Map; public class ChatInterceptors extends HttpSessionHandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { //我們可以在這裡向屬性中新增一個值,這個值我們可以用作標記,map的key我們可以隨意,只要能保證唯一性以及記住就行 //獲取請求地址,我們要求 最後一個/後面是標記 String s = request.getURI().toString(); String substring = s.substring(s.lastIndexOf("/") + 1); attributes.put("name",substring); return super.beforeHandshake(request, response, wsHandler, attributes); } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) { super.afterHandshake(request, response, wsHandler, ex); } }
步驟四:編寫類 ChatMessageHandler extends TextWebSocketHandler
package com.qf.websocket;
import com.google.gson.Gson;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* 這個物件是單例的,
* 當前類是一個訊息的處理類
* @author dongbo
* @date 2018/11/9 20:44
*/
public class ChatMessageHandler extends TextWebSocketHandler {
private Map<String,WebSocketSession> allClient = new ConcurrentHashMap<>();
/**
* 當連結建立的時候,相當於onOpen
* @param session
* @throws Exception
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
//攔截器中的map存放著我們的name
Map<String, Object> attributes = session.getAttributes();
//將連結存入map集合中
allClient.put(((String) attributes.get("name")),session);
super.afterConnectionEstablished(session);
}
/**
* 相當於onMessage
* @param session
* @param message
* @throws Exception
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
byte[] bytes = message.asBytes();
String content = new String(bytes);
//將收到的資訊存放在map中
Map map = new Gson().fromJson(content, Map.class);
//獲取訊息的接受者
String to = (String) map.get("to");
//獲取傳送的訊息
String content1 = (String) map.get("content");
//獲取接受者的連結
WebSocketSession session1 = allClient.get(to);
//獲取傳送者
String from = (String) session.getAttributes().get("name");
if(session1!=null&&session1.isOpen()){
//傳送訊息
session1.sendMessage(new TextMessage("收到"+from+"傳送的訊息,內容是:====>"+content1));
}
//群發
Set<Map.Entry<String, WebSocketSession>> entries = allClient.entrySet();
for (Map.Entry<String, WebSocketSession> entry : entries) {
if(entry.getValue()!=null&&entry.getValue().isOpen()){
entry.getValue().sendMessage(new TextMessage("收到"+from+"傳送的訊息,內容是:====>"+content1));
}
}
super.handleTextMessage(session, message);
}
/**
* 相當於onClose
* @param session
* @param status
* @throws Exception
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
super.afterConnectionClosed(session, status);
}
}
步驟五:前端介面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript">
var websocket = null;
function abc() {
var name = document.getElementById("name").value;
if("WebSocket" in window){
websocket = new WebSocket("ws://"+document.location.host+"/websocket/"+name);
websocket.onopen = function () {
setMessage("連結成功");
}
websocket.onmessage = function (message) {
setMessage(message.data);
}
websocket.onerror = function (){
setMessage("連結出錯");
}
websocket.onclose = function () {
setMessage("關閉連結");
}
}else {
alert("瀏覽器太垃圾了");
}
}
function setMessage(data) {
var message = document.getElementById("xianshi");
message.innerHTML = data;
}
function sendMessage() {
var to = document.getElementById("to").value;
var mes = document.getElementById("content").value;
if(websocket!=null){
var message = '{"to":"'+to+'","content":"'+mes+'"}';
websocket.send(message);
}
}
function close() {
if(websocket!=null){
websocket.clone();
}
}
window.onbeforeunload = function () {
close();
}
</script>
</head>
<body>
使用者名稱 <input id="name"> <input type="button" onclick="abc()" value="連結"><br>
接受者 <input id="to"><br>
傳送內容<input id="content"> <input type="button" onclick="sendMessage()" value="傳送"><br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<span id="xianshi"></span>>
</body>
</html>
步驟六:啟動類
package com.qf.websocket;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author dongbo
* @date 2018/11/9 20:52
*/
@SpringBootApplication
public class StartApp {
public static void main(String[] args) {
SpringApplication.run(StartApp.class,args);
}
}