GVKun编程网logo

具有嵌入式ActiveMQ Broker的Spring Boot WebSocket

17

本文将分享具有嵌入式ActiveMQBroker的SpringBootWebSocket的详细内容,此外,我们还将为大家带来关于Errorcreatingbeanwithname''webSocket

本文将分享具有嵌入式ActiveMQ Broker的Spring Boot WebSocket的详细内容,此外,我们还将为大家带来关于Error creating bean with name ''webSocketServer''(springboot 整合 webstock)、java – 无法使用内置的BrokerService.stop调用关闭嵌入式activeMQ服务、Spring 4 AbstractWebSocketMessageBrokerConfigurer与SockJS无法正确协商传输、Spring 4 WebSocket Remote Broker配置的相关知识,希望对你有所帮助。

本文目录一览:

具有嵌入式ActiveMQ Broker的Spring Boot WebSocket

具有嵌入式ActiveMQ Broker的Spring Boot WebSocket

我尝试使用Spring Boot 1.5.4将Web应用程序从简单代理更改为带有脚踩的嵌入式ActiveMq代理,但始终在启动时出现错误

Caused by: java.lang.IllegalArgumentException: No handlers    at org.springframework.util.Assert.isTrue(Assert.java:92) ~[spring-core-4.3.9.RELEASE.jar:4.3.9.RELEASE]    at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.start(SubProtocolWebSocketHandler.java:244) ~[spring-websocket-4.3.9.RELEASE.jar:4.3.9.RELEASE]    at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:175) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]    ... 15 common frames omitted

我用一个简单的例子减少了失败

POM文件*

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.example</groupId>    <artifactId>websocket</artifactId>    <version>0.0.1-SNAPSHOT</version>    <packaging>jar</packaging>    <name>websocket</name>    <description>Demo project for Spring Boot</description>    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.4.RELEASE</version>        <relativePath/> <!-- lookup parent from repository -->    </parent>    <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>        <java.version>1.8</java.version>    </properties>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-activemq</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-websocket</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-configuration-processor</artifactId>        </dependency>        <dependency>            <groupId>org.apache.activemq</groupId>            <artifactId>activemq-stomp</artifactId>        </dependency>        <dependency>            <groupId>io.projectreactor</groupId>            <artifactId>reactor-net</artifactId>        </dependency>        <dependency>            <groupId>io.projectreactor</groupId>            <artifactId>reactor-core</artifactId>        </dependency>        <dependency>            <groupId>io.netty</groupId>            <artifactId>netty-all</artifactId>            <version>4.1.2.Final</version>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>    </dependencies>    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build></project>

应用类别

package com.example.websocket;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class WebsocketApplication {    public static void main(String[] args) {        SpringApplication.run(WebsocketApplication.class, args);    }}

WebSocketConfig类别

package com.example.websocket;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Configuration;import org.springframework.jms.annotation.EnableJms;import org.springframework.messaging.simp.config.MessageBrokerRegistry;import org.springframework.web.socket.config.annotation.EnableWebSocket;import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;import org.springframework.web.socket.config.annotation.StompEndpointRegistry;import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurationSupport;@Configuration@EnableWebSocket@EnableWebSocketMessageBroker@EnableJmspublic class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport {    @Value("${spring.activemq.user}")    private String mqUser;    @Value("${spring.activemq.password}")    private String mqPasword;    @Override    public void configureMessageBroker(final MessageBrokerRegistry config) {        config.enableStompBrokerRelay("/topic") //        .setRelayHost("localhost") //        .setRelayPort(61613) //        .setClientLogin(mqUser) //        .setClientPasscode(mqPasword) //        ;        config.setApplicationDestinationPrefixes("/app");    }    @Override    public void registerStompEndpoints(final StompEndpointRegistry registry) {        registry.addEndpoint("/websocket").withSockJS();    }}

application.yml

spring:  activemq:    broker-url: stomp://localhost:61613    user: user    password: pass

有人知道我的错误吗?

答案1

小编典典

我找到了解决方案。我的问题是EnableWebSocketMessageBroker批注和ActiveMQ Broker的缺少部署

删除application.yml并将WebSocketConfig类更改为

package com.example.websocket;import org.apache.activemq.broker.BrokerService;import org.apache.activemq.broker.jmx.ManagementContext;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.messaging.simp.config.MessageBrokerRegistry;import org.springframework.web.socket.config.annotation.EnableWebSocket;import org.springframework.web.socket.config.annotation.StompEndpointRegistry;import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurationSupport;@Configuration@EnableWebSocketpublic class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport {    @Override    public void configureMessageBroker(final MessageBrokerRegistry config) {        config.enableStompBrokerRelay("/topic") //        .setRelayHost("localhost") //        .setRelayPort(61613);        config.setApplicationDestinationPrefixes("/app");    }    @Override    public void registerStompEndpoints(final StompEndpointRegistry registry) {        registry.addEndpoint("/websocket").withSockJS();    }    @Bean(initMethod = "start", destroyMethod = "stop")    public BrokerService broker() throws Exception {        final BrokerService broker = new BrokerService();        broker.addConnector("stomp://localhost:61613");        broker.setPersistent(false);        final ManagementContext managementContext = new ManagementContext();        managementContext.setCreateConnector(true);        broker.setManagementContext(managementContext);        return broker;    }}

为我工作。

Error creating bean with name ''webSocketServer''(springboot 整合 webstock)

Error creating bean with name ''webSocketServer''(springboot 整合 webstock)

   今天踩了一个坑记录下,springboot 项目,整合 webstock, 总是报以下错误

org.springframework.beans.factory.BeanCreationException: Error creating bean with name ''webSocketServer'': Lookup method resolution failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class 
...
Caused by: java.lang.IllegalStateException: Failed to introspect Class [com.safesys.monitoring.util.WebSocketServer] from ClassLoader [org.springframework.boot.devtools.restart.classloader.RestartClassLoader@2f6f3352]
...
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:248)
...
Caused by: java.lang.ClassNotFoundException: javax.websocket.Session
...
Disconnected from the target VM, address: ''127.0.0.1:50767'', transport: ''socket''

刚刚开始,各种找错,发现只要添加 ServerEndpointExporter 就报错了

@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}

也找过很多帖子,让你注释启动test类的@RunWith(SpringRunner.class) 或者修改@SpringBootTest为测试环境之类的

反正各种找,准备放弃的时候,我尝试看看 tomcate 自身问题,因为要打 war,之前 pom 做过修改

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--声明spring boot内嵌tomcat的作用范围 在运行时不起作用-->
<scope>provided</scope>
</dependency>
看了注释,我注释了<scope>provided</scope> ,然后刷新包,发现真可以启动了,暂时先记录下,这个还是容器依赖的问题,要让springboot内置tomcate和web生效才行,没时间,就到这把,记录下


 

java – 无法使用内置的BrokerService.stop调用关闭嵌入式activeMQ服务

java – 无法使用内置的BrokerService.stop调用关闭嵌入式activeMQ服务

我一直在使用嵌入式activeMQ服务器配置(配置非常类似于说明嵌入式activeMQ服务器/监听器概念的示例).
作为应用程序的一部分,我有一个监视目录的监视线程.我没有必要终止关闭activeMQ服务器的进程,而是引入了对“STOP”文件的检查,如果文件存在,服务器将关闭.
我试图通过调用代理上的stop函数来完成关闭.

(broker.stop())这似乎关闭了服务.但是,在System.exit上,会引发异常错误:

我观察到另一个提到类似行为的帖子的响应表明“这是正常的”行为.另一篇文章指出我应该禁用shutdownhook(通过设置useShutdownHook =“false”来通过代理的Spring配置).这也没有解决问题.

有关此问题的任何帮助表示赞赏.

谢谢

这是异常堆栈跟踪:

17:10:20.056 [Thread-9] DEBUG org.apache.activemq.AdvisoryConsumer - Failed to send remove command: javax.jms.JMSException: Peer (vm://localhost#3) disposed.
javax.jms.JMSException: Peer (vm://localhost#3) disposed.
    at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:62) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.doAsyncSendPacket(ActiveMQConnection.java:1267) [activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.asyncSendPacket(ActiveMQConnection.java:1259) [activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.AdvisoryConsumer.dispose(AdvisoryConsumer.java:56) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.close(ActiveMQConnection.java:615) [activemq-core-5.5.1.jar:5.5.1]
    at org.springframework.jms.connection.SingleConnectionFactory.closeConnection(SingleConnectionFactory.java:426) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.jms.connection.SingleConnectionFactory.resetConnection(SingleConnectionFactory.java:321) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.jms.connection.SingleConnectionFactory.destroy(SingleConnectionFactory.java:312) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.disposableBeanAdapter.destroy(disposableBeanAdapter.java:211) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:498) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:474) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:442) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1066) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1040) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:958) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
Caused by: org.apache.activemq.transport.TransportdisposedioException: Peer (vm://localhost#3) disposed.
    at org.apache.activemq.transport.vm.VMTransport.oneway(VMTransport.java:89) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:40) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.transport.ResponseCorrelator.oneway(ResponseCorrelator.java:60) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.doAsyncSendPacket(ActiveMQConnection.java:1265) [activemq-core-5.5.1.jar:5.5.1]
    ... 13 common frames omitted
17:10:20.069 [Thread-9] DEBUG o.s.j.c.SingleConnectionFactory - Could not close shared JMS Connection
javax.jms.JMSException: Peer (vm://localhost#3) disposed.
    at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:62) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.doSyncSendPacket(ActiveMQConnection.java:1342) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.close(ActiveMQConnection.java:660) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.springframework.jms.connection.SingleConnectionFactory.closeConnection(SingleConnectionFactory.java:426) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.jms.connection.SingleConnectionFactory.resetConnection(SingleConnectionFactory.java:321) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.jms.connection.SingleConnectionFactory.destroy(SingleConnectionFactory.java:312) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.disposableBeanAdapter.destroy(disposableBeanAdapter.java:211) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:498) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:474) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:442) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1066) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1040) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:958) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
Caused by: org.apache.activemq.transport.TransportdisposedioException: Peer (vm://localhost#3) disposed.
    at org.apache.activemq.transport.vm.VMTransport.oneway(VMTransport.java:89) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:40) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.transport.ResponseCorrelator.asyncRequest(ResponseCorrelator.java:81) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.transport.ResponseCorrelator.request(ResponseCorrelator.java:91) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.doSyncSendPacket(ActiveMQConnection.java:1329) ~[activemq-core-5.5.1.jar:5.5.1]
    ... 11 common frames omitted
17:10:20.069 [Thread-9] DEBUG o.s.b.f.s.disposableBeanAdapter - Invoking destroy() on bean with name 'jmsProducerConnectionFactory'
17:10:20.069 [Thread-9] DEBUG o.s.j.c.SingleConnectionFactory - Closing shared JMS Connection: ActiveMQConnection {id=ID:u0102180-MacA.local-57101-1331074458547-2:1,clientId=ID:u0102180-MacA.local-57101-1331074458547-3:1,started=false}
17:10:20.070 [Thread-9] DEBUG org.apache.activemq.AdvisoryConsumer - Failed to send remove command: javax.jms.JMSException: Peer (vm://localhost#1) disposed.
javax.jms.JMSException: Peer (vm://localhost#1) disposed.
    at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:62) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.doAsyncSendPacket(ActiveMQConnection.java:1267) [activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.asyncSendPacket(ActiveMQConnection.java:1259) [activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.AdvisoryConsumer.dispose(AdvisoryConsumer.java:56) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.close(ActiveMQConnection.java:615) [activemq-core-5.5.1.jar:5.5.1]
    at org.springframework.jms.connection.SingleConnectionFactory.closeConnection(SingleConnectionFactory.java:426) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.jms.connection.SingleConnectionFactory.resetConnection(SingleConnectionFactory.java:321) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.jms.connection.SingleConnectionFactory.destroy(SingleConnectionFactory.java:312) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.disposableBeanAdapter.destroy(disposableBeanAdapter.java:211) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:498) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:474) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:442) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1066) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1040) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:958) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
Caused by: org.apache.activemq.transport.TransportdisposedioException: Peer (vm://localhost#1) disposed.
    at org.apache.activemq.transport.vm.VMTransport.oneway(VMTransport.java:89) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:40) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.transport.ResponseCorrelator.oneway(ResponseCorrelator.java:60) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.doAsyncSendPacket(ActiveMQConnection.java:1265) [activemq-core-5.5.1.jar:5.5.1]
    ... 13 common frames omitted
17:10:20.071 [Thread-9] DEBUG o.s.j.c.SingleConnectionFactory - Could not close shared JMS Connection
javax.jms.JMSException: Peer (vm://localhost#1) disposed.
    at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:62) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.doSyncSendPacket(ActiveMQConnection.java:1342) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.close(ActiveMQConnection.java:660) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.springframework.jms.connection.SingleConnectionFactory.closeConnection(SingleConnectionFactory.java:426) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.jms.connection.SingleConnectionFactory.resetConnection(SingleConnectionFactory.java:321) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.jms.connection.SingleConnectionFactory.destroy(SingleConnectionFactory.java:312) [spring-jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.disposableBeanAdapter.destroy(disposableBeanAdapter.java:211) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:498) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:474) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:442) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1066) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1040) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:958) [spring-context-3.1.0.RELEASE.jar:3.1.0.RELEASE]
Caused by: org.apache.activemq.transport.TransportdisposedioException: Peer (vm://localhost#1) disposed.
    at org.apache.activemq.transport.vm.VMTransport.oneway(VMTransport.java:89) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:40) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.transport.ResponseCorrelator.asyncRequest(ResponseCorrelator.java:81) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.transport.ResponseCorrelator.request(ResponseCorrelator.java:91) ~[activemq-core-5.5.1.jar:5.5.1]
    at org.apache.activemq.ActiveMQConnection.doSyncSendPacket(ActiveMQConnection.java:1329) ~[activemq-core-5.5.1.jar:5.5.1]
    ... 11 common frames omitted

(@TimBish – 感谢您的评论)

最佳答案
ActiveMQ注册自己的shutdown hook并在进程终止时自动停止.因此,在调用stop()之前它已经停止并且出现异常.

如果你通过Spring手动停止它,那么你应该通过设置属性useShutdownHook =“false”来禁用关闭钩子

<broker brokerName="broker" useShutdownHook="false">

Spring 4 AbstractWebSocketMessageBrokerConfigurer与SockJS无法正确协商传输

Spring 4 AbstractWebSocketMessageBrokerConfigurer与SockJS无法正确协商传输

所以我必须说所有的websocket教程/示例看起来都很简单,但是你似乎真的需要挖掘才能找到简单例子中遗漏的非常重要的信息.我的webapp使用前端有SockJS的Spring 4 Stomp消息代理,我有很多问题.

目前,如果我在没有启用SockJS()的情况下向StompEndpointRegistry添加端点,然后使用dojo的dojox / socket在前端声明我的套接字,Firefox 28将打开websocket就好了.但是,我需要在IE8和IE9中支持,所以我切换到了SockJS.使用AbstractAnnotationConfigdispatcherServletinitializer,我花了很多时间来弄清楚如何确保所有过滤器和servlet都设置为使用异步(在Web上非常稀疏的文档).一旦我解决了这个问题,我现在可以在Firefox中使用它,但只能使用xhr_streaming.将sessionCookieNeeded设置为true,IE9默认尝试使用iframe进行连接,但是,它失败:

LOG: opening Web Socket... 
LOG: opening transport: iframe-htmlfile  url:rest/hello/904/ft3apk1g  RTO:1008 
LOG: Closed transport: iframe-htmlfile SimpleEvent(type=close,code=1006,reason=Unable to load an iframe (onload timeout),wasClean=false) 
LOG: opening transport: iframe-xhr-polling  url:rest/hello/904/bf63eisu  RTO:1008 
LOG: Closed transport: iframe-xhr-polling SimpleEvent(type=close,wasClean=false) 
LOG: Whoops! Lost connection to undefined 

如果我将所需的cookie设置为false,IE将使用xdr-streaming并正常工作,它会丢失请求中的jsessionid cookie,反过来我失去了在控制器中获取Principal的能力,这对我来说很重要.我在spring security中启用了相同的origin x frame header,我已经验证了请求中是否存在标题,但它没有帮助.所以我想知道如何A)让Spring和SockJS在Firefox中使用WebSocket传输正确协商,并且B)让IE8和9正确使用iframe传输,这样我就可以保留cookie.

这是我的配置/代码:

网络应用配置:

public class WebAppInitializer extends AbstractAnnotationConfigdispatcherServletinitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws servletexception {
        super.onStartup(servletContext);
        Maparameter("dispatchOptionsRequest","true");
        registration.setAsyncSupported(true);
    }

    @Override
    protected ClassfigClasses() {
        return new Class[]{SecurityConfig.class,Log4jConfig.class,PersistenceConfig.class,ServiceConfig.class};
    }

    @Override
    protected ClassfigClasses() {
        // loading the Initializer class from the dispatcher servlet context ensures it only executes once,// as the ContextRefreshedEvent fires once from the root context and once from the dispatcher servlet context   
        return new Class[]{SpringMvcConfig.class,WebSocketConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{
            "/rest/*","/index.html","/login.html","/admin.html","/index/*","/login/*","/admin/*"
        };
    }

    @Override
    protected Filter[] getServletFilters() {
        OpenEntityManagerInViewFilter openEntityManagerInViewFilter = new OpenEntityManagerInViewFilter();
        openEntityManagerInViewFilter.setBeanName("openEntityManagerInViewFilter");
        openEntityManagerInViewFilter.setPersistenceUnitName("Hsql");

        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding("UTF-8");
        encodingFilter.setForceEncoding(true);

        return new javax.servlet.Filter[]{openEntityManagerInViewFilter,encodingFilter};
    }

}

Spring MVC配置:

@Configuration
@EnableWebMvc
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
@ComponentScan(basePackages = "x.controllers")  // Only scan for controllers.  Other classes are scanned in the parent's root context
public class SpringMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(31556926);
        registry.addResourceHandler("/img/**").addResourceLocations("/img/").setCachePeriod(31556926);
        registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926);
    }

    @Override
    public void configureMessageConverters(ListfigureMessageConverters(converters);
    }

    @Bean
    public InternalResourceViewResolver setupViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    @Bean
    public JacksonAnnotationIntrospector jacksonAnnotationIntrospector() {
        return new JacksonAnnotationIntrospector();
    }

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setAnnotationIntrospector(jacksonAnnotationIntrospector());
        mapper.registerModule(new Jodamodule());
        mapper.registerModule(new Hibernate4Module());
        return mapper;
    }

    @Bean
    public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
        messageConverter.setobjectMapper(objectMapper());
        return messageConverter;
    }

    @Bean(name = "marshaller")
    public Jaxb2Marshaller jaxb2Marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setcontextpath("com.x);
        return marshaller;
    }

    @Bean
    public MarshallingHttpMessageConverter marshallingMessageConverter() {
        return new MarshallingHttpMessageConverter(
                jaxb2Marshaller(),jaxb2Marshaller()
        );
    }
}

Spring root上下文配置:

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {"com.x.services"},// scan for all annotated classes for the root context OTHER than controllers -- those are in the child web context. also don't rescan these config files
        excludeFilters = {
            @ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class),@ComponentScan.Filter(type = FilterType.ANNOTATION,value = Configuration.class)
        }
)
public class ServiceConfig {

    @Bean
    public DefaultAnnotationHandlerMapping defaultAnnotationHandlerMapping() {
        DefaultAnnotationHandlerMapping handlerMapping = new DefaultAnnotationHandlerMapping();
        handlerMapping.setAlwaysUseFullPath(true);
        handlerMapping.setDetectHandlersInAncestorContexts(true);
        return handlerMapping;
    }

    @Bean
    public DefaultConversionService defaultConversionService() {
        return new DefaultConversionService();
    }

    @Bean(name = "kmlContext")
    public JAXBContext kmlContext() throws JAXBException {
        return JAXBContext.newInstance("net.opengis.kml");
    }

    @Bean(name = "ogcContext")
    public JAXBContext ogcContext() throws JAXBException {
        return JAXBContext.newInstance("net.x");
    }
}

春季安全:

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsService;
    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        AuthenticationProvider rememberMeAuthenticationProvider = rememberMeAuthenticationProvider();
        TokenBasedRememberMeServices tokenBasedRememberMeServices = tokenBasedRememberMeServices();

        Listdisable()
                //.headers().disable()
                .headers().addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN))
                .and()
                .authenticationProvider(customAuthenticationProvider)
                .addFilter(new RememberMeAuthenticationFilter(authenticationManager,tokenBasedRememberMeServices))
                .rememberMe().rememberMeServices(tokenBasedRememberMeServices)
                .and()
                .authorizeRequests()
                .antMatchers("/js/**","/css/**","/img/**","/login","/processLogin").permitAll()
                .antMatchers("/index.jsp","/index").hasRole("USER")
                .antMatchers("/admin","/admin.jsp","/js/saic/jswe/admin/**").hasRole("ADMIN")
                .and()
                .formLogin().loginProcessingUrl("/processLogin").loginPage("/login").usernameParameter("username").passwordParameter("password").permitAll()
                .and()
                .exceptionHandling().accessDeniedPage("/login")
                .and()
                .logout().permitAll();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**","/img/**");
    }

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager(Listecurity.authentication.RememberMeAuthenticationProvider("testKey");
    }

    protected void registerauthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
    }
}

WebSocket消息代理配置:

@Configuration
@EnableWebSocketMessagebroker
@EnableScheduling
public class WebSocketConfig extends AbstractWebSocketMessagebrokerConfigurer {

    @Override
    public void configureMessagebroker(MessagebrokerRegistry config) {
        config.enableSimplebroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
            SockJsServiceRegistration registration = registry.addEndpoint("/hello").withSockJS().setClientLibraryUrl("http://localhost:8084/swtc/js/sockjs-0.3.4.min.js");
            registration.setWebSocketEnabled(true);
            //registration.setSessionCookieNeeded(false);

    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.taskExecutor().corePoolSize(4).maxPoolSize(8);
    }

    @Override
    public void configureClientOutboundChannel(ChannelRegistration registration) {
        registration.taskExecutor().corePoolSize(4).maxPoolSize(8);
    }

}

WebSocket控制器:

@Controller
public class WebSocketController {
    @MessageMapping({"/hello","/hello/**"})
    @SendTo("/topic/greetings")
    // in order to get principal,you must set cookiesNeeded in WebSocketConfig,which forces IE to use iframes,which doesn't seem to work
    public AjaxResponseTradiusRequest prr,Principal principal) throws Exception {
        Thread.sleep(3000); // simulated delay
        AjaxResponse

最后,我的html中的javascript用于测试:

disconnect = function() {
                stompClient.disconnect();
                console.log("disconnected");
            };

            window.sendName = function() {
                stompClient.send("/app/hello",{},JSON.stringify({'latitude': 12,'longitude': 123.2,radius: 3.14}));
            };
        

当我在Firefox中连接时,这是我在控制台中看到的:

>>> connect()
connecting
/swtc/ (line 109)
opening Web Socket...
stomp.js (line 130)
undefined
GET http://localhost:8084/swtc/rest/hello/info

200 OK
        202ms   
sockjs....min.js (line 27)
opening transport: websocket url:rest/hello/007/xkc17fkt RTO:912
sockjs....min.js (line 27)
SyntaxError: An invalid or illegal string was specified


...3,reason:"All transports Failed",wasClean:!1,last_event:g})}f.readyState=y.CLOSE...

sockjs....min.js (line 27)
Closed transport: websocket SimpleEvent(type=close,code=2007,reason=Transport timeouted,wasClean=false)
sockjs....min.js (line 27)
opening transport: xhr-streaming url:rest/hello/007/8xz79yip RTO:912
sockjs....min.js (line 27)
POST http://localhost:8084/swtc/rest/hello/007/8xz79yip/xhr_streaming

200 OK
        353ms   
sockjs....min.js (line 27)
Web Socket Opened...

>>> CONNECT
accept-version:1.1,1.0
heart-beat:10000,10000

�

stomp.js (line 130)
POST http://localhost:8084/swtc/rest/hello/007/8xz79yip/xhr_send

204 No Content
        63ms    

<<< CONNECTED
user-name:first.mi.last
heart-beat:0,0
version:1.1

�

stomp.js (line 130)
connected to server undefined
stomp.js (line 130)

Connected: CONNECTED
version:1.1
heart-beat:0,0
user-name:xxx

>>> SUBSCRIBE
id:sub-0
destination:/topic/greetings

�

stomp.js (line 130)
POST http://localhost:8084/swtc/rest/hello/007/8xz79yip/xhr_send

204 No Content
        57ms

/ info响应是:

{"entropy":441118013,"origins":["*:*"],"cookie_needed":true,"websocket":true}

在尝试进行websocket连接时,请注意奇怪的字符串错误.我猜这是我的问题的根源,但我没有做任何有趣的事情,我不知道是什么导致它.

在IE中,这是网络流量. iframe.html文件似乎构建正确,但它无法建立到后端的连接.

URL Method  Result  Type    Received    Taken   Initiator   Wait‎‎  Start‎‎ Request‎‎   Response‎‎  Cache read‎‎    Gap‎‎
/swtc/rest/hello/info?t=1399328502157   GET 200 application/json    411 B   328 ms      0   47  281 0   0   2199
/swtc/rest/hello/iframe.html    GET 200 text/html   0.97 KB 156 ms  frame navigate  328 0   156 0   0   2043
/swtc/js/sockjs-0.3.4.min.js    GET 304 application/javascript  157 B   < 1 ms  

信息响应如下所示:

{"entropy":-475136625,"websocket":true}

如果有人想查看请求或响应标头,请告诉我.

更新1:

罗森,谢谢你的回应.关于Spring 4我所知道的一切我都是从你那里学到的:)

Firefox实际上并没有(完全)工作,我无法获得websocket会话,它降级为xhr-streaming.使用xhr-streaming,没有任何问题,但我希望有一个真正的websocket会话.

使用IE浏览器,我不确定删除标题会确认什么?我认为x帧标题只影响了iframe会话,但根本不起作用.当我禁用require cookie时,IE使用xdr-streaming(并且可以工作,虽然无法获取Principal).一旦我启用了cookie,IE就可以正确地使用iframe来尝试ATTEMPTS.但即使标头到位,所有尝试都会失败:

    http://localhost:8084/swtc/rest/hello/info?t=1399328502157

        Key Value
        Response    HTTP/1.1 200 OK
        Server  Apache-Coyote/1.1
        x-frame-options SAMEORIGIN
        Access-Control-Allow-Origin http://localhost:8084
        Access-Control-Allow-Credentials    true
        Cache-Control   no-store,no-cache,must-revalidate,max-age=0
        Content-Type    application/json;charset=UTF-8
        Content-Length  78
        Date    Mon,05 May 2014 22:21:42 GMT

LOG: opening Web Socket... 
LOG: opening transport: iframe-htmlfile  url:rest/hello/904/ft3apk1g  RTO:1008 
LOG: Closed transport: iframe-htmlfile SimpleEvent(type=close,wasClean=false) 
LOG: Whoops! Lost connection to undefined 

iframe-htmlfile和iframe-xhr-polling都失败了.我确实清除IE中每次刷新的缓存,我确实在SockJS中启用了调试模式.我会在IE中使用xdr-streaming很好,但我真的需要jsessionid cookie.

有什么想法吗?

另外,如果客户端库代码支持相对路径(它实际上构建了具有相对路径的html文件并且应该工作,但仍然在日志中产生错误),那将是非常好的,即:

SockJsServiceRegistration registration = registry.addEndpoint("/hello").withSockJS().setClientLibraryUrl("js/sockjs-0.3.4.min.js");

这将使部署到生产的痛苦减少.

更新2:

快速摘要:没有变化.

这是我尝试在我的安全配置中使用.headers().和()连接IE9:

LOG: opening Web Socket... 
LOG: opening transport: iframe-htmlfile  url:rest/hello/924/1ztfjm7z  RTO:330 
LOG: Closed transport: iframe-htmlfile SimpleEvent(type=close,wasClean=false) 
LOG: opening transport: iframe-xhr-polling  url:rest/hello/924/cgq8_s5j  RTO:330 
LOG: Closed transport: iframe-xhr-polling SimpleEvent(type=close,wasClean=false) 
LOG: Whoops! Lost connection to undefined 

/ info的请求标头:

Key Value
Request GET /swtc/rest/hello/info?t=1399404419358 HTTP/1.1
Accept  */*
Origin  http://localhost:8084
Accept-Language en-US
UA-cpu  AMD64
Accept-Encoding gzip,deflate
User-Agent  Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Host    localhost:8084
Connection  Keep-Alive
Cache-Control   no-cache

和响应标头:

Key Value
Response    HTTP/1.1 200 OK
Server  Apache-Coyote/1.1
X-Content-Type-Options  nosniff
X-XSS-Protection    1; mode=block
Cache-Control   no-cache,no-store,max-age=0,must-revalidate
Pragma  no-cache
Expires 0
x-frame-options DENY
Access-Control-Allow-Origin http://localhost:8084
Access-Control-Allow-Credentials    true
Cache-Control   no-store,max-age=0
Content-Type    application/json;charset=UTF-8
Content-Length  78
Date    Tue,06 May 2014 19:26:59 GMT

Firefox中没有区别.我尝试打开websocket时遇到同样奇怪的字符串错误,然后回到xhr-streaming:

opening transport: websocket url:rest/hello/849/fy_06t1v RTO:342
SyntaxError: An invalid or illegal string was specified
Closed transport: websocket SimpleEvent(type=close,wasClean=false)
opening transport: xhr-streaming url:rest/hello/849/2r0raiz8 RTO:342
http://localhost:8084/swtc/rest/hello/849/2r0raiz8/xhr_streaming
Web Socket Opened...
>>> CONNECT
accept-version:1.1,10000
最佳答案
鉴于它在FF和IE中使用sessionCookieNeeded = false,我猜这个问题与x-frame-options标题有关.

您的配置似乎正确.特别适用于Spring Security:

        .headers().addHeaderWriter(
            new XFrameOptionsHeaderWriter(
                    XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN)).and()

对于SockJS也是如此:

            setClientLibraryUrl("http://localhost:8084/swtc/js/sockjs-0.3.4.min.js");

我建议尝试禁用标题只是为了确认它是否是问题,即:

        .headers().and()

还要确保没有涉及发送相同响应的浏览器缓存问题.因此,请检查x-frame-options值的实际响应标头.

为此,我强烈建议通过SockJS构造函数的options参数启用SockJS客户端调试模式.

Spring 4 WebSocket Remote Broker配置

Spring 4 WebSocket Remote Broker配置

我设法用Spring4和Stomp创建了简单的Websocket应用程序。在这里看到我的最后一个问题,然后我尝试使用远程消息代理(ActiveMQ)。我刚刚开始经纪人,并改变了

registry.enableSimpleBroker("/topic");

registry.enableStompBrokerRelay("/topic");

而且有效。

问题是如何配置代理?我了解在这种情况下,应用程序会自动在localhost:defaultport上找到代理,但是如果我需要将应用程序指向其他计算机上的其他代理,该怎么办?

答案1

小编典典

enableStompBrokerRelay方法返回一个方便的Registration实例,该实例公开了流畅的API。

您可以使用此流利的API配置您的Broker中继:

registry.enableStompBrokerRelay("/topic").setRelayHost("host").setRelayPort("1234");

您还可以配置各种属性,例如代理的登录/通过凭据等。

与XML配置相同:

<websocket:message-broker>  <websocket:stomp-endpoint path="/foo">    <websocket:handshake-handler ref="myHandler"/>    <websocket:sockjs/>  </websocket:stomp-endpoint>  <websocket:stomp-broker-relay prefix="/topic,/queue"       relay-host="relayhost" relay-port="1234"      client-login="clientlogin" client-passcode="clientpass"      system-login="syslogin" system-passcode="syspass"      heartbeat-send-interval="5000" heartbeat-receive-interval="5000"      virtual-host="example.org"/></websocket:message-broker>

有关属性和默认值的更多详细信息,请参见StompBrokerRelayRegistration
javadoc。

关于具有嵌入式ActiveMQ Broker的Spring Boot WebSocket的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于Error creating bean with name ''webSocketServer''(springboot 整合 webstock)、java – 无法使用内置的BrokerService.stop调用关闭嵌入式activeMQ服务、Spring 4 AbstractWebSocketMessageBrokerConfigurer与SockJS无法正确协商传输、Spring 4 WebSocket Remote Broker配置的相关信息,请在本站寻找。

本文标签: