Springboot中使用websocket

引入依賴jar

本例項使用的springboot版本是2。2。12

org。springframework。boot spring-boot-starter-websocket

啟用WebSocket

使用註解@EnableWebSocket啟用

@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry reg) { reg。addHandler(wsChargeStatusHandler(), “/ws/status/handle”); reg。addHandler(wsChargeStatusHandler(), “/ws/status/handle/sockjs”)。withSockJS(); } @Bean public WebSocketChargeStatusHandler wsChargeStatusHandler(){ return new WebSocketChargeStatusHandler(); }}

定義具體業務的WebSocketHandler類

利用TextWebSocketHandler抽象類,覆蓋handleTextMessage()方法來發送文字訊息。

public class WebSocketChargeStatusHandler extends TextWebSocketHandler { @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String payload = message。getPayload(); Gson gson = new Gson(); Map map = gson。fromJson(payload, Map。class); String msg = “”; try { msg = yourRestApiByParams(map。get(“orderNo”)); } catch (Exception ex) { } session。sendMessage(new TextMessage(msg)); } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { super。afterConnectionEstablished(session); MyWsSessionManager。add(session); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { MyWsSessionManager。remove(session); } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { MyWsSessionManager。remove(session); if (session。isOpen()) { session。close(); } }}

自定義Session管理類,包括新增和刪除方法。

public class MyWsSessionManager { private static Map SessionKeyMap = new ConcurrentHashMap<>(200); public static void add(WebSocketSession session) { if (session != null) { SessionKeyMap。put(session。getId(), session); } } public static void remove(WebSocketSession session) { if (session != null) { SessionKeyMap。remove(session。getId()); } }}

前端Js的使用

如果是https協議,websocket需要使用wss,利用new WebSocket()建立webSocket物件。定義出websocket物件的onmessage()等鉤子函式,來收發訊息。

var websocket = null;function websocketQuery(params){ var wsurl = window。location。host + “/ws/status/handle”; if (websocket == null) { let wsroot = location。protocol === ‘https:’? ‘wss://’: ‘ws://’; if (‘WebSocket’ in window) { websocket = new WebSocket(wsroot + wsurl); } else if (‘MozWebSocket’ in window) { websocket = new MozWebSocket(wsroot + wsurl); } else { try { websocket = new SockJS(location。protocol + “//” + wsurl + “/sockjs”); }catch (error){ websocketError = true; } } } websocket。onerror = function (event) { console。log(“wsError = ” + event); websocketError = true; }; websocket。onopen = function (event) { ROUND_ROBIN_STARTED = true; websocket。send(JSON。stringify(params)); }; websocket。onmessage = function (rep) { var data = rep。data; console。log(“onmessage:” + data); var timeoutProcess; if (data == ‘’ || data == null) { timeoutProcess = setTimeout(function () { websocket。send(JSON。stringify(params)); }, 2000) } else if (data != ‘PENDING’) { //支付狀態也改變 clearTimeout(timeoutProcess); var encodeSign = filter(sign); window。location。href = “/payment/success/handle?orderNo=” + orderNo + “&appId=” + appId + “×tamp=” + timestamp + “&sign=” + encodeSign + “”; } else if (data != ‘’) {//未支付 timeoutProcess = setTimeout(function () { websocket。send(JSON。stringify(params)); }, 2000) } }; websocket。onclose = function (event) { console。log(event); if (websocket。readyState > 0) { websocketError = true; } };}

Nginx伺服器配置

與WebSocket相關的配置如下:

proxy_set_header Origin “”;

proxy_http_version 1。1;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection ‘upgrade’;

下面是一個具體的配置例項

listen 80;listen 443 ssl;ssl on;server_name domain。com;ssl_certificate cert/domain。com。crt;ssl_certificate_key cert/domain。com。key;location ~/ws/ { proxy_pass http://127。0。0。1:8090; index dashboard index; proxy_redirect off; proxy_set_header Origin “”; proxy_http_version 1。1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection ‘upgrade’; proxy_connect_timeout 300; proxy_send_timeout 600; proxy_read_timeout 600; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }