Springboot stomp websocket使用應注意的地方


Springboot stomp websocket使用應注意的地方


使用使用了代理服務器

如果使用了Nginx,則需要開啟ng支持websocket,一般配置如下:

<code>$ vim /usr/local/nginx/conf/nginx.conf

# 在http上下文中增加如下配置,確保Nginx能處理正常http請求。

http{
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

upstream websocket {
#ip_hash;
server localhost:8010;
server localhost:8011;
}

# 以下配置是在server上下文中添加,location指用於websocket連接的path。

server {
listen 80;
server_name localhost;
access_log /var/log/nginx/yourdomain.log;

location / {
proxy_pass http://websocket;
proxy_read_timeout 30s; //超時自動斷開

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

\t\t}
\t}
}/<code>

是否開啟了心跳

設置心跳的好處:是可以將閒置較久或無用的連接自動斷開; 自己不用維護;

服務端開啟心跳,代碼如下:

<code>ThreadPoolTaskScheduler te = new ThreadPoolTaskScheduler();
te.setPoolSize(1);
te.setThreadNamePrefix("ws-heartbeat-thread-");
te.initialize();
registry.enableSimpleBroker( "/topic")
.setHeartbeatValue(new long[]{HEART_BEAT,HEART_BEAT}).setTaskScheduler(te);/<code>

建立連接之後顯示的客戶端和服務端心跳的信息如下:

>>> CONNECT

direction:2

clientId:1000000020184101

accept-version:1.1,1.0

heart-beat:10000,0 // 客戶端連接時的心跳設置


<<< CONNECTED

version:1.1

heart-beat:5000,5000 // 服務端建立連接後的心跳設置

user-name:yttqceuw

官網說明如下:

CONNECT

heart-beat:,


CONNECTED:

heart-beat:,

For heart-beats from the client to the server:


if is 0 (the client cannot send heart-beats) or is 0 (the server does not want to receive heart-beats) then there will be none


otherwise, there will be heart-beats every MAX(,) milliseconds


In the other direction, and are used the same way.

簡單點說就是, 大於0時,如果 max(sy, cx) > proxy_read_timeout(ng中設置的),則超過proxy_read_timeout會自動斷開。

服務端開啟發送心跳之後,會有幾個地方需要注意(會自動斷開)

  1. 如果服務端設置了發送心跳( > 0),間隔為5s, 假如客戶端也設置了發送心跳(),間隔為10s,那麼建立連接後,客戶端發送的心跳間隔就為10s (MAX(,)),如果任何一方發送消息的時間間隔超過了Nginx配置的超時時間(比如是 30s),那麼ng會自動斷開連接 。
  2. 服務端設置心跳之後,會啟動一個定時任務(HeartbeatTask),執行間隔為(min(,)), 任務的執行內容為服務端發送心跳,以及檢查連接無交互的時間間隔是否超過了 (MAX(,)),如果超過了,則服務端會主動斷開連接,具體源碼如下:


Springboot stomp websocket使用應注意的地方

SimpleBrokerMessageHandler.java

總結:

開啟心跳後會有很多限制,所以需綜合考慮是否開啟,如果不開啟,可自維護心跳機制(服務端主動發送自定義的心跳信息)。


服務端主動斷開

服務端向客戶端發送消息時,如果滿足下面兩個條件,則服務端會主動斷開(closeStatus=4500):

  • 服務端發送消息的時間超過指定時間(默認為10s,可通過 sendTimeLimit設置);
  • 服務端發送消息的大小超過指定大小(默認為512K,可通過 sendBufferSizeLimit設置);

具體配置代碼如下:

@Override

public void configureWebSocketTransport(WebSocketTransportRegistration registration) {

registration.setSendBufferSizeLimit(512 * 1024); // 512K

registration.setSendTimeLimit(10 * 10000); // 10s

}

查看連接斷開的原因

斷開枚舉類型見: org.springframework.web.socket.CloseStatus

獲取斷開連接的事件,查看具體的code:

@EventListener(SessionDisconnectEvent.class)

public void handleWebsocketDisconnectListner(SessionDisconnectEvent event) {

log.info("session closed : sessionId={}, status={}", event.getSessionId(), event.getCloseStatus());

}


分享到:


相關文章: