前言
早期,很多网站为了实现推送技术,所用的技术都是轮询。轮询是指由浏览器每隔一段时间(如每秒)向服务器发出HTTP请求,然后服务器返回最新的数据给客户端。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求与回复可能会包含较长的头部,其中真正有效的数据可能只是很小的一部分,所以这样会消耗很多带宽资源。比较新的轮询技术是Comet。这种技术虽然可以实现双向通信,但仍然需要反复发出请求。而且在Comet中普遍采用的HTTP长连接也会消耗服务器资源。在这种情况下,HTML5定义了WebSocket协议,在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输,这样能更好的节省服务器资源和带宽,并且能够更实时地进行通讯(以上内容来自维基百科)。
Websocket使用ws或wss的统一资源标志符(URI)。其中wss表示使用了TLS的Websocket。如:
ws://example.com/wsapi wss://secure.example.com/wsapi复制代码
下面就通过一个简单的例子介绍如何在SpringBoot中集成WebSocket,只展示WebSocket的核心配置,完整代码已上传到GitHub:
效果展示
在展示代码配置前,先展示一下效果(已提前登录了三个用户):
具体的代码配置
引入依赖
首先需要在pom.xml中引入以下依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>复制代码
配置ServerEndpointExporter的Bean
@Configurationpublic class WebSocketConfig { @Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter(); } }复制代码
配置服务器终端
@Component@ServerEndpoint("/websocket")public class WebSocketServer { private Session session;// 保存所有的客户端连接private static final Map<String, WebSocketServer> connections = new LinkedHashMap<>(); @OnOpenpublic void onOpen(Session session) {this.session = session; connections.put(session.getId(), this); } @OnMessagepublic void onMessage(String message, Session session) {try { sendMessage(message); } catch (Exception e) { e.printStackTrace(); } } @OnErrorpublic void onError(Throwable error, Session session) throws Throwable {throw error; } @OnClosepublic void onClose() { connections.remove(session.getId()); } public void sendMessage(String message) throws IOException { session.getBasicRemote().sendText(message); } // 广播方法(实现消息群发)public static void broadcast(String message) { connections.forEach((k, v) -> {try { v.sendMessage(message); } catch (Exception e) { e.printStackTrace(); } }); } }复制代码
配置群发通知接口
@RestControllerpublic class BroadcastController { @PostMapping("/broadcast")public void broadcast(@RequestBody String msg){ WebSocketServer.broadcast(msg); } }复制代码
客户端配置
客户端简单使用Vue框架,没有使用单文件组件形式,客户端连接代码如下:
let socket = new WebSocket("ws://localhost:8080/websocket") socket.onerror = err => {console.log(err) } socket.onopen = event => {console.log(event) } socket.onmessage = event => {// 这里接受服务端发送的信息vue.$data.toast = {isShow: true,msg: JSON.parse(event.data).msg } } socket.onclose = () => {console.log("连接关闭") }复制代码
完成以上简单配置后,只要调用了群发信息的接口,客户端就可以通过onmessage函数来处理接收到的信息。
浏览器控制台测试
如果想要尽快测试结果,不想写前端代码,可以直接在控制台中输入以下代码(对5中的代码稍作修改):
然后在新建一个页面并地址栏中输入http://localhost:8080/broadcast?msg=1234567并回车(记得将4中的PostMapping改为GetMapping,并删掉@RequestBody),输完回车后,在返回上一个界面查看控制台,即可发现接收信息:
总结
本文简单介绍了如何通过SpringBoot集成WebSocket实现群发信息的功能,本文只讲解了WebSocket的基本使用,也只使用了ws,在下篇文章将会介绍如何使用加密的wss协议。