我目前正在开发一个需要使用WebSockets的项目.客户端将只是浏览器,因此对这两者的任何消息代理功能都不感兴趣.
虽然我认为这不会有什么不同,但是如果我可以对STOMP vs WAMP作为使用Spring-WebSockets的子协议获得一些评论感兴趣.
我可能会得到一些提示,可能有助于选择一个而不是另一个.
干杯,
EDITED(27-02-2014): 由于直接使用webSockets进行编程是低级的,因此在许多地方(一个是spring文档)建议使用一些子协议.
此外,在websocket上使用子协议是一种原生的webSocket安全性; 就像你可以做一个子协议验证.
还有许多其他子协议可用于代替STOMP或WAMP,如XMPP,AMQP.我找不到与这些和webSockets相关的太多信息,其中大部分只与消息代理有关.
是否可以创建STOMP和Spring 4的房间?Socket.IO有内置的房间,所以我想知道Spring是否有这个
我的代码目前:
@MessageMapping("/room/greet/{room}")
@SendTo("/room/{room}")
public Greeting greet(@DestinationVariable String room, HelloMessage message) throws Exception {
return new Greeting("Hello, " + room + "!");
}
Run Code Online (Sandbox Code Playgroud)
@SendTo("/ room/{room}")是理想的选择
但是,我受限于:
@SendTo("/room/room1")
@SendTo("/room/room2")
@SendTo("/room/room3")
Run Code Online (Sandbox Code Playgroud)
等......这非常非常不合理
客户是:
stompClient.subscribe('/room/' + roomID, function(greeting){
showGreeting(JSON.parse(greeting.body).content);
});
Run Code Online (Sandbox Code Playgroud)
roomID可以是room1,room2或room3 ...如果我想要更多房间怎么办?现在感觉就像这样的痛苦
我有一个网站(Java + Spring),它依赖于Websockets(Stomp over Websockets for Spring + RabbitMQ + SockJS)来实现某些功能.
我们正在创建一个基于Python的命令行界面,我们想添加一些使用websockets已经可用的功能.
有谁知道如何使用python客户端,所以我可以使用SockJS协议连接?
PS_我知道一个简单的库,我没有测试,但它没有订阅主题的能力
PS2_因为我可以从python直接连接到RabbitMQ的STOMP并订阅一个主题但直接暴露RabbitMQ感觉不对.有关第二种选择的任何评论?
有没有澄清,如果我使用"简单代理",Spring Websocket + SockJS的/ topic,/ queue等之间有什么区别?例如,这里向Spring Websocket上的特定用户发送消息:当您的客户端订阅以/ user /开头的频道时,例如:/ user/queue/reply,您的服务器实例将订阅名为queue/reply-user的队列[会话ID]
我想以一种明确的方式理解这种转换背后的逻辑.
我有一个OpenShift Wildfly服务器.我正在用Spring MVC框架构建一个网站.我的一个网页也使用WebSocket连接.在服务器端,我使用了@ServerEndpoint注释和javax.websocket.*库来创建我的websocket:
package com.myapp.spring.web.controller;
import java.io.IOException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.springframework.web.socket.server.standard.SpringConfigurator;
@ServerEndpoint(value="/serverendpoint", configurator = SpringConfigurator.class)
public class serverendpoint {
@OnOpen
public void handleOpen () {
System.out.println("JAVA: Client is now connected...");
}
@OnMessage
public String handleMessage (Session session, String message) throws IOException {
if (message.equals("ping")) {
// return "pong"
session.getBasicRemote().sendText("pong");
}
else if (message.equals("close")) {
handleClose();
return null;
}
System.out.println("JAVA: Received from client: "+ message); …Run Code Online (Sandbox Code Playgroud) spring-mvc spring-security websocket spring-boot spring-websocket
所以我们在后端使用Spring websocket STOMP + RabbitMQ,我们遇到了打开文件描述符的麻烦.经过一段时间后,我们达到了服务器的限制,服务器不接受任何连接,包括websockets和API端点.
2018-09-14 18:04:13.605 INFO 1288 --- [MessageBroker-1]
o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[2 current WS(2)-
HttpStream(0)-HttpPoll(0), 1159 total, 0 closed abnormally (0 connect
failure, 0 send limit, 63 transport error)], stompSubProtocol[processed
CONNECT(1014)-CONNECTED(1004)-DISCONNECT(0)], stompBrokerRelay[9 sessions,
127.0.0.1:61613 (available), processed CONNECT(1015)-CONNECTED(1005)-
DISCONNECT(1011)], inboundChannel[pool size = 2, active threads = 2, queued
tasks = 2, completed tasks = 12287], outboundChannelpool size = 0, active
threads = 0, queued tasks = 0, completed tasks = 4225], sockJsScheduler[pool
size = 1, active threads = 1, …Run Code Online (Sandbox Code Playgroud) 我们正在尝试使用spring webflux WebSocket实现设计WebSocket服务器.服务器具有通常的HTTP服务器操作,例如create/fetch/update/fetchall.使用WebSockets,我们试图公开一个端点,以便客户端可以利用单个连接进行所有类型的操作,因为WebSockets就是为此目的而设计的.它是一个使用webflux和WebSockets的正确设计吗?
我们正在开始一个将使用反应式网络套接字的项目spring-webflux.我们需要构建一个反应式客户端库,消费者可以使用它来连接到服务器.
在服务器上,我们收到请求,读取消息,保存并返回静态响应:
public Mono<Void> handle(WebSocketSession webSocketSession) {
Flux<WebSocketMessage> response = webSocketSession.receive()
.map(WebSocketMessage::retain)
.concatMap(webSocketMessage -> Mono.just(webSocketMessage)
.map(parseBinaryToEvent) //logic to get domain object
.flatMap(e -> service.save(e))
.thenReturn(webSocketSession.textMessage(SAVE_SUCCESSFUL))
);
return webSocketSession.send(response);
}
Run Code Online (Sandbox Code Playgroud)
在客户端,当有人调用save方法并从中返回响应时,我们想要打电话server.
public Mono<String> save(Event message) {
new ReactorNettyWebSocketClient().execute(uri, session -> {
session
.send(Mono.just(session.binaryMessage(formatEventToMessage)))
.then(session.receive()
.map(WebSocketMessage::getPayloadAsText)
.doOnNext(System.out::println).then()); //how to return this to client
});
return null;
}
Run Code Online (Sandbox Code Playgroud)
我们不确定,如何设计这个.理想情况下,我们认为应该有
1)client.execute应该只调用一次并以某种方式持有session.应使用相同的会话在后续调用中发送数据.
2)如何从我们进入的服务器返回响应session.receive? …
我们有一个Spring over WebSockets连接,我们正在传递一个CONNECT框架:
CONNECT\naccept-version:1.2\nheart-beat:10000,10000\n\n\u0000
Run Code Online (Sandbox Code Playgroud)
处理程序确认哪个,启动一个新会话,然后返回:
CONNECTED
version:1.2
heart-beat:0,0
Run Code Online (Sandbox Code Playgroud)
但是,我们想要心跳,以便我们可以保持WebSocket开放.我们没有使用SockJS.
我介绍了Spring Message Handler:
StompHeaderAccessor [headers={simpMessageType=CONNECT, stompCommand=CONNECT, nativeHeaders={accept-version=[1.2], heart-beat=[5000,0]}, simpSessionAttributes={}, simpHeartbeat=[J@5eba717, simpSessionId=46e855c9}]
Run Code Online (Sandbox Code Playgroud)
在获得heart-beat(本机标头)之后,它设置看起来像内存地址的内容simpHeartbeat=[J@5eba717, simpSessionId=46e855c9}]
值得注意的是,经纪人验证后:
Processing CONNECT session=46e855c9 (这里的sessionId与simpSessionId不同)?
在运行早期的TRACE调试时,我看到了一个通知"调度心跳......"或者那种效果......虽然我现在没有看到它?
知道发生了什么事吗?
谢谢
我在文档中找到了解释:
来自SockJS任务调度程序的线程池的SockJS任务计划程序统计信息,用于发送检测信号.请注意,在STOMP级别协商心跳时,将禁用SockJS心跳.
SockJS的心跳是否与STOMP心跳不同?
我有spring的配置和一个完整的功能stomp代理(activemq):
@Configuration
@EnableWebSocketMessageBroker
public class WebsocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
private static Logger LOG = org.slf4j.LoggerFactory.getLogger(WebsocketConfig.class);
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableStompBrokerRelay("/topic/", "/queue/");
config.setApplicationDestinationPrefixes("/app");
config.setUserDestinationPrefix("/user");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/socket").withSockJS();
}
}
Run Code Online (Sandbox Code Playgroud)
天真地,我虽然spring使用了我当前的activemq配置,但实际上它尝试使用默认的stomp端口连接到localhost中的服务器.我发现可以通过输入以下内容来更改此配置:
config.enableStompBrokerRelay("/topic/", "/queue/")
.setRelayHost("activeMQHOST")
.setRelayPort(9999);
Run Code Online (Sandbox Code Playgroud)
多数民众赞成,但目前我有两个经纪人的故障转移设置(master/flave with shared file system).如何为stomp broker relay配置这样的设置?
如果不可能,我想在以下解决方案中:
第二种选择是可取的吗?
我有一个带有 websockets 的 Spring Boot 应用程序:
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
@EnableScheduling
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
Run Code Online (Sandbox Code Playgroud)
WebSocket 配置:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
webSocketHandlerRegistry.addHandler(socketHandler(), "/connect/*")
.setAllowedOrigins("*")
.addInterceptors(handshakeInterceptor());
}
@Bean
public WebSocketHandler socketHandler() {
return new CustomHandler();
}
@Bean
public HandshakeInterceptor handshakeInterceptor() {
return new CustomInterceptor();
}
}
Run Code Online (Sandbox Code Playgroud)
它工作得很好。然后我添加@EnableSheduled并创建了 Scheduling 组件:
@Component
public class ScheduledTask {
@Scheduled(fixedRate = 1000)
public void printHello() …Run Code Online (Sandbox Code Playgroud) spring-websocket ×10
stomp ×7
spring ×5
java ×4
websocket ×3
spring-boot ×2
epoll ×1
netty ×1
python ×1
rabbitmq ×1
sockjs ×1
spring-mvc ×1
wamp ×1