SpringWeb编程方式分为Servlet模式和响应式。Servlet模式参考官方文档:Web on Servlet Stack :: Spring Framework,响应式(Reacive)参考官方文档:Web on Reactive Stack :: Spring Framework。
WebSocket也有两种编程方式的分别实现。在Java服务器web开发中,Servlet模式更为常见,这里暂且只探索Servlet模式。对应参考官方文档为WebSockets :: Spring Framework
在官方文档中,给出了实现WebSocket的三个方案:
- WebSocket API。SpringMVC封装JSR 356 WebSocket API。
- SocketJS Fallback。服务器环境不支持WebSocket的降级方案。
- STOMP。功能更强大的在WebSocket基础上实现的Simple Text Oriented Messaging Prototcal子协议。
本章从最简单的WebSocketAPI入手进行简单的编码演示。
什么时候使用WebSocket
在实现WebSocket应用程序前,借助官方文档讨论一下使用WebSocket的时机。
WebSocket提供了web页面动态和交互的能力。但大多情况,使用AJAX和HTTP流或长训练的结合可能是更简单和高效的方案。
像新闻、邮件和社交媒体每几分钟动态更新一次也是可以的。另一个方面,协同、游戏和财务应用就需要更近实时。
除了延迟这个决定性因素。如果数据量比较低,HTTP流或者长轮询可能是更高效的解决方案。如果需要低延迟、高频率和大量数据,更使用使用WebSocket。
互联网,受限的中间代理也可能影响WebSocket的交互效果。运行环境可能不支持从HTTP升级为WebSocket,或者关闭了长连接。这意味着在WebSocket更适合在内网运行。
WebSocket实现
- 定义业务控制器类。
业务控制器类需要实现WebSocketHandler
接口。对于文本消息,继承TextWebSocketHandler
更简单些。
public class ServletGreetingWebSocketHandler extends TextWebSocketHandler {
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
System.out.println("ServletGreetingWebSocketHandler<=" + message.getPayload());
session.sendMessage(new TextMessage("ServletGreetingWebSocketHandler=>hello," + message.getPayload()));
}
}
2.部署业务控制器类
借助SpringBoot的自动配置,把业务控制器类注入到容器中,并让Spring把业务控制器类添加到WebSocket容器中。
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(servletGreetingWebSocketHandler(), "/app/hello__").setAllowedOrigins("*");
}
@Bean
public ServletGreetingWebSocketHandler servletGreetingWebSocketHandler() {
return new ServletGreetingWebSocketHandler();
}
}
- 客户端代码
上面代码在向WebSocketHandlerRegistry
中添加业务控制器类ServletGreetingWebSocketHandler
实例时,已通过setAllowedOrigins
方法配置为允许跨域。就可以在浏览器控制台直接执行js客户端代码:
ws = new WebSocket("http://localhost:8090/app/hello__")
ws.onmessage=console.log
ws.send("aodi")