1. 什么是WebSocket?
WebSocket是一种全双工通信协议,它基于TCP/IP协议,可以在客户端与服务器之间建立一个无限期的双向通信的通道。
浏览器实现WebSocket协议可以利用JavaScript来发送和接收消息。相较于HTTP协议,WebSocket具有双向通信和实时性的优势。
1.1 WebSocket的特点
WebSocket的主要特点有下面几个方面:
全双工通信
基于TCP协议,保证数据可靠性
双方能随时发送和接收数据,无需等待
较少的控制开销,服务器可以主动发送消息给客户端
1.2 创建WebSocket连接
var socket = new WebSocket("ws://localhost:8080");
socket.onopen = function(event) {
console.log("WebSocket连接已经建立成功!");
};
socket.onmessage = function(event) {
console.log("服务端返回数据:", event.data);
};
socket.onclose = function(event) {
console.log("WebSocket已经关闭:", event);
};
socket.onerror = function(event) {
console.log("WebSocket连接发生错误:", event);
};
如上代码中,我们可以通过new WebSocket(url)创建一个WebSocket连接对象,其中url表示服务器地址。在建立连接后,我们可以通过onopen、onmessage、onclose和onerror这些事件监听来实现与服务器的交互。
2. WebSocket心跳重连
有时,我们的WebSocket连接会因为网络不稳定等原因而中断,这时候需要通过心跳包来保持连接的稳定性,同时当连接中断时也需要自动进行重连,以确保数据的完整性。
2.1 心跳包实现
我们可以通过定时发送数据包来实现心跳包,例如每隔30秒发送一个ping包,服务器返回pong包表示连接未断开。
var socket = new WebSocket("ws://localhost:8080");
socket.onopen = function(event) {
setInterval(() => {
socket.send("ping");
}, 30000);
};
socket.onmessage = function(event) {
if (event.data === "pong") {
console.log("服务端返回心跳包");
} else {
console.log("服务端返回数据:", event.data);
}
};
如上代码中,我们使用setInterval定时发送ping数据包,同时在onmessage事件监听中处理服务端返回的pong包。这样我们就可以通过定时发送心跳包来保持WebSocket连接的稳定性。
2.2 重连机制实现
当WebSocket连接中断时,我们需要自动重连来保持连接的稳定性和数据的完整性。
var socket = null;
var lockedReconnect = false; // 线程锁,避免重复连接
var inited = false;
function createWebSocket(url) {
try {
socket = new WebSocket(url);
socket.onopen = function(event) {
console.log("WebSocket连接已经建立成功!");
};
socket.onmessage = function(event) {
if (event.data === "pong") {
console.log("服务端返回心跳包");
} else {
console.log("服务端返回数据:", event.data);
}
};
socket.onclose = function(event) {
console.log("WebSocket已经关闭:", event);
if (!lockedReconnect && !inited) {
reconnect(url);
}
};
socket.onerror = function(event) {
console.log("WebSocket连接发生错误:", event);
if (!lockedReconnect && !inited) {
reconnect(url);
}
};
} catch (e) {
console.log("WebSocket连接失败!");
reconnect(url);
}
}
function reconnect(url) {
if (lockedReconnect) {
return;
}
lockedReconnect = true;
setTimeout(() => {
console.log("WebSocket重新连接!");
createWebSocket(url);
lockedReconnect = false;
inited = true;
}, 5000);
}
createWebSocket("ws://localhost:8080");
如上代码实现了基于心跳包的WebSocket重连机制。我们使用了一个线程锁lockedReconnect来避免重复连接,在onclose和onerror事件监听中处理连接中断的情况,并使用setTimeout来实现重连逻辑,同时也注意了避免重复连接的问题。
3. 基于微信小程序的实现
为了在微信小程序中实现WebSocket的心跳重连,我们可以使用小程序提供的网络API:wx.connectSocket、wx.sendSocketMessage、wx.onSocketMessage、wx.onSocketOpen、wx.onSocketError和wx.onSocketClose等事件监听,用法类似浏览器的WebSocket API。同时,由于小程序的不同点,我们需要注意一些细节问题。
3.1 小程序中WebSocket的实现
let socketTask = null;
function createWebSocket(url) {
socketTask = wx.connectSocket({
url: url,
header: {
"content-type": "application/json"
}
});
socketTask.onOpen(function(res) {
console.log("WebSocket连接已经建立成功!");
socketTask.send({ data: "ping" });
setInterval(() => {
socketTask.send({ data: "ping" });
}, 30000);
});
socketTask.onMessage(function(res) {
if (res.data === "pong") {
console.log("服务端返回心跳包");
} else {
console.log("服务端返回数据:", res.data);
}
});
socketTask.onClose(function(res) {
console.log("WebSocket已经关闭:", res);
reconnect(url);
});
socketTask.onError(function(res) {
console.log("WebSocket连接发生错误:", res);
reconnect(url);
});
}
function reconnect(url) {
setTimeout(() => {
console.log("WebSocket重新连接!");
createWebSocket(url);
}, 5000);
}
createWebSocket("ws://localhost:8080");
在小程序中,我们使用wx.connectSocket来创建WebSocket连接,同时,在onOpen事件监听中启动心跳包定时器,onClose和onError事件监听中处理重连逻辑。
3.2 心跳重连的实现
在小程序中,我们需要注意以下几个问题:
心跳包需要以字符串形式发送,不能使用JSON格式。
由于小程序对WebSocket连接的维护不如浏览器稳定,有时候会出现连接中断但是不触发onClose和onError事件监听的情况,这时候需要使用onSocketClose事件监听来检测连接中断。
let socketTask = null;
function createWebSocket(url) {
socketTask = wx.connectSocket({
url: url,
header: {
"content-type": "application/json"
}
});
socketTask.onOpen(function(res) {
console.log("WebSocket连接已经建立成功!");
socketTask.send({ data: "ping" });
setInterval(() => {
socketTask.send({ data: "ping" });
}, 30000);
});
socketTask.onMessage(function(res) {
if (res.data === "pong") {
console.log("服务端返回心跳包");
} else {
console.log("服务端返回数据:", res.data);
}
});
socketTask.onClose(function(res) {
console.log("WebSocket已经关闭:", res);
reconnect(url);
});
socketTask.onError(function(res) {
console.log("WebSocket连接发生错误:", res);
reconnect(url);
});
wx.onSocketClose(function(res) {
console.log("WebSocket已经关闭:", res);
reconnect(url);
});
}
function reconnect(url) {
setTimeout(() => {
console.log("WebSocket重新连接!");
createWebSocket(url);
}, 5000);
}
createWebSocket("ws://localhost:8080");
4. 总结
本文介绍了WebSocket的特点和基本使用方法,并且详细讲解了如何实现WebSocket的心跳重连。同时,我们还结合了微信小程序的特点,实现了基于小程序的WebSocket心跳重连功能。
WebSocket作为一种新型的双向通信协议,具有实时性和稳定性的优势,在前端开发中被广泛应用。通过本文的学习,相信读者对WebSocket有了更深入的理解和使用经验。