我有一个使用stomp的简单Web套接字应用程序.当用户访问页面时,它将自动与服务器建立一个stomp连接.用户通过弹簧安全性进行身份验证.当用户关闭浏览器时,我希望用户自动注销.为此,我创建了一个监听器来监听SessionDisconnectEvent.问题是我没有与websocket会话相关的httpSession句柄?有没有想从websocket会话中获取httpsession?
这是我的代码:
<websocket:message-broker application-destination-prefix="/test">
<websocket:stomp-endpoint path="/sbapp">
<websocket:handshake-interceptors>
<bean class="com.sample.HttpSessionIdHandshakeInterceptor"></bean>
</websocket:handshake-interceptors>
<websocket:sockjs />
</websocket:stomp-endpoint>
<websocket:stomp-broker-relay prefix="/topic,/queue,/user" relay-host="localhost" relay-port="61613"/>
</websocket:message-broker>
Run Code Online (Sandbox Code Playgroud)
这是我的websocket会话监听器:
@Component
public class StompDisconnectListener implements ApplicationListener<SessionDisconnectEvent>{
@Override
public void onApplicationEvent(SessionDisconnectEvent event) {
System.out.println("Stomp disconnect: " + event.getSessionId());
}
}
Run Code Online (Sandbox Code Playgroud)
我需要一种方法,当我得到一个断开事件时,我得到相应的HttpSession然后手动注销HttpSession.这可能吗?
我正在检修播放应用程序的websocket功能,并希望有一个像STOMP这样的应用程序层协议.我已经走上了将spring-websocket引入混合的道路,但是在将传入请求路由到我的消息处理程序时遇到了麻烦.
该文件的第21.2.1节表明:
以上内容适用于Spring MVC应用程序,应包含在DispatcherServlet的配置中.但是,Spring的WebSocket支持不依赖于Spring MVC.在WebSocketHttpRequestHandler的帮助下,将WebSocketHandler集成到其他HTTP服务环境中相对简单.
我一直在寻找以这种方式利用WebSocketHttpRequestHandler的应用程序的一些示例,并且还没有找到它.
如果有人能指出我正确的方向,那将是非常棒的!
谢谢,杰里米
为了对此进行更新,经过两周的尝试让我们为我们解决这个问题,我们全力以赴.我们问题的核心似乎是无法映射任何春天可以识别的游戏请求对象.因此,我们无法通过协商获得握手.
我们没有尝试过的一些事情可能会发生一些事情:1)将游戏部署为.war,以便有一个可以获得的服务器请求.2)或许你可以让游戏协商握手,一旦你有一个套接字连接,你可以将它传递给春天......
但最终我们努力尝试完成这项工作并决定我们将在春季完全重新实施我们的应用程序.
与工作Spring Boot 1.2.1.RELEASE和Spring Websockets.有一个部署运行时问题,当运行嵌入式时Jetty 9,我不能java.security.Principal成功地伪装用户()当app部署在除localhost之外的任何其他地方.
我咨过过
下面的配置(我相信)已经"升级"了一个请求
@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// see http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-handle-broker-relay
// requires an external broker like AMQP or RabbitMQ
//registry.enableStompBrokerRelay("/queue/", "/topic/");
// XXX This might wind up being the impl we actually deploy; but be aware it has certain constraints
// see http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-message-flow
registry.enableSimpleBroker("/queue/", "/topic/");
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/cards").setHandshakeHandler(new UserHandler()).withSockJS(); …Run Code Online (Sandbox Code Playgroud) 我正在使用Spring Boot 1.3.0.RELEASE.我的代码基于使用Stomp和SocketJS的Spring Boot中的websocket启动指南.
当我从localhost运行客户端时:8080(Spring Server)......当然可行.直到我尝试从不同的端口调用它,我得到403禁止.我的CorsFilter设置如下.
我设置我的CorsFilter来访问我的客户端...
package hello;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CorsFilter implements Filter {
private final Logger log = LoggerFactory.getLogger(CorsFilter.class);
public CorsFilter() {
log.info("SimpleCORSFilter init");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String clientOrigin = request.getHeader("origin");
response.addHeader("Access-Control-Allow-Origin", …Run Code Online (Sandbox Code Playgroud) 我正在客户端用StompJS编写一个spring websocket应用程序.
在客户端,我打算发送一个对象列表,并在服务器端映射到java对象时,它将自身转换为LinkedHashMap
我的客户端代码是
function stomball() {
stompClient.send("/brkr/call", {}, JSON.stringify(listIds));
}
Run Code Online (Sandbox Code Playgroud)
Listids看起来像
[{
"path": "/a/b/c.txt",
"id": 12
}, {
"path": "/a/b/c/d.txt",
"id": 13
}]
Run Code Online (Sandbox Code Playgroud)
List Id对象看起来像
public class ListId {
private String path;
private Long id;
//getters and setters...
}
Run Code Online (Sandbox Code Playgroud)
控制器看起来像这样
@MessageMapping("/call" )
@SendTo("/topic/showResult")
public RetObj process(List<ListId> listIds) {
if (!listIds.isEmpty()) {
for(ListId listId: listIds) {
}
}
Run Code Online (Sandbox Code Playgroud)
所以我得到一个java.lang.ClassCastException:java.util.LinkedHashMap无法强制转换为com.blah.ListId
然而,当我使用RestMapping使用普通的Spring控制器时,它工作正常,是否有任何弹簧MessageMapping注释将对象映射到java的方式与传统方式不同我不知道为什么不转换为ListID
我正在使用spring-websocket和spring-messaging(版本4.2.2.RELEASE)通过功能齐全的代理(Apache ActiveMQ 5.10.0)在websockets上实现STOMP.
我的客户只想订阅目的地 - 也就是说他们不应该发送消息.此外,我想对客户可以订阅的目的地实施更严格的控制.在任何一种情况下(即客户端尝试发送消息或订阅无效目的地)我希望能够
请注意,我的所有目的地都转发给ActiveMQ.我认为我可以在入站通道上实现ChannelInterceptor,但是看看API我无法弄清楚如何实现我想要的.这是可能的,验证客户端请求的最佳方法是什么?我的websocket配置如下:
<websocket:message-broker
application-destination-prefix="/app">
<websocket:stomp-endpoint path="/pushchannel"/>
<websocket:stomp-broker-relay relay-host="localhost"
relay-port="61613" prefix="/topic"
heartbeat-receive-interval="300000" heartbeat-send-interval="300000" />
<websocket:client-inbound-channel>
<websocket:interceptors>
<bean class="MyClientMessageInterceptor"/>
</websocket:interceptors>
</websocket:client-inbound-channel>
</websocket:message-broker>
Run Code Online (Sandbox Code Playgroud) 我们目前有一个直接的Websocket连接,从我们的UI应用程序转到后端Web服务.现在,当我们尝试通过Zuul(ApiGateway)做同样的事情时,我们无法连接到后端服务我们已经解决了以下无法解决问题的问题https://github.com/spring-cloud/spring-cloud -netflix /问题/ 163
但它给了我一个替代下面链接 https://jmnarloch.wordpress.com/2015/11/11/spring-cloud-sock-js-stomp-zuul-no-websockets/ 我正在考虑它作为最后的解决方案.
我的另一个问题是,如果我们想使用websocket协议和zuul我们需要在zuul中执行哪些更改,因为我是websocket的新手,因为我们知道spring支持websocket和Zuul是一个基于spring的服务(如果我错了,请更正)
spring spring-boot spring-websocket spring-cloud netflix-zuul
===更新===(见下面的原帖)
虽然由zyro发起的错误修复带来了一些改进,但是错误仍然没有完全消失.它仍然看起来像这样:
31-Jan-2018 19:30:53.529 INFO [MessageBroker-3] org.apache.coyote.AbstractProcessor.setErrorState An error occurred in processing while o
n a non-container thread. The connection will be closed immediately
java.io.IOException: APR error: -32
at org.apache.coyote.http11.InternalAprOutputBuffer.writeToSocket(InternalAprOutputBuffer.java:291)
at org.apache.coyote.http11.InternalAprOutputBuffer.writeToSocket(InternalAprOutputBuffer.java:244)
at org.apache.coyote.http11.InternalAprOutputBuffer.flushBuffer(InternalAprOutputBuffer.java:213)
at org.apache.coyote.http11.AbstractOutputBuffer.flush(AbstractOutputBuffer.java:305)
at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:765)
at org.apache.coyote.Response.action(Response.java:177)
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:349)
at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:317)
at org.apache.catalina.connector.Response.flushBuffer(Response.java:510)
at org.apache.catalina.connector.ResponseFacade.flushBuffer(ResponseFacade.java:318)
at javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapper.java:176)
at org.springframework.boot.web.support.ErrorPageFilter$ErrorWrapperResponse.flushBuffer(ErrorPageFilter.java:318)
at javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapper.java:176)
at javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapper.java:176)
at javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapper.java:176)
at org.springframework.security.web.util.OnCommittedResponseWrapper.flushBuffer(OnCommittedResponseWrapper.java:159)
at org.springframework.http.server.ServletServerHttpResponse.flush(ServletServerHttpResponse.java:96)
at org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession.writeFrameInternal(AbstractHttpSockJsSession
.java:350)
at org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.writeFrame(AbstractSockJsSession.java:318)
at org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.sendHeartbeat(AbstractSockJsSession.java:251)
at org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession$HeartbeatTask.run(AbstractSockJsSession.java:455
)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) …Run Code Online (Sandbox Code Playgroud) 我有一个Spring Boot应用程序,它通过二进制websocket交换消息。即没有STOMP,AMQP等或任何其他消息传递协议!!!现在,我需要用“ websocket”的范围标记我的一个班级。像下面这样:
@Service("session")
@Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Session {
...
}
Run Code Online (Sandbox Code Playgroud)
我在这里阅读了 引用该文档的文档:
“可以将WebSocket范围的bean注入到控制器以及在“ clientInboundChannel”上注册的任何通道拦截器中。
我想在那句话中强调“和”一词。
好吧,我确实有一个控制器,但是我没有任何channelInterceptor。我将其注入为:
@Controller("entryPoint")
public class EntryPoint {
@Autowired
private ApplicationContext applicationContext;
private ApplicationEventPublisher applicationEventPublisher;
@Autowired
private Session session;
...
@PostConstruct
public void init() {
// Invoked after dependencies injected
logger.info("EntryPoint init method i.e. @PostConstruct invoked");
}
...
}
Run Code Online (Sandbox Code Playgroud)
现在,我发现很有趣的第一个想法是,我需要注释@EnableWebSocketMessageBroker,即@EnableWebSocket似乎还不够,但是接着问为什么。无论我是否使用消息传递协议,我都应该能够独立定义该范围。至少那是我所相信的。
反正没有它我得到错误
java.lang.IllegalStateException: No Scope registered for scope name 'websocket'
Run Code Online (Sandbox Code Playgroud)
我说好,让我们为消息代理创建一个虚拟的配置文件,它带来了更多的依赖性,例如:
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-net</artifactId> …Run Code Online (Sandbox Code Playgroud) 我正在使用Spring boot的WebSocketConfigurer来创建websocket,按照以下代码创建一个在线系统.我的用户将连接到它,它将继续跟踪他们的存在.
@Configuration
@EnableWebSocket
public class WebSocketServerConfiguration implements WebSocketConfigurer {
private final PresenceListener presenceListener;
Logger logger = Logger.getLogger(WebSocketServerConfiguration.class.getName());
@Autowired
public WebSocketServerConfiguration(StringRedisTemplate stringRedisTemplate){
this.presenceListener = new PresenceListener(stringRedisTemplate);
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new WebSocketHandler() {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
logger.info("afterConnectionEstablished:"+session.toString());
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
//Some code inside
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
logger.info("handleTransportError:" +session.toString());
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) …Run Code Online (Sandbox Code Playgroud) spring-websocket ×10
java ×4
spring ×4
spring-boot ×4
stomp ×3
websocket ×3
cors ×1
grails ×1
grails3 ×1
netflix-zuul ×1
session ×1
spring-cloud ×1
spring-mvc ×1
stompjs ×1
tomcat8 ×1