问题
In javax websockets we can use something like the follows
Session.getAsyncRemote().sendText(String text) Session.getBasicRemote().sendText();
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 Note: I am using Basic Spring websockets...
The configuration and code is as follows:
@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 {
}
}
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]
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
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)?
回答1:
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"
来源:https://stackoverflow.com/questions/36318483/extracting-remote-endpoint-object-from-spring-websocket-session