Integration of JSR-356 WebSocket @ServerEndpoint with Spring beans 3

I'm using Spring 3.2.5 without the full support of new web sockets JSR-356.

I would like to have a link singleton- bean on my server @ServerEndpoint the WebSocket, which is generated by the servlet container and not in the context of the Spring.

What is the cleanest way to do this?

My current solution: I did @Service The singleton instance of the bean from a static field:

 @Service public class WebSocketSupportBean { private volatile static WebSocketSupportBean instance = null; public static WebSocketSupportBean getInstance() { return instance; } public WebSocketSupportBean() { instance = this; } 

and just get it in @ServerEndpoint static method by disabling the user if null return (if not bean A jet, created at server startup time, but the user is connected):

+6
source share
4 answers

You can customize websockets using spring framework 3.x

I have developed a small application for proof of concept to demonstrate how based on Rossen Stoyanchev SpringConfiguration released spring -core 4.0.

An application installs the endpoint server websocket with the uri /wstest , which will use @Autowired spring the bean, to select the welcome address and respond to the message webcam.

Runs connection with websocket and messages sent via html-pages ( index.html ), running in a browser that supports web files.

Registration end point is performed using ServletContextListener when the initial context and creating an instance of the end point will be connected by a spring:

 @WebListener public class MyApplication implements ServletContextListener { private final static String SERVER_CONTAINER_ATTRIBUTE = "javax.websocket.server.ServerContainer"; @Override public void contextInitialized(ServletContextEvent sce) { ServletContext container = sce.getServletContext(); final ServerContainer serverContainer = (ServerContainer) container.getAttribute(SERVER_CONTAINER_ATTRIBUTE); try { serverContainer.addEndpoint(new MyEndpointConfig(MyEndpoint.class, "/wstest")); } catch (DeploymentException e) { e.printStackTrace(); } } } (SERVER_CONTAINER_ATTRIBUTE); @WebListener public class MyApplication implements ServletContextListener { private final static String SERVER_CONTAINER_ATTRIBUTE = "javax.websocket.server.ServerContainer"; @Override public void contextInitialized(ServletContextEvent sce) { ServletContext container = sce.getServletContext(); final ServerContainer serverContainer = (ServerContainer) container.getAttribute(SERVER_CONTAINER_ATTRIBUTE); try { serverContainer.addEndpoint(new MyEndpointConfig(MyEndpoint.class, "/wstest")); } catch (DeploymentException e) { e.printStackTrace(); } } } / wstest")); @WebListener public class MyApplication implements ServletContextListener { private final static String SERVER_CONTAINER_ATTRIBUTE = "javax.websocket.server.ServerContainer"; @Override public void contextInitialized(ServletContextEvent sce) { ServletContext container = sce.getServletContext(); final ServerContainer serverContainer = (ServerContainer) container.getAttribute(SERVER_CONTAINER_ATTRIBUTE); try { serverContainer.addEndpoint(new MyEndpointConfig(MyEndpoint.class, "/wstest")); } catch (DeploymentException e) { e.printStackTrace(); } } } 

And the final point:

 @Component public class MyEndpoint extends Endpoint { @Autowired MyService myService; @Override public void onOpen(Session session, EndpointConfig config) { session.addMessageHandler(new MyMessageHandler(session)); } class MyMessageHandler implements MessageHandler.Whole<String> { final Session session; public MyMessageHandler(Session session) { this.session = session; } @Override public void onMessage(String message) { try { String greeting = myService.getGreeting(); session.getBasicRemote().sendText(greeting + ", got your message (" + message + "). Thanks ! (session: " + session.getId() + ")"); } catch (IOException e) { e.printStackTrace(); } } } } config) { @Component public class MyEndpoint extends Endpoint { @Autowired MyService myService; @Override public void onOpen(Session session, EndpointConfig config) { session.addMessageHandler(new MyMessageHandler(session)); } class MyMessageHandler implements MessageHandler.Whole<String> { final Session session; public MyMessageHandler(Session session) { this.session = session; } @Override public void onMessage(String message) { try { String greeting = myService.getGreeting(); session.getBasicRemote().sendText(greeting + ", got your message (" + message + "). Thanks ! (session: " + session.getId() + ")"); } catch (IOException e) { e.printStackTrace(); } } } } ; @Component public class MyEndpoint extends Endpoint { @Autowired MyService myService; @Override public void onOpen(Session session, EndpointConfig config) { session.addMessageHandler(new MyMessageHandler(session)); } class MyMessageHandler implements MessageHandler.Whole<String> { final Session session; public MyMessageHandler(Session session) { this.session = session; } @Override public void onMessage(String message) { try { String greeting = myService.getGreeting(); session.getBasicRemote().sendText(greeting + ", got your message (" + message + "). Thanks ! (session: " + session.getId() + ")"); } catch (IOException e) { e.printStackTrace(); } } } } ", got your message (" + message + ") Thanks (session:.!" + session.getId () + ")"); @Component public class MyEndpoint extends Endpoint { @Autowired MyService myService; @Override public void onOpen(Session session, EndpointConfig config) { session.addMessageHandler(new MyMessageHandler(session)); } class MyMessageHandler implements MessageHandler.Whole<String> { final Session session; public MyMessageHandler(Session session) { this.session = session; } @Override public void onMessage(String message) { try { String greeting = myService.getGreeting(); session.getBasicRemote().sendText(greeting + ", got your message (" + message + "). Thanks ! (session: " + session.getId() + ")"); } catch (IOException e) { e.printStackTrace(); } } } } 

Look at the full source code and is ready to run on my page Github .

+6
source

Try

 @ServerEndpoint(value = "/ws", configurator = SpringConfigurator.class) 

And add a dependency maven

 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> </dependency> artifactId> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> </dependency> 
+1
source

You can make an object @ServerEndpoint advanced SpringBeanAutowiringSupport. Then just tell the beans, which is created within the framework on Spring-based web application as follows:

  @PostConstruct public void init() { SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); } 

Thus, @ Custom annotation is correct:

 @Autowired MyService myService; 
0
source

Try it, it works for me

 @Component @ServerEndpoint(value = "/instantMessageServer",configurator = SpringConfigurator.class) public class InstantMessageServer{ private static IChatService chatService; @Autowired public InstantMessageServer(IChatService chatService){ this.chatService = chatService; } public InstantMessageServer(){} } , configurator = SpringConfigurator.class) @Component @ServerEndpoint(value = "/instantMessageServer",configurator = SpringConfigurator.class) public class InstantMessageServer{ private static IChatService chatService; @Autowired public InstantMessageServer(IChatService chatService){ this.chatService = chatService; } public InstantMessageServer(){} } 

I found this solution https://spring.io/blog/2013/05/23/spring-framework-4-0-m1-websocket-support but there is another failure, class annotated using @ServerEndpoint, can not get httpsession with SpringConfigurator, there is no overriding changehandler method. Perhaps, we create a separate configurator, extending SpringConfigurator and override this method that will work. I think it is better to create a Web application in real time with the help of spring -websocket api and posts.


 public class ModifiedServerEndpointConfigurator extends SpringConfigurator{ @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { HttpSession httpSession = (HttpSession) request.getHttpSession(); sec.getUserProperties().put(HttpSession.class.getName(),httpSession); super.modifyHandshake(sec, request, response); } } request, HandshakeResponse response) { public class ModifiedServerEndpointConfigurator extends SpringConfigurator{ @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { HttpSession httpSession = (HttpSession) request.getHttpSession(); sec.getUserProperties().put(HttpSession.class.getName(),httpSession); super.modifyHandshake(sec, request, response); } } ); public class ModifiedServerEndpointConfigurator extends SpringConfigurator{ @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { HttpSession httpSession = (HttpSession) request.getHttpSession(); sec.getUserProperties().put(HttpSession.class.getName(),httpSession); super.modifyHandshake(sec, request, response); } } ), httpSession); public class ModifiedServerEndpointConfigurator extends SpringConfigurator{ @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { HttpSession httpSession = (HttpSession) request.getHttpSession(); sec.getUserProperties().put(HttpSession.class.getName(),httpSession); super.modifyHandshake(sec, request, response); } } ; public class ModifiedServerEndpointConfigurator extends SpringConfigurator{ @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { HttpSession httpSession = (HttpSession) request.getHttpSession(); sec.getUserProperties().put(HttpSession.class.getName(),httpSession); super.modifyHandshake(sec, request, response); } } 
0
source

All Articles