我正在将 Spring Web 套接字实现到我们的 Web 应用程序中,并且我想访问套接字控制器方法中的用户名,但我将其设置为 null。
这是代码
@MessageMapping("/user/sockettest" )
@SendTo("/topic/sockettestresult")
public String sockAdd(ListId[] listIds) {
..
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return stringRet;
}
Run Code Online (Sandbox Code Playgroud)
spring-security xml 看起来像这样
<sec:intercept-url pattern="/topic/**" access="permitAll" />
<sec:intercept-url pattern="/" access="permitAll" />
<sec:intercept-url pattern="/login*" access="permitAll" />
<sec:intercept-url pattern="/resources/**" access="permitAll" />
<sec:form-login login-page="/login" default-target-url="/user/home" always-use-default-target="true" authentication-failure-url="/login?error"/>
<sec:logout logout-success-url="/login?logout" delete-cookies="JSESSIONID" />
<sec:access-denied-handler error-page="/denied"/>
<sec:intercept-url pattern="denied/*" access="permitAll" />
<sec:csrf disabled="true" />
</sec:http>
Run Code Online (Sandbox Code Playgroud)
套接字配置如下所示
<websocket:stomp-endpoint path="/user/sockettest">
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic"/>
<websocket:message-converters register-defaults="false">
<bean id="mappingJackson2MessageConverter" class="org.springframework.messaging.converter.MappingJackson2MessageConverter">
<property name="objectMapper" ref="objectMapper"></property>
</bean>
</websocket:message-converters>
</websocket:message-broker>
Run Code Online (Sandbox Code Playgroud)
我看过一些示例,其中大多数都在 java 配置中,但是我遇到的问题是,当我使用 …
我有带有网络套接字配置的简单 Spring Boot 应用程序。
当我使用SimpleBroker(由spring提供)运行我的应用程序时,一切正常,但是当我想使用rabbitmq而不是SimpleBroker时,我遇到了一些问题,我的经纪人“不可用”
@Configuration
@EnableWebSocketMessageBroker
open class WebSocketConfig : ILogging by LoggingImp<WebSocketConfig>(),
WebSocketMessageBrokerConfigurer {
@Autowired
private lateinit var env: Environment
override fun registerStompEndpoints(registry: StompEndpointRegistry) {
registry.addEndpoint("/hig").setAllowedOrigins("*").withSockJS()
}
override fun configureMessageBroker(registry: MessageBrokerRegistry) {
registry.setApplicationDestinationPrefixes("/app")
val host = env.getProperty("spring.rabbitmq.host")!!
val port = env.getProperty("spring.rabbitmq.port")!!.toInt()
val login = env.getProperty("spring.rabbitmq.username")!!
val pass = env.getProperty("spring.rabbitmq.password")!!
log.debug("webSocket=$host, $port, $login, $pass")
// registry.enableSimpleBroker("/chat")
registry.enableStompBrokerRelay("/chat")
.setRelayHost(host)
.setRelayPort(port)
.setClientLogin(login)
.setClientPasscode(pass)
.setAutoStartup(true)
.setSystemHeartbeatReceiveInterval(10000)
.setSystemHeartbeatSendInterval(10000)
}
}
Run Code Online (Sandbox Code Playgroud)
来自 WebSocketMessageBrokerStats 的响应:
{
"loggingPeriod": 1800000,
"webSocketSessionStatsInfo": "0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 …Run Code Online (Sandbox Code Playgroud) 在我的 Spring Boot 应用程序中,我也使用了 websockets。一切正常,正如在生产中预期的那样。
现在我开始使用 Spring-Boot-Test 创建单元测试。
每次我启动 @SpringBootTest 时,都会遇到以下异常(缩短):
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'createWebSocketContainer' defined in class path resource [com/package/spring/ws/MyWebsocketConfig.class]: Invocation of init method failed;
Caused by: java.lang.IllegalStateException: Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext
Run Code Online (Sandbox Code Playgroud)
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at …Run Code Online (Sandbox Code Playgroud) 我试图从 Spring websocket SessionConnectEvent 获取主体用户名,但它在每个侦听器上均为空。我可能做错了什么?
为了实现它,我遵循了您可以在这里找到的答案:how to capture connection event in my webSocket server with Spring 4?
@Slf4j
@Service
public class SessionEventListener {
@EventListener
private void handleSessionConnect(SessionConnectEvent event) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(event.getMessage());
String sessionId = headers.getSessionId();
log.debug("sessionId is " + sessionId);
String username = headers.getUser().getName(); // headers.getUser() is null
log.debug("username is " + username);
}
@EventListener
private void handleSessionConnected(SessionConnectEvent event) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(event.getMessage());
String sessionId = headers.getSessionId();
log.debug("sessionId is " + sessionId);
String username = headers.getUser().getName(); …Run Code Online (Sandbox Code Playgroud) 我正在使用 spring WebSocket、SockJs 和 Amazon MQ 构建一个示例聊天应用程序。当客户端订阅主题时,它会抛出“代理不可用”异常。所有入站流量规则都在 AWS 安全组中正确设置,并且代理也有 stomp 支持。我正在关注这个Spring Guide。
如果我使用的是内存代理,它工作正常。我非常感谢您对此的帮助,以下是示例代码。
代理:Amazon MQ(内部使用 Active MQ)
版本:5.15.0
WebSocketConfig.java
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableStompBrokerRelay("/topic")
.setRelayHost("***********.mq.us-east-2.amazonaws.com").setRelayPort(61614)
.setClientLogin("******").setClientPasscode("*****");
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat-endpoint").withSockJS();
}
Run Code Online (Sandbox Code Playgroud)
应用程序启动日志
.......
INFO 14280 --- [alina-utility-1] o.s.m.s.s.StompBrokerRelayMessageHandler : Starting...
INFO 14280 --- [alina-utility-1] o.s.m.s.s.StompBrokerRelayMessageHandler : Starting "system" session, StompBrokerRelay[ReactorNettyTcpClient[reactor.netty.tcp.TcpClientDoOn@7acb7b3e]]
INFO 14280 --- [alina-utility-1] o.s.m.s.s.StompBrokerRelayMessageHandler : Started.
......
Run Code Online (Sandbox Code Playgroud)
客户
var socket = new SockJS('/chat-endpoint');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true); …Run Code Online (Sandbox Code Playgroud) 我正在尝试在我现有的Spring MVC应用程序中实现聊天.我指的是来自github的这两个链接 -
但是当我尝试通过websocket连接时,看起来初始的HttpHandhsake失败了.我已经在这里上传了我的源代码 - 服务器代码.这是关于源代码的简要介绍.配置类是 -
只有ChatController处理WebSocket和webapp/WEB-INF/pages/home.jsp包含客户端js.I我在Sock JS上使用STOMP.
因此,请查看代码并建议我进行聊天工作的更改.目前,当我在网络选项卡上看到它看起来像初始HttpHandshake失败,因为交换机协议请求的延迟非常高(它永远不会返回).
从网络和控制台面板编辑 ScreenShots -


我想创建 2 个网络套接字端点。你能说有可能吗?
在那种情况下应该是什么配置?
如何在WebSocketMessageBrokerStats中设置loggingPeriod以减小值(默认为30')
WebSocketMessageBrkerConfigurationSupport中的@Bean加载WebSocketMessageBrokerStats
版本:Spring 4.2.0.RELEASE
我目前的配置:
@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class AppWebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(final MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
}
@Override
public void registerStompEndpoints(final StompEndpointRegistry registry) {
registry.addEndpoint("/entry")
.setAllowedOrigins("*")
.withSockJS()
.setDisconnectDelay(10000);
}
}
Run Code Online (Sandbox Code Playgroud) 当我尝试在Spring websocket上从客户端向服务器发送消息时,我遇到了问题.我在服务器上配置Websocket并在控制器上创建@Message.我通过javascript从客户端发送数据.它有时会工作,但有时会失败并在服务器上抛出消息:MissingSessionUserException:消息中没有"user"标题
这是我的WebsocketConfig:
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/connectsocket").withSockJS();
}
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/");
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的MessageController:
@RestController
public class MessageController {
@Autowired
private SimpMessagingTemplate template;
@MessageMapping("/websocket/message")
public synchronized void message(Message<Object> messageObj,
WebMessage message, Principal principal) throws Exception {
if (principal != null) {
String name = principal.getName();
template.convertAndSendToUser(name, "/topic/dynamic", new MessagePojo("stage", "value", "message"));
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的Javascript-backbonejs代码:
app.Models.WebsocketModel = Backbone.Model.extend({
fetchData : function() {
console.log("WebsocketModel: fetchData");
var …Run Code Online (Sandbox Code Playgroud) 我有一个Spring Websocket Stomp应用程序,它接受SUBSCRIBE请求.
在应用程序中,我有一个SUBSCRIBE的处理程序,即
@Component
public class SubscribeStompEventHandler implements ApplicationListener<SessionSubscribeEvent> {
@Override
public void onApplicationEvent(SessionSubscribeEvent event) {}
}
Run Code Online (Sandbox Code Playgroud)
我用来验证订阅.
我会检查onApplicationEvent中的某些内容并从此函数将STOMP ERROR消息发送回客户端.
我找到了这个配方如何使用Spring WebSocket向STOMP客户端发送ERROR消息?但我需要了解如何获得outboundChannel.
我还尝试了以下代码:
public void sendStompError(SimpMessagingTemplate simpMessagingTemplate, String sessionId, String topic, String errorMessage) {
StompHeaderAccessor headerAccessor = StompHeaderAccessor.create(StompCommand.ERROR);
headerAccessor.setMessage(errorMessage);
headerAccessor.setSessionId(sessionId);
headerAccessor.setLeaveMutable(true);
simpMessagingTemplate.convertAndSendToUser(sessionId, topic, new byte[0], headerAccessor.getMessageHeaders());
}
Run Code Online (Sandbox Code Playgroud)
我试过主题成为一些subsciption主题和/ queue/error主题.但是我没有看到消息传播到客户端.
在客户端,我使用:
stompClient.connect(headers
, function (frame) {
console.log("Conn OK " + url);
}, function (error) {
console.log("Conn NOT OK " + url + ": " …Run Code Online (Sandbox Code Playgroud) spring-websocket ×10
spring ×5
websocket ×5
java ×4
spring-boot ×3
stomp ×3
sockjs ×2
spring-mvc ×2
amazon-mq ×1
backbone.js ×1
rabbitmq ×1
tomcat9 ×1