什么是websocket?
websocket是一種長連接協議,它可以在瀏覽器和服務器之間建立一個不受限的雙向實時通信的通道。
與http協議的區別
- http協議是短鏈接協議,一次請求對應一次響應。
- http協議下,如果瀏覽器不主動請求,服務器就沒法發送數據給瀏覽器。
- http協議需要三次握手,websocket協議只需要一次就能發送消息。
springmvc使用websocket
博主接手的業務系統中,有一個springmvc項目使用到了websocket,所以這里使用了springmvc來整合websocket。
導入websocket依賴
在springmvc的基礎依賴上添加websocket依賴。
<properties>
<spring-version>4.3.7.RELEASE</spring-version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring-version}</version>
</dependency>
配置websoket處理器
public class MySocketHandler extends TextWebSocketHandler {
private static ConcurrentHashMap<String, WebSocketSession> users = new ConcurrentHashMap<>();
private static Logger logger = LoggerFactory.getLogger(MySocketHandler.class);
@Override
public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
//建立連接
users.put(webSocketSession.getId(), webSocketSession);
}
@Override
public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
String message = webSocketMessage.getPayload().toString();
logger.info(webSocketSession + "---->" + webSocketMessage + ":"+ message);
TextMessage textMess = new TextMessage(message);
webSocketSession.sendMessage(textMess);
}
@Override
public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
logger.info("handleTransportError=====================");
if(users.get(webSocketSession.getId()) != null){
users.remove(webSocketSession.getId());
}
}
@Override
public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
//連接建立完畢
logger.info("用戶: " + webSocketSession.getRemoteAddress() + " is leaving, because:" + closeStatus);
if(users.get(webSocketSession.getId()) != null){
users.remove(webSocketSession.getId());
}
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}
創建websocket配置類
@Configuration
@EnableWebSocket
public class WebSocketServerConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// 添加攔截地址以及相應的websocket消息處理器
registry.addHandler(new MySocketHandler(), "/websocket")
.addInterceptors(new MyHandshakeInterceptor())
.setAllowedOrigins("*");
registry.addHandler(new MySocketHandler(), "/sockJs")
.addInterceptors(new MyHandshakeInterceptor())
.setAllowedOrigins("*")
.withSockJS();
}
}
編寫前端頁面
這里如果瀏覽器不支持websocket的話,可以通過sockjs來實現。這里我新建了一個message.html,頁面內容如下所示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>websocket</title>
</head>
<style type="text/css">
#div {
color: red;
}
</style>
<body>
<h1>webSocket</h1>
<div id="div">
</div>
<script type="text/javascript" src="./js/sockjs.js"></script>
<script type="text/javascript">
var div = document.getElementById('div');
var prefix = "ws://127.0.0.1:8088/";
var websocketUrl = prefix + 'websocket';
var sockJSUrl = prefix + 'socketJs';
var socket = null;
if ('WebSocket' in window) {
socket = new WebSocket(websocketUrl);
}
else {
socket = new SockJS(sockJSUrl);
}
socket.onopen = function(event){
console.log(event);
socket.send('websocket client connect test');
}
socket.onclose = function(event){
console.log(event);
}
socket.onerror = function(event){
console.log(event);
}
socket.onmessage = function(event){
console.log(event)
div.innerHTML += ('接受到服務器消息:' + event.data);
}
</script>
</body>
</html>
查看測試結果
博主微信公眾號
