前言
<<手把手教你入门vue+springboot开发(十)–springboot集成WebSocket>>中我们研究了springboot集成WebSocket实现HTTP服务端向浏览器上报消息事件,随着研究的深入,特别是业务代码的加入,我们遇到了一些问题,在解决这些问题的过程中我们对springboot和WebSocket都有了一些更深的理解,现把它们分享出来,跟大家共同学习。
一、window.location
<<手把手教你入门vue+springboot开发(十)–springboot集成WebSocket>>的实例在本机开发调试时没有问题,但是当我们把它真实部署到服务器上时,就发现websocket连接没有建立。为什么呢?
我们先来理解一下,HTTP协议与WebSocket协议的区别。在springboot中,HTTP协议实际上还是跑在tomcat虚拟机上,由于有虚拟机的存在,所以vue前端和springboot后端可以看成跑在同一台机器上。但是WebSocket有所不同,它实际上可以理解成是个TCP长连接,就是从浏览器到HTTP服务器之间建立的TCP连接,那么浏览器要连接websocket服务端就需要通过服务器的IP来连接。
let ws = new WebSocket("ws://localhost:8080/myWs")
再回到<<手把手教你入门vue+springboot开发(十)–springboot集成WebSocket>>的实例,WebSocket客户端连接服务端用的是localhost,在本机开发调试过程中,由于前端与后端代码跑在同一台机器上,所以测试没有问题。但是当springboot+vue打包部署到服务器上时,浏览器连接的是本机的服务端,本机根本没有WebSocket服务端,所以连接不上。
那么springboot如何获取浏览器中输入的IP地址来建立WebSocket连接呢?这时候就需要使用window.location。
window.location | 返回值 |
---|---|
.origin | 协议 + 域名/IP + 端口(http://127.0.0.1:8080) |
.protocol | 协议 (http: 或者 htts:) |
.host | 域名/IP + 端口(127.0.0.1:8080) |
.port | 端口(8080) |
.pathname | ‘/’ 后面跟的路径 |
.search | ‘?’ 后面跟的查询字符串 |
.hash | 从 ‘#’ 号开始的部分 |
.href | 完整网址 |
把上述代码中”localhost:8080“替换成window.location.host即可解决问题。
当然,我们不仅可以调用window.location的属性来检索URL信息,还可以使用它来设置新属性并更改URL,.origin属性是只读的,不能设置,其它属性都可以设置。
二、WebSocket心跳实现
在<<手把手教你入门vue+springboot开发(十)–springboot集成WebSocket>>中,如果WebSocket服务端与客户端之间网络断开,或者WebSocket服务端意外关闭时,WebSocket客户端需要知道并通知用户。所以WebSocket客户端与服务端之间需要有心跳机制,在WebSocket协议中,PING和PONG消息是用来检测连接的活跃性和响应性的,PING消息由客户端发送到服务器,服务器必须用PONG消息进行响应。
1.后端代码修改
springboot后端只需要修改接收消息的回调函数onMessage,收到前端发来的心跳消息"PING"后回复"PONG"消息。
@OnMessage
public String onMessage(Session session, String text){
log.info("收到一条新消息: " + text);
if (text.equals(