从 Spring websocket 会话中提取远程端点对象 [英] Extracting Remote endpoint Object from Spring websocket session
问题描述
在 javax websockets 中,我们可以使用如下代码
In javax websockets we can use something like the follows
Session.getAsyncRemote().sendText(String text)Session.getBasicRemote().sendText();
Session.getAsyncRemote().sendText(String text) Session.getBasicRemote().sendText();
我们如何使用 spring websocket 发送异步消息.我们可以从 spring webscockets 的 WebSocketSession 中提取 RemoteEndPoint 并发送异步消息
How can we send an asynchronous messages using spring websocket. From WebSocketSession of spring webscockets can we extract RemoteEndPoint and send an async messages
PS 注意:我使用的是基本的 Spring websockets...
PS Note: I am using Basic Spring websockets...
配置和代码如下:
@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy
@EnableWebSocket
public class WebMVCConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
private static final String ENDPOINT_URL = "/echo";
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(socketHandler(), ENDPOINT_URL).setAllowedOrigins("*");
}
@Bean
public WebSocketHandler socketHandler() {
return new WebSocketTestHandler();
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Bean
public DefaultHandshakeHandler handshakeHandler() {
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
policy.setInputBufferSize(8192);
policy.setIdleTimeout(600000);
return new DefaultHandshakeHandler(new JettyRequestUpgradeStrategy(new WebSocketServerFactory(policy)));
}
public class SpringMVCInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { ApplicationConfig.class, RabbitMQConfig.class, RabbitConnectionFactory.class,
WebPropertyPlaceHolderConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
}
@Configuration
public class WebSocketTestHandler extends TextWebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
log.info("Connection is established to Server....:: Session Open : {}", session.isOpen());
}
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) {
}
@Override
public void afterConnectionClosed(WebSocketSession curSession, CloseStatus status) throws Exception {
}
}
所以在handleTextMessage(WebSocketSession session,TextMessage message)里面{在此方法内部创建多个线程并发送相同的会话对象和其他一些参数..在每个线程内部没有修改任何与会话对象相关的参数,而是尝试执行
So inside handleTextMessage(WebSocketSession session,TextMessage message) { Inside this method am creating multiple threads And sending same session Object and some other parameters..Inside each thread am not modifying any session object related parameters but am trying to execute
TextMessage socketMessage = new TextMessage(message);
session.sendMessage(socketMessage);
}
所以每个线程都试图使用相同的会话对象发送消息..但是我面临以下错误
So each thread is trying to send messages using same session Object..But am facing the following error
java.lang.IllegalStateException: Blocking message pending 10000 for BLOCKING
at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.lockMsg(WebSocketRemoteEndpoint.java:130) ~[websocket-common-9.3.8.v20160314.jar:9.3.8.v20160314]
at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.sendString(WebSocketRemoteEndpoint.java:379) ~[websocket-common-9.3.8.v20160314.jar:9.3.8.v20160314]
at org.springframework.web.socket.adapter.jetty.JettyWebSocketSession.sendTextMessage(JettyWebSocketSession.java:188) ~[spring-websocket-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage(AbstractWebSocketSession.java:105) ~[spring-websocket-4.2.4.RELEASE.jar:4.2.4.RELEASE]
那么可以使用spring websockets发送异步消息吗?如果是,请告诉我上面代码中需要哪些配置更改..或者我们可以从spring Websocket Session中提取核心AsyncRemoteEndPoint和BasicRemoteEndpoint,我们可以发送异步消息..或者如果不是上述两种情况..移动代码到公共场所并放置同步(sessionObject){发信息}...很抱歉,如果问题的框架不清楚或已经是重复的问题
So is it possible to send asynchronous messages using spring websockets? If yes please let me know what configuration changes are required in the above code..Or Can we extract the core AsyncRemoteEndPoint and BasicRemoteEndpoint from spring Websocket Session and can we send asynchronous messages..or if not both the above cases ..move the code to common place and put synchonized(sessionObject) { sendmessage }..Sorry if the framing of question is not clear or already a duplicate question
请注意,我没有使用任何 Stomp 客户端或 spring websocket 上的任何其他功能..我使用的是普通的 spring websockets..是否可以不使用 Future(java 功能)(如果是..会更好)?
Please note I am not using any Stomp client or anyother features over spring websocket..Am using plain spring websockets..And is it possible to do without using Future(java feature)(If yes..it would be better)?
推荐答案
我在会话中使用了 ConcurrentWebSocketSessionDecorator.根据:https://jira.spring.io/browse/SPR-13602
I used ConcurrentWebSocketSessionDecorator on the session. according to: https://jira.spring.io/browse/SPR-13602
装饰器强制使用发送缓冲区一次发送一条消息并限制每个会话的发送时间.这有助于限制慢速客户端的影响"
The decorator "enforces sending messages one at a time with a send buffer and send time limit per session. That helps quite a bit to limit the impact of slow clients"
这篇关于从 Spring websocket 会话中提取远程端点对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!