将JSR-356 WebSocket @ServerEndpoint与Spring 3 bean集成

Pio*_*ler 8 java spring websocket spring-3 jsr356

我使用Spring 3.2.5而没有全新的JSR-356 WebSockets支持.

我想在我的@ServerEndpointWebSocket服务器中使用singleton-bean引用,它由servlet容器本身实例化,而不是在Spring上下文中实例化.

干净的方法是什么?

我目前的解决方案:我@Service在静态字段中使用实例制作了单例bean:

@Service
public class WebSocketSupportBean {
    private volatile static WebSocketSupportBean instance = null;

    public static WebSocketSupportBean getInstance() {
        return instance;
    }

    public WebSocketSupportBean() {
        instance = this;
    }
Run Code Online (Sandbox Code Playgroud)

并且只是@ServerEndpoint通过静态方法获取它,如果null返回则断开用户连接(如果在服务器启动期间bean没有创建但用户连接时):

Mar*_*ins 7

您可以使用spring framework 3.x设置websockets

我开发了一个小概念验证应用程序来演示如何基于Rossen Stoyanchev的SpringConfiguration与spring-core 4.0一起发布.

应用程序使用uri设置websocket服务器端点,/wstest该端点将使用@Autowiredspring bean来选择问候语并回复websocket消息.

websocket连接被启动,并且由index.html支持websockets的浏览器中运行的html page()发送消息.

端点初始化时由ServletContextListener进行端点注册,当端点被实例化时,它将与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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

而端点是:

@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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的Github页面上查看完整的源代码并准备运行示例.