一、简介:
websocket 建立网络长链接,最开始存在的意义就是为了解决我们使用 '轮询' 的方式进行网络请求,轮询的效率很低并且浪费网络资源,一般使用定时器来实现,而 websocket 的出现就解决了这个问题。它实现了服务器端直接向客户端推送消息,并且客户端也可以直接向服务端发送消息,这是一个真正的双向平等对话。最典型的例子就是聊天室。
二、客户端的简单实现方法:
1.实例化一个 ws 对象 ,即:
var ws = new WebSocket(' url ');
复制代码
2.简单的步骤:
①链接打开的事件监听:
ws.onopen = function(event) {
console.log("Connection open ...");
ws.send("Hello WebSockets!"); // 向服务器发送数据
};
复制代码
②监听消息事件,当有消息到达就会直接触发:
ws.onmessage = function(event) {
console.log( "Received Message: " + evt.data);
ws.close(); // 关闭请求
};
复制代码
③监听关闭事件,当使用close 时触发:
ws.onclose = function(event) {
console.log("Connection closed.");
};
复制代码
④错误监听:
ws.onerror = function( err ){
console.error(err)
}
复制代码
此处注意事项:
使用 onmessage 接受消息的时候,我们可以指定数据类型,服务器的数据可能是文本,也可能是二进制数据, 以上就是一个最基本的客户端的 websocket 实现;
三、WebSocket.readyState 实例对象的当前状态:
通过 switch 可以直接查看;
switch (ws.readyState){
case WebSocket.CONNECTING:
console.log('值为0,表示正在创建链接');
break;
case WebSocket.OPEN:
console.log('值为1,表示连接成功,可以通信');
break;
case WebSocket.CLOSING:
console.log('值为0,表示正在关闭链接');
break;
case WebSocket.CLOSED:
console.log('值为0,表示连接已经关闭或者打开连接失败');
break;
default:
break;
}
复制代码
四、日常代码开发封装:
在平时我们写代码的时候,可以通过封装一个类来实现 socket 长链接,具体代码如下:
class SocketManager {
_socketMsgQueue = [];
_isOpen = false;
_messageCbs = [];
constructor(url) {
if(!url) {
console.error('SocketManager: url is required');
return;
}
this._url = url;
this._init();
// 判断是否有url 的存在,如果没有就return,否则执行init () 方法;
}
_init() {
// 创建WebSocket 链接:
this._socketInstance = new WebSocket(this._url);
// 打开链接并发送数据:
this._socketInstance.onopen = () => {
this._isOpen = true;
for (let i = 0; i < this._socketMsgQueue.length; i += 1) {
this.sendMessage(this._socketMsgQueue[i]);
}
this._socketMsgQueue.length = 0;
};
this._socketInstance.onmessage = (e) => {
for (let i = 0; i < this._messageCbs.length; i += 1) {
this._messageCbs[i](e.data);
}
};
this._socketInstance.onclose = () => {
this.destroy();
this._init();
};
}
//调用的回调,这个地方比较绕,我想了大半天!!!和上述的onmessage 时间相对应
的。我们调用的时候,将一个函数出入,所以此时数组中保存的多个函数!!!所以在
onmessage 中,我们拿到的e.data 就是数据使用for 循环,调用每一个函数!!!
registerMessage(cb) {
if (typeof cb === 'function') {
this._messageCbs.push(cb);
}
}
// 发送数据,可通过this._isOpen 来判断是否打开了长链接;
sendMessage(msg) {
if (this._isOpen) {
this._socketInstance.send(msg);
} else {
this._socketMsgQueue.push(msg);
}
}
// 销毁此次长链接
destroy() {
this._socketInstance.close();
this._socketInstance.onmessage = null;
this._socketInstance.onopen = null;
this._socketInstance.onclose = null;
delete this._socketInstance;
}
}
export default SocketManager;
复制代码
五、封装对象的调用:
1.首先引入我们封装对象的文件;import ....
2.由于我们封装的时候是将这个对象暴露出去的,所以在引入之后,直接new 这个对象即可:
const socketMng = new SocketManager(xcxSocketUrl);
复制代码
注意:这个地方的 url 是必须传入的,在对象中也做了一个判断!
3.执行方法:
socketMng.sendMessage('这是数据!!!');
socketMng.registerMessage((msg)=>{
if(...){
// 执行相应的操作!
}
})
复制代码
注意:此时的这个箭头函数,就是我们在registerMessage ()中传入的值,即cb;
以上就是最近写 WebSocket 所学习到的所有知识了,希望对大家有所帮助!!!不喜勿碰....