以下文章来源于ELab团队 ,作者ELab.linmuen
分享技术新见解
题外话:
HTTP keep-alive 的作用是,告知服务端持久化当前的 TCP 连接,不要立即断开,以便后续的 HTTP 请求复用它,也就是我们所说的「长连接」
HTTP 的 keep-alive 是为了让 TCP 活久一点,而 TCP 本身也有一个 keepalive(注意没有横杠哦)机制。这是 TCP 的一种检测连接状况的保活机制,keepalive 是 TCP 保活定时器:TCP 建立后,如果闲置没用,服务器不可能白等下去,闲置一段时间[可设置]后,服务器就会尝试向客户端发送侦测包,来判断 TCP 连接状况,如果没有收到对方的回答(ACK包),就会过一会[可设置]再侦测一次,如果多次[可设置]都没回答,就会丢弃这个 TCP 连接
(TCP keepalive 保活示意图)
背景与目的:
伪码示意:
SocketTask.onOpen(function () {
SocketTask.sendSocketMessage({
msg_type: '验签',
token: 'xxx'
}, (response) => {
console.log(response.user_id, response.access_token)
// 通道可用,打个标记
global.isSocketAvaliable = true;
})
})
背景与目的:为了减少 TCP 连接的无效占用,客户端定时发送一个空包到服务端,告知服务端不要销毁这条 socket,如果服务端超过一定时间都没收到心跳包,则将关闭并销毁该 socket
伪码示意:
SocketTask.onOpen(function () {
SocketTask.sendSocketMessage({
msg_type: '验签',
token: 'xxx'
}, (response) => {
console.log(response.user_id, response.access_token)
// 通道可用,打个标记
global.isSocketAvaliable = true;
// 验签成功,开始定时发送心跳包
setInterval(() => {
SocketTask.sendSocketMessage({
msg_type: '心跳'
});
});
});
})
背景与目的:在发送心跳包时,可得知一个心跳包的 RTT,以此模拟当前用户网络环境的 TCP RTT,并据此计算出平滑 RTO,用于弱网体验优化
伪码示意:
SocketTask.onOpen(function () {
SocketTask.sendSocketMessage({
msg_type: '验签',
token: 'xxx'
}, (response) => {
console.log(response.user_id, response.access_token)
// 通道可用,打个标记
global.isSocketAvaliable = true;
// 验签成功,开始定时发送心跳包
setInterval(() => {
// 计算 RTT
const begin = Date.now();
SocketTask.sendSocketMessage({
msg_type: '心跳'
}, () => {
const end = Date.now();
const RTT = begin - end;
const smoothedRTO = cal(RTT);
global.smoothedRTO = smoothedRTO;
});
});
});
});
背景与目的:在小程序中引入第三方压缩包(牺牲小程序包体积),减少 websocket 传输的字节数
伪码示意:
import Snappy from 'snappy';
SocketTask.sendSocketMessage = function (msg) {
const encryptedMsg = Snappy.encode(msg);
wx.send(encryptedMsg);
}
背景与目的:用户的网络环境不稳定,可能会存在主动 / 被动断开 socket 的情况,需要进行自动重连
伪码示意:
SocketTask.onClose(function () {
// 限定最大重连次数
if (retryCount > maxCount) {
return;
}
retryCount++;
setTimeout(() => {
SocketTask.connectSocket();
}, retryCount * 1000 + Math.random() * 1000);
});
背景与目的:为减少网络传输的包体积,通过 websocket 上报埋点日志时,可以把部分重复字段值在第一次上报时缓存在服务端,从第二次上报开始只上报值不重复的字段,然后由服务端做日志合并
伪码示意:
SocketTask.sendSocketMessage({
msg_type: '埋点日志',
logs: {
country: 'China', // 可缓存字段
city: '北京', // 可缓存字段
platform: '安卓', // 可缓存字段
click_some_btn: true // 动态变化的埋点字段
},
cacheFields: ['country', 'city', 'platform'] // 只在第一次上报时携带
});
TCP_NODELAY 是用来禁用 Nagle 算法的。Nagle 算法设计的目的是提高网络带宽利用率,其核心思路是「合并小的 TCP 包为一个大的 TCP 包」,避免过多的小包的 TCP 头部浪费网络带宽
参考资料:https://www.zhihu.com/question/42308970
欢迎
长按图片加刷碗智为好友
,我会第一时间和你分享前端行业趋势,学习途径,搞怪趣事,生活中的另一面幽默等等。新的一年我们一起洗刷刷!!!!!!