我在 Tomcat 8 上使用 Spring 4 websockets,我有以下配置:
<websocket:message-broker application-destination-prefix="/app">
<websocket:stomp-endpoint path="/notify">
<websocket:sockjs />
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic" />
</websocket:message-broker>
Run Code Online (Sandbox Code Playgroud)
我的 Spring 控制器有以下方法:
@MessageMapping("/notify/{client}")
public void pushMessage(@DestinationVariable long client, String message) {
System.out.println("Send " + message + " to " + client);
template.convertAndSend("/topic/push/" + client, message);
}
Run Code Online (Sandbox Code Playgroud)
所以我在这里尝试做的是,如果客户端 1 想要向客户端 2 发送消息,他会使用/app/notify/2. Spring 控制器然后将消息推送到 topic /topic/push/2。
我在客户端中编写了以下代码:
var id = 1;
var sock = new SockJS('/project/notify');
var client = Stomp.over(sock);
client.connect({}, function() {
client.subscribe('/topic/push/' + id, function(message) {
console.log(message); …Run Code Online (Sandbox Code Playgroud) 我有以下代码(来自 spring websocket 演示应用程序):
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/user/queue/greeting', function(greeting) {
displayQueueMessage(greeting);
});
function sendName() {
var name = document.getElementById('name').value;
stompClient.send("/app/wsdemo", {}, JSON.stringify({
'name' : name
}));
}
Run Code Online (Sandbox Code Playgroud)
这是对服务器上队列的简单订阅调用,以及另一种发送调用服务器的方法“sendName()”。
在调用 sendName 之后,服务器响应 connect 方法提供的回调函数:
function(greeting) {
displayQueueMessage(greeting);
});
Run Code Online (Sandbox Code Playgroud)
我的问题是 - 客户应该从subscribe调用等待多久,直到他可以开始调用sendName?我的意思是,我在这里可以看到的潜在问题如下:
i) 客户端首先订阅队列,
ii) 客户端调用 sendName
iii) 服务器在收到订阅调用之前收到第二个调用。
iv) 客户端不会收到来自服务器的响应。
我的问题:
1)那个场景真的是一个问题吗?
2)我怎样才能避免它?
3)我在某处读到过,因为 websocket 与 tcp 一起工作,所以消息的顺序是保持的,所以我的最后一个问题是 - 对于没有 websocket 支持的客户端,stompJS 的回退功能怎么样?订单也会维持吗?
我希望有人能帮助我解决这个问题。我正在将 Spring 的 Websocket 支持与 SockJs 和 StompJs 一起使用。我订阅了这样的队列:
var socket = new SockJS(localhost + 'websocket');
stompClient = Stomp.over(socket);
stompClient.connect('', '', function(frame) {
stompClient.subscribe("/user/queue/gotMessage", function(message) {
gotMessage((JSON.parse(message.body)));
});
}, function(error) {
});
Run Code Online (Sandbox Code Playgroud)
这对于 Spring 的 SimpMessageSendingOperations 非常有效。但是有一个大问题。队列名称如下所示:gotMessage-user3w4tstcj并且它没有声明为自动删除队列,但这正是我想要的。否则,我有 10k 个未使用的队列。在队列没有消费者的那一刻,应该删除队列。我怎么能假设呢?
我基于 Spring 框架实现了自己的 Websocket 应用程序并使用了相同的配置:http : //docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html
服务器端代码:
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
}
Run Code Online (Sandbox Code Playgroud)
客户端代码:*.jsp 文件
/*
*connect to websocket
*/
function connect() {
var socket = new SockJS("<c:url value='/ws'/>");
stompClient = Stomp.over(socket);
stompClient.connect();
}
function disconnect() {
stompClient.disconnect();
setConnected(false);
console.log("Disconnected");
}
Run Code Online (Sandbox Code Playgroud)
pom.xml 依赖项:
<!-- Spring websocket and messaging …Run Code Online (Sandbox Code Playgroud) In the server end, I use Spring-websocket, Handshake as follow:
public class WebsocketEndPoint extends TextWebSocketHandler {
@Override
protected void handleTextMessage(WebSocketSession session,
TextMessage message) throws Exception {
System.out.println("start to translate data!");
super.handleTextMessage(session, message);
for (int i = 0; i <= 1000; i++) {
session.sendMessage(new TextMessage("push message " + i));
Thread.sleep(2000);
}
session.sendMessage(message);
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("Connection Established!");
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("Connection Closed?");
}
}
Run Code Online (Sandbox Code Playgroud)
springmvc.xml as follow: …
我似乎遇到了一个问题,遇到了嵌入式 tomcat 对 stomp websocket 消息的 8k 大小限制。
从服务器向客户端发送消息时,出现以下错误。根据我读过的文档,似乎 tomcat 对通过 websockets 的消息有 8k 的限制,但我也读到 Stomp 可以发送部分消息并让客户端重新组装它们,这似乎没有发生。
消息永远不会到达客户端处理程序,所以我非常有信心问题出在我的 WebSocketConfig 中,但似乎无论我尝试过什么参数,我都无法克服 8k 消息和/或 B 的 A) 大小限制) 如果超过缓冲区限制,则以部分消息块的形式发送它。
双方都有如下错误码
[code=1009, reason=The decoded text message was too big for the output buffer and the endpoint does not support partial messages]
Run Code Online (Sandbox Code Playgroud)
我很确定我错过了一些简单的东西,但似乎无法解决它。任何额外的眼睛将不胜感激。谢谢!
服务器端 Stomp WebSocket 配置
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
private static final Logger logger = LoggerFactory.getLogger(WebSocketConfig.class);
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker(
"/resp",
"/not",
"/sub"
);
config.setApplicationDestinationPrefixes("/admin"); …Run Code Online (Sandbox Code Playgroud) stomp spring-boot spring-websocket java-websocket embedded-tomcat-8
我创建了我的项目,需要使用Jhipster和基于令牌的身份验证的 spring web socket .最近我发现,基于令牌的认证不具有Spring Web插座的工作在这里.如何在不重新开始应用程序的情况下更改身份验证类型
我已经在我的项目中通过 Stomp 配置了 Spring Websocket。
我的环境有 2 个集群节点和一个平衡器。如何在集群模式下配置spring websocket?
提前致谢
我想创建一个 Spring Server 和一个通过 sockjs-client 连接的 Broswer javascript 客户端。连接应该通过 Spring Security 来保护。
我有以下困境:
Spring Security 似乎假设 websocket 握手是通过经过身份验证的 http 会话发生的(例如 JSESSIONID cookie 设置,登录发生)。
然而,sockjs-client 似乎对开发人员施加了限制,即不得使用经过身份验证的 http 会话(参见https://github.com/sockjs/sockjs-client/issues/196),以任何方式强制执行此操作。
我对困境的评估是否正确,是否有任何明显的解决方案来实现带有 websockets 的 spring 服务器的安全性,以便 sockjs-client 可以安全地连接?
如果用于创建经过身份验证的 HttpSession,在 GET /info 请求中传递任何身份验证令牌的建议解决方案似乎是绕过 SockJS 安全限制的黑客。
这似乎是一些人出现问题的基础,例如:
今天,我已经搜索了几个小时的实现或教程,以了解如何在Spring中跟踪Websocket连接。
我已经完成了关于websockets和STOMP的(非常好)Spring教程。在这里链接
因此,我的设置是什么,我有一个带有Spring后端的Ionic Hybrid应用,我想在后端出现新的通知事件时向客户端发送通知。所有这些代码已经实现,并且连接正常,但是现在无法指定通知需要到达的位置。
在Spring教程的结构中,没有关于此问题的教程或解释(至少不经过5个小时的研究),而且我对有关Websocket和Web安全性的所有信息有些不知所措。(我已经学习了2天的websockets)
因此,对于之前和之后的所有工作,我认为按照Spring教程的结构进行紧凑而轻巧的回答非常有用。
我在StackOverflow上发现了这个未解决的问题,该问题与我遇到的问题相同,因此,我相信这些问题将证明它是值得的。
TL; DR
如何基于Spring WebSocket教程在后端中实现一个列表来跟踪连接?
建立连接后如何将数据从客户端发送到后端?(例如,用户ID或令牌)
spring-websocket ×10
spring ×8
java ×5
sockjs ×4
stomp ×2
javascript ×1
jhipster ×1
rabbitmq ×1
spring-boot ×1
websocket ×1