如何配置zuul_SpringCloudSockjs实现前后端分离的长尾词WebSocket点对点消息发送?
- 内容介绍
- 文章标签
- 相关推荐
本文共计421个文字,预计阅读时间需要2分钟。
项目后端架构采用SpringCloud、SpringBoot。前端阶段使用Vue、SockJS。三方框架版本:SpringCloud Dalston.SR4,SpringBoot 1+。
项目后端架构采用SpringCloudSpringBoot前段使用VueSockJS。三方框架版本SpringCloudDalston.SR4SpringBoot1项目后端架构采用SpringCloudSpringBoot前段使用Vue SockJS。
三方框架
版本
SpringCloud
Dalston.SR4
SpringBoot
1.5.10
spring-cloud-starter-zuul
1.3.5
现在需要将异步任务的结果通过websocket通知前端希望可以websocket连接穿透zuul网关访问内部的websocket server微服务。找了一圈目前zuul 1.x还不支持websocket说是2.x会支持。后来找到github上有针对1.x的解决方法github.com/mthizo247/spring-cloud-netflix-zuul-websocket作者提供了demo可以跑通hello world。不过demo中是订阅topic广播的例子。
下面围绕demo提供的例子来实现点对点发送消息的功能。
思路是每个客户端连接后创建一个clientId并且将clientid存储到数据库后续可以将用户信息或者公司信息绑定到clientId上服务器端发送消息到指定client。
对于zuul和websocket微服务上的websocket连接必须使用同一个clientId这样方可实现点对点。具体步骤在zuul网关部分通过websocket handshakeinteceptor获取一个clientId然后clientId作为principal并且将clientId传递到websocket微服务在websocket微服务通过websocket handshakeinteceptor获取到clientId然后clientId作为principal。
连接创建后后端通过messagingTemplate的convertAndSendToUser发送消息给用户。
MessageMapping("/greeting")
public void greeting(HelloMessage message, MessageHeaders messageHeaders) throws Exception {
String sessionId this.getSessionId(messageHeaders);
Map a new HashMap();
a.put("body", message.getName());
messagingTemplate.convertAndSendToUser(sessionId, "/queue/notifications", payload)
}
private String getSessionId(MessageHeaders messageHeaders){
if(messageHeaders.get("simpSessionAttributes")!null ((Map)messageHeaders.get("simpSessionAttributes")).get("session_id");
if (sessionId!null) {
return sessionId.toString();
}
}
throw new RuntimeException("session id 丢失");
}
hello项目中websocketConfig的配置比较简单
package com.github.mthizo247.hello;
import java.security.Principal;
import java.util.Map;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.localhost:7078/gs-guide-websocket, null, {
transports: [websocket]
});
stompClient Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log(Connected: frame);
// 订阅用户消息通知
stompClient.subscribe("/user/queue/notifications",handleNotification);
});
function handleNotification(message) {
showGreeting(message);
}
}
见证一下效果
本文共计421个文字,预计阅读时间需要2分钟。
项目后端架构采用SpringCloud、SpringBoot。前端阶段使用Vue、SockJS。三方框架版本:SpringCloud Dalston.SR4,SpringBoot 1+。
项目后端架构采用SpringCloudSpringBoot前段使用VueSockJS。三方框架版本SpringCloudDalston.SR4SpringBoot1项目后端架构采用SpringCloudSpringBoot前段使用Vue SockJS。
三方框架
版本
SpringCloud
Dalston.SR4
SpringBoot
1.5.10
spring-cloud-starter-zuul
1.3.5
现在需要将异步任务的结果通过websocket通知前端希望可以websocket连接穿透zuul网关访问内部的websocket server微服务。找了一圈目前zuul 1.x还不支持websocket说是2.x会支持。后来找到github上有针对1.x的解决方法github.com/mthizo247/spring-cloud-netflix-zuul-websocket作者提供了demo可以跑通hello world。不过demo中是订阅topic广播的例子。
下面围绕demo提供的例子来实现点对点发送消息的功能。
思路是每个客户端连接后创建一个clientId并且将clientid存储到数据库后续可以将用户信息或者公司信息绑定到clientId上服务器端发送消息到指定client。
对于zuul和websocket微服务上的websocket连接必须使用同一个clientId这样方可实现点对点。具体步骤在zuul网关部分通过websocket handshakeinteceptor获取一个clientId然后clientId作为principal并且将clientId传递到websocket微服务在websocket微服务通过websocket handshakeinteceptor获取到clientId然后clientId作为principal。
连接创建后后端通过messagingTemplate的convertAndSendToUser发送消息给用户。
MessageMapping("/greeting")
public void greeting(HelloMessage message, MessageHeaders messageHeaders) throws Exception {
String sessionId this.getSessionId(messageHeaders);
Map a new HashMap();
a.put("body", message.getName());
messagingTemplate.convertAndSendToUser(sessionId, "/queue/notifications", payload)
}
private String getSessionId(MessageHeaders messageHeaders){
if(messageHeaders.get("simpSessionAttributes")!null ((Map)messageHeaders.get("simpSessionAttributes")).get("session_id");
if (sessionId!null) {
return sessionId.toString();
}
}
throw new RuntimeException("session id 丢失");
}
hello项目中websocketConfig的配置比较简单
package com.github.mthizo247.hello;
import java.security.Principal;
import java.util.Map;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.localhost:7078/gs-guide-websocket, null, {
transports: [websocket]
});
stompClient Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log(Connected: frame);
// 订阅用户消息通知
stompClient.subscribe("/user/queue/notifications",handleNotification);
});
function handleNotification(message) {
showGreeting(message);
}
}
见证一下效果

