我有一个使用spring(4.2.x)工件的web应用程序spring-webmvc,spring-messaging,spring-websocket
我在spring config java类中使用了以下@ Enable*annotations
@EnableWebMvc
@EnableWebSocketMessageBroker
@EnableAsync
@EnableMBeanExport
Run Code Online (Sandbox Code Playgroud)
WebSocket用于向浏览器客户端广播消息.并且很少有使用@Async注释的异步方法
春季版本4.2.0.RC3的应用程序运行良好.但当我将其更改为GA版本4.2.0.RELEASE时,我在启动时得到以下异常.如果我删除@EnableAsync它工作正常,但我需要异步功能.
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.core.task.TaskExecutor] is defined: expected single matching bean but found 4: clientOutboundChannelExecutor,messageBrokerTaskScheduler,clientInboundChannelExecutor,brokerChannelExecutor
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:366)
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor.setBeanFactory(AsyncAnnotationBeanPostProcessor.java:128)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1597)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1565)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:201)
org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:228)
org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:682)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:522)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:667)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:539)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:493)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
Run Code Online (Sandbox Code Playgroud) 我正在使用带有SockJS的Spring-Websockets 4.2.
由于客户端收到的消息可能非常大,我想使用部分消息.我的TextWebSocketHandler的子类确实覆盖supportsPartialMessages以返回true.但是,由于Spring创建的SockJsWebSocketHandler不支持部分消息,我仍然会收到错误code=1009, reason=The decoded text message was too big for the output buffer and the endpoint does not support partial messages.
作为一种变通方法,如描述我增加了缓冲区大小为1 MB 这里,但因为我要支持相当大量的客户端(〜2000年在同一时间),这需要太多的内存.
有没有办法使用SockJS的部分消息?
我正在使用Spring 4 websockets和stomp进行实验,我很难弄清楚如何在注释的消息处理方法中获取/设置当前用户和其他会话属性@MessageMapping.
该文件说,处理方法的消息可以采取委托作为参数,我发现主要是由春检索调用getUserPrincipal()在本机插座会话,然后与插座会话相关的,但我没有发现任何方式除了编写servlet过滤器并将原始请求包装回一个返回我的cookie中找到的主体的包装器之外,可以轻松地自定义此行为.
所以我的问题是:
注意:请参阅问题底部的更新,了解我最终得出的结论.
我需要通过发送请求消息的Web套接字向请求发送多个响应,第一个快速响应,其他响应在数据验证之后(10到60秒之后,从多个并行线程).
我无法让后来的响应停止在所有打开的网络套接字上播放.如何让它们只发送到初始Web套接字?或者我应该使用Spring STOMP之外的东西(因为,老实说,我想要的是路由到各种功能的消息,我不需要或想要能够广播到其他网络套接字,所以我怀疑我可以写信息经销商自己,即使它正在重新发明轮子).
我没有使用Spring身份验证(这是在改进遗留代码中).
在初始返回消息中,我可以使用@SendToUser,即使我们没有用户,Spring也只将返回值发送到发送消息的websocket.(见这个问题).
但是,响应速度较慢,我认为我需要使用SimpMessagingTemplate.convertAndSendToUser(用户,目的地,消息),但我不能,因为我必须传入用户,而我无法弄清楚用户是什么用户使用SendToUser.我试图按照这个问题中的步骤进行操作,但是在未经过身份验证时没有使它工作(在这种情况下,principal.getName()返回null).
我已经为原型大大简化了这一点,所以不要担心同步线程或任何东西.我只是希望网络套接字正常工作.
这是我的控制器:
@Controller
public class TestSocketController
{
private SimpMessagingTemplate template;
@Autowired
public TestSocketController(SimpMessagingTemplate template)
{
this.template = template;
}
// This doesn't work because I need to pass something for the first parameter.
// If I just use convertAndSend, it broacasts the response to all browsers
void setResults(String ret)
{
template.convertAndSendToUser("", "/user/topic/testwsresponse", ret);
}
// this only sends "Testing Return" to the browser tab hooked to this …Run Code Online (Sandbox Code Playgroud) 我有一个带有websocket功能的简单弹簧应用程序,到目前为止一切正常.现在我想使用@SendToUser注释从我的服务器向特定客户端发送消息.这给了我错误"忽略消息,没有可用的主要信息".我知道我的服务器上没有任何登录信息,因此每个用户都是"匿名"且没有委托人(我现在不使用Spring安全性).但是每个用户都有一个session-id.是否有可能以某种方式使用会话ID来区分用户?我如何实现这一点,以便我的用户获得与session-id相对应的主体?
java spring spring-security spring-messaging spring-websocket
我正在使用带有后端弹簧的wss(安全网络套接字)和用于javascript客户端的STOMP.
有谁知道为什么得到:
Handshake failed due to invalid Upgrade header: null
Run Code Online (Sandbox Code Playgroud) 我需要对用户目标订阅做出反应.
用户订阅/user/messages,因为他想接收所有传入的消息.现在,我想查找该用户的任何消息,这些消息是在他离线时创建的,然后将它们发送给该用户.
客户代码:
stompClient.subscribe('/user/messages', function(msg){
alert(msg.body);
});
Run Code Online (Sandbox Code Playgroud)
服务器代码:
template.convertAndSendToUser(p.getName(), "/messages", "message content");
Run Code Online (Sandbox Code Playgroud)
似乎无法在服务器端捕获用户目标订阅,即:
@SubscribeMapping("/user/messages")
public void test(Principal p) {
sendMessagesThatWereReceivedWhileUserWasOffline();
}
Run Code Online (Sandbox Code Playgroud)
@SubscribeMapping("/messages")
public void test(Principal p) { ... }
Run Code Online (Sandbox Code Playgroud)
如果客户端订阅了/app/messages,这可以工作,但不会被调用 /user/messages.
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/queue", "/topic");
registry.setUserDestinationPrefix("/user");
}
@Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
return true;
}
// all …Run Code Online (Sandbox Code Playgroud) 我使用Spring的STOMP而不是WebSocket实现,使用功能齐全的ActiveMQ代理.当用户SUBSCRIBE访问某个主题时,在成功订阅之前,他们必须通过一些权限逻辑.我正在使用ChannelInterceptor来应用权限逻辑,如下所示:
WebSocketConfig.java:
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp")
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableStompBrokerRelay("/topic", "/queue")
.setRelayHost("relayhost.mydomain.com")
.setRelayPort(61613);
}
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.setInterceptors(new MySubscriptionInterceptor());
}
}
Run Code Online (Sandbox Code Playgroud)
WebSocketSecurityConfig.java:
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
.simpSubscribeDestMatchers("/stomp/**").authenticated()
.simpSubscribeDestMatchers("/user/queue/errors").authenticated()
.anyMessage().denyAll();
}
}
Run Code Online (Sandbox Code Playgroud)
MySubscriptionInterceptor.java:
public class MySubscriptionInterceptor extends ChannelInterceptorAdapter {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor headerAccessor= StompHeaderAccessor.wrap(message);
Principal …Run Code Online (Sandbox Code Playgroud) java activemq-classic stomp spring-messaging spring-websocket
我发现Spring WebSocket支持的当前文档指示用户使用stomp.js进行客户端JavaScript实现,这让我感到惊讶.
这个项目,在它的GitHub页面上的自述文件中说:
该项目不再维护.
如果您遇到错误或需要增强功能,您可以分叉并修改它,因为项目在Apache License 2.0下.
自2015年9月以来,该存储库没有任何提交(这只是为了将上述内容添加到自述文件中),并且自2014年12月以来没有代码提交,因此在过去的两年中它已被有效地放弃.
我不确定该存储库的284个分支中的哪个将是该库的稳定和最新版本,并且似乎没有可行的替代方案来自Google搜索.
有人可以推荐一个可以替代使用的稳定替代品吗?
理想情况下,我希望Spring团队能够为正确的客户端库提供一些指导,以便与他们的STOMP支持一起使用.
我是弹簧websocket的新手.我想将产品更改发送给客户.为此,我想按如下方式执行:客户端创建套接字连接并订阅目标:
var socket = new SockJS('/websocket');
var stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
stompClient.subscribe('/product/changes', function (scoredata) {
// We received product changes
});
});
//Send Ajax request and say server I want to know product with id=5 changes.
sendAjaxRequest(5);
Run Code Online (Sandbox Code Playgroud)
我已将弹簧应用程序配置如下:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/product/");
registry.setApplicationDestinationPrefixes("/app");
}
}
Run Code Online (Sandbox Code Playgroud)
现在我需要以下方法:
@RestController
public class ProductController {
@GetMapping("product-{id}")
public void startSubscribe(@PathVariable("id") Long …Run Code Online (Sandbox Code Playgroud) spring-websocket ×10
spring ×9
java ×5
stomp ×4
websocket ×4
sockjs ×2
spring-4 ×1
spring-boot ×1
spring-mvc ×1