前言
前一段时间需要做一个关于监控服务器的需求,如果某个服务器挂了就需要在前端展示,定时请求又很。。。就想到了 websocket 服务器自动推送的技术,记录一下我使用的全过程,希望对大家有帮助!
一、前端调用代码
在用这个之前当然需要先了解一下啦!
HTTP 协议做不到服务器主动向客户端推送信息。而 websocket 它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。并且他没有同源限制,协议标识符是ws(如果加密,则为wss)。
我将 websocket 连接写到了刚开始的地方,然后直接打开控制台,根据输出看有没有连接成功就好啦。
componentDidMount() {
if(typeof(WebSocket) == "undefined") {
console.log("您的浏览器不支持WebSocket");
}else{
console.log("您的浏览器支持WebSocket");
}
let websocket = new WebSocket("ws://10.200.125.165:8080/api/mail/index");
//打开事件
websocket.onopen = function () {
console.log("websocket已打开");
}
//发现消息进入
websocket.onmessage = function (msg) {
console.log("websocket已连接");
console.log(msg.data); // 第一次进去会显示:连接成功
}
//关闭事件
websocket.onclose = function() {
console.log("websocket已关闭");
};
//发生了错误事件
websocket.onerror = function() {
console.log("websocket发生了错误");
}
}
二、前后端联调中的问题
1. 连接成功之路
(1)完全没成功
写完代码直接就成功是不可能的哇,第一个问题,没连上,一个函数都没进去,报错如下:
然后我跟后台小哥哥就开始搜,搜出来这种报错一般是后台过滤器,拦截器的问题,然后在这方面查了也没什么问题,并且还给我了postman的截图。
然后我俩就开始想为啥子 postman 能连上,但是前端连不上呢,过了一会,看着那个 http 和 ws 突然灵光一闪,去搜了一下 postman测试websocket接口 ,好家伙,原来跟平时的请求方法不一样。
用这个测的话也是没有连上的状态,所以后台又进行了一系列的检查,结果发现。。。是大小写粗心写错了emmmm。
(2)进入onopen,但是没数据
改完上面的问题,好,这次可以连接了,url如下:ws://10.200.122.123:8080/imserver/10 (跟前面不一样是因为当时换了个地址)结果后台说那个10没有传过来,也就是连上了,进入onopen但是onmessage那个函数没执行,我当时还在传这个10干啥,不是你给我传数据嘛。。这个好像也不需要我动手,后台一会会就改好啦!然后我们就连接成功了!
分享一下成功的截图:
图中的连接成功是第一次 onmessage 里面 msg.data 的输出,然后后台发给我123123也可以在控制台看到。
2. 神奇的 userId
(1)问题出现:
成功之后,当然是后台给我发点消息测试啦!我们当时用的ws://10.200.122.123:8080/imserver/10 ,然后,后台小哥哥连的我本地,所以我们看的一个页面,发请求也是一个url,然后他说要发数据了,我半天都没收到,结果。。。嗯。。他收到了,我没收到。原来id一样的话只会给一个用户发消息,所以这就需要保证每次用户打开的时候需要是不同的id。
(2)解决问题:
为了让用户的id不同,我先想到了随机数,搞了个0-1000的随机数,每次用户进来就随机造一个数字做为id,然后又想到说不定很巧的两个人随机数就一样了。就开始思考什么才能保证不重复,啊,时间戳,但是他又太长了,虽然后台对这个没要求,但是我又把它转成了36进制,这下总不会相同了叭。
当时还想到用户ip作为id传,然后就查前端怎么获取用户ip,http://pv.sohu.com/cityjson?ie=utf-8结果我们用这个发现大家都是同一个ip,可能是因为内网吧。
三、运用到项目中发现的问题
前后端联调的差不多之后,我就要根据onmessage里的数据开始渲染页面了,这时候发现。。。this.setState操作时,this找不到了。 后来改成了
componentDidMount() {
//......
websocket.onmessage = this.message
//......
}
message = (msg) => {
console.log("websocket有数据");
console.log(msg.data);
// 逻辑处理,这里this可以正常获取了
}
差不多就这些啦。
总结
1. onmessage里面用来处理函数,注意this的指向
2. 每个用户需要创建不同的id,后台会根据id发消息(向所有人发消息时,后台需要存储当前在线的人)
3. 注意url 是ws开头。