Spring Cloud微服務(wù)使用webSocket的方法
webSocket
webSocket長(zhǎng)連接是一種在單個(gè)tcp連接上進(jìn)行全雙工通信的協(xié)議,允許雙向數(shù)據(jù)推送。一般微服務(wù)提供的restful API只是對(duì)前端請(qǐng)求做出相應(yīng)。使用webSocket可以實(shí)現(xiàn)后端主動(dòng)向前端推送消息。
網(wǎng)關(guān)配置
spring cloud 的網(wǎng)關(guān)組件有zuul和getway
getway
base:
config:
nacos:
nacoshost: localhost
port: 8848
spring:
application:
name: gateway
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
server-addr: ${base.config.nacos.nacoshost}:${base.config.nacos.port}
gateway:
discovery:
locator:
enabled: true
routes:
# websocket
- id: CLOUD-WEBSOCKET
uri: lb:ws://cloud-websocket
predicates:
- Path=/cloud-websocket/**
server:
port: 8888
配置網(wǎng)關(guān)的時(shí)候注意添加ws協(xié)議。
zuul
zuul只能管理http請(qǐng)求,不推薦使用zuul管理websocket連接,推薦直連。
服務(wù)端
添加maven依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
添加webSocket 配置
@Configuration
@EnableWebSocket
public class WebsocketConfiguration implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// webSocket通道
// 指定處理器和路徑
registry.addHandler(new WebSocketHandler(), "/websocket")
// 指定自定義攔截器
.addInterceptors(new WebSocketInterceptor())
// 允許跨域
.setAllowedOrigins("*");
// sockJs通道
registry.addHandler(new WebSocketHandler(), "/sock-js")
.addInterceptors(new WebSocketInterceptor())
.setAllowedOrigins("*")
// 開啟sockJs支持
.withSockJS();
}
}
添加處理器
package com.auexpress.cloud.handler;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Description
* @ClassName WebSocketHandler
* @Author HYSong
* @date 2020.04.14 10:08
*/
public class WebSocketHandler extends AbstractWebSocketHandler {
/**
* 存儲(chǔ)sessionId和webSocketSession
* 需要注意的是,webSocketSession沒有提供無參構(gòu)造,不能進(jìn)行序列化,也就不能通過redis存儲(chǔ)
* 在分布式系統(tǒng)中,要想別的辦法實(shí)現(xiàn)webSocketSession共享
*/
private static Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap<>();
private static Map<String, String> userMap = new ConcurrentHashMap<>();
/**
* webSocket連接創(chuàng)建后調(diào)用
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) {
// 獲取參數(shù)
String user = String.valueOf(session.getAttributes().get("user"));
userMap.put(user, session.getId());
sessionMap.put(session.getId(), session);
}
/**
* 接收到消息會(huì)調(diào)用
*/
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
JSONObject jsonObject = JSONObject.parseObject(message.getPayload().toString());
String content = jsonObject.getString("content");
String targetAdminId = jsonObject.getString("targetId");
if("0".equals(targetAdminId)){
// 推送給所有人
userMap.forEach((key,value)->{
try {
this.sendMessage(key,content);
} catch (IOException e) {
e.printStackTrace();
}
});
}else{
sendMessage("1", content);
}
}
/**
* 連接出錯(cuò)會(huì)調(diào)用
*/
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) {
sessionMap.remove(session.getId());
}
/**
* 連接關(guān)閉會(huì)調(diào)用
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
sessionMap.remove(session.getId());
}
@Override
public boolean supportsPartialMessages() {
return false;
}
/**
* 后端發(fā)送消息
*/
public void sendMessage(String user, String message) throws IOException {
String sessionId = userMap.get(user);
if (StringUtils.isEmpty(sessionId)) {
return;
}
WebSocketSession session = sessionMap.get(sessionId);
if (session == null) {
return;
}
session.sendMessage(new TextMessage(message));
}
}
添加攔截器
package com.auexpress.cloud.interceptor;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
import java.util.Map;
/**
* @Description
* @ClassName WebSocketInterceptor
* @Author HYSong
* @date 2020.04.14 10:09
*/
public class WebSocketInterceptor implements HandshakeInterceptor {
/**
* handler處理前調(diào)用,attributes屬性最終在WebSocketSession里,
* 可能通過webSocketSession.getAttributes().get(key值)獲得
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
// 獲取請(qǐng)求路徑攜帶的參數(shù)
String user = serverHttpRequest.getServletRequest().getParameter("user");
attributes.put("user", user);
return true;
} else {
return false;
}
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
}
}
到此這篇關(guān)于Spring Cloud微服務(wù)使用webSocket的方法的文章就介紹到這了,更多相關(guān)Spring Cloud使用webSocket內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot添加jvm監(jiān)控實(shí)現(xiàn)數(shù)據(jù)可視化
這篇文章主要介紹了Springboot添加jvm監(jiān)控實(shí)現(xiàn)數(shù)據(jù)可視化,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
一次Spring無法啟動(dòng)的問題排查實(shí)戰(zhàn)之字節(jié)碼篇
最近學(xué)習(xí)了spring相關(guān)知識(shí),公司項(xiàng)目也用到了spring,下面這篇文章主要給大家介紹了一次Spring無法啟動(dòng)的問題排查實(shí)戰(zhàn)之字節(jié)碼篇的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04
springboot啟動(dòng)后和停止前執(zhí)行方法示例詳解
這篇文章主要介紹了springboot啟動(dòng)后和停止前執(zhí)行方法,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
controller接口跳轉(zhuǎn)到另一個(gè)controller接口的實(shí)現(xiàn)
這篇文章主要介紹了controller接口跳轉(zhuǎn)到另一個(gè)controller接口的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
SpringBoot?2.5.5整合輕量級(jí)的分布式日志標(biāo)記追蹤神器TLog的詳細(xì)過程
分布式追蹤系統(tǒng)是一個(gè)最終的解決方案,如果您的公司已經(jīng)上了分布式追蹤系統(tǒng),這篇文章主要介紹了SpringBoot?2.5.5整合輕量級(jí)的分布式日志標(biāo)記追蹤神器TLog,需要的朋友可以參考下2022-10-10
Spring中的攔截器HandlerInterceptor詳細(xì)解析
這篇文章主要介紹了Spring中的攔截器HandlerInterceptor詳細(xì)解析,HandlerInterceptor 是 Spring 框架提供的一個(gè)攔截器接口,用于在請(qǐng)求處理過程中攔截和處理請(qǐng)求,需要的朋友可以參考下2024-01-01

