zimv / websocket-heartbeat-js Goto Github PK
View Code? Open in Web Editor NEW:hearts: simple and useful
License: MIT License
:hearts: simple and useful
License: MIT License
我这边后台想知道用户是不是第一次连接。。向修改url可以实现吗?
在options参数相同的情况下,如何创建一个单例的ws对象呢?而不是每new一个,就新建一个ws连接。
this.pongTimeoutId = setTimeout(() => {
//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
this.ws.close();
}, this.opts.pongTimeout);
为什么直接执行reconnect 会触发onclose导致重连两次
因为在实际业务中,可能连接多次失败以后基本可以判断是网络或者服务的问题
WebsocketHeartbeatJs.prototype.reconnect = function(){
// 如果重连过程中,连接成功了,并不会停止这里的逻辑
if(this.opts.repeatLimit>0 && this.opts.repeatLimit <= this.repeat) return;
if(this.lockReconnect || this.forbidReconnect) return;
// TODO: 需要在加类似连接成功的判断,否则会出现一直重连
if (this.status === 'connect') return
this.lockReconnect = true;
this.repeat++;
this.onreconnect();
setTimeout(() => {
this.createWebSocket();
this.lockReconnect = false;
}, this.opts.reconnectTimeout);
};
问下为什么把返回的对象存进vuex里面的属性。然后调用关闭方法 没效果?
根据我的实际测试, 发现:
server 与 client 对 websocket 处理逻辑完全相同:
一端正常关闭,另一端也会正常关闭。
一端异常关闭(断网,更准确的说是找不到此 ip, 再准确的说是找不到此电脑),另一端会等待一段时间后再关闭。
如果这段时间内找到了此 ip:
如果双方进程都保留着 websocket 连接,则连接恢复正常,并且把这段时间内 send 的消息一块发完(只保证自己这边的顺序,至于双方的顺序就不被保证了)
如果其中一方连接丢失,则另一方会在 send 的时候发现并立即触发自己的 close。
或者不 send 消息, 只是等待一段时间后关闭自己
连接正常的时候,哪怕没有任何消息,也不会关闭:所以本质上来说,websocket 本身就有个底层传输层心跳包,不然无法出现“等待一段时间后再关闭”的情况
但长时间没有消息,运营商可能会断开连接,让两端各自认为另一端异常关闭,并且一直找不到 ip,哪怕明明 ip 在那儿,连接在那儿, send 消息也只会 buffer 起来.
于是, 单纯的对于使用而言, 只要这样就好:
client.onclose = () => {
setState({closed:true}); // 改变 UI
client.reconnect();
}
如果要求界面上完全显示(即要不 client 显示自己已断开连接,要不 client 就要立即响应 server 变化), 那 server 要每秒向 client 发 应用层心跳, client 如果两秒内没收到心跳,就断开自己,并显示已断开,并重新连接
如果要求 server 消息不丢失(事实上做不到, 或者说非常复杂,应该改变程序逻辑模型)
其实, 当 websocket 连接断开的时候, 不是什么 前端 后端 无感知, 而是它们都有 buffer, 它们本身就有传输层心跳, 它们立即就感知到断网了, 但是它们在等待着重新联网, 期间发消息都发到 buffer 上.
I'm running the same code on client side (browser) and server side (node.js)
I will not be using this library on the server side, but it needs to load properly.
Right now when the code executes I get this error window is not defined
使用的时候报这个错,有人遇到过吗?
一直尝试重连,而导致断开连接。
connect success index.vue?6ced:126 close connecti... index.vue?6ced:129 reconnecting... index.vue?6ced:132 connect success index.vue?6ced:126 close connecti... index.vue?6ced:129 reconnecting... index.vue?6ced:132 connect success index.vue?6ced:126 close connecti... index.vue?6ced:129 reconnecting... index.vue?6ced:132 connect success
这个我设置了 pingTimeout: 1000,
repeatLimit: 1 这个为什么会一直进行重连? 我设置来重连次数是1。可是这个会一直给ws发送消息。然后创建一个新链接
这个重连,我需要根据状态来判断是否需要重连。有暴露手动进行重连的函数吗。比如用户离线,我需要断开。然后用户又上线来我需要对之前断开的webscoket进行重连
后台要返回什么呢
WebSocket断线后我重新new了一个链接,新的连接在Network里看可以继续收到和发出数据,但是我发现ws.onmessage没有返重连后的数据
我感觉他是不是还在等断线前的那个地址的数据
`
export function initWebsocket(user = {}, userType) {
socketurl = "ws://" + WEBSOKET_URL + "//////"
ws = new WebSocket(socketurl);
ws.onopen = function (evt) {
wsReadyState = evt.currentTarget.readyState;
if (wsReadyState == 1) {
//连接好了之后
wsPromise = new Promise((resolve, reject) => {
resolve();
})
wsPromise.then((data) => {
let wsMsgListCopy = [
...wsMsgList
];
wsMsgListCopy.forEach((msg) => {
ws.send(JSON.stringify(msg));
wsMsgList.shift();
})
})
initEventHandle();
}
};
return ws;
}
export function sendMsgByWebsccket(msg, toast, ) {
//发送信息时调用
ws.send(JSON.stringify(msg));
}
function createWebSocket(url) {
try {
ws = new WebSocket(url);
initEventHandle();
} catch (e) {
reconnect(url);
}
}
function initEventHandle() {
ws.onclose = function () {
reconnect(socketurl);
};
ws.onerror = function () {
reconnect(socketurl);
};
}
function reconnect(url) {
if (lockReconnect) return;
lockReconnect = true;
setTimeout(function () {
createWebSocket(url);
lockReconnect = false;
}, 2000);
}
const heartCheck = {
timeout: 10000,
serverTimeoutObj: null,
reset: function () {
clearTimeout(this.serverTimeoutObj);
return this;
},
start: function () {
const self = this;
self.serverTimeoutObj = setTimeout(function () {
ws.close();
createWebSocket(socketurl);
}, self.timeout)
}
}
// index.js
import { initWebsocket } from '../websocket'
componentDidMount() {
console.log('接收数据');
const self = this;
self.ws = initWebsocket(curUser, USER_TYPE);
self.ws.onmessage = (event) => {
const arg = JSON.parse(event.data);
//处理接收的数据,现在重连后这里收不到了
}
}
`
WebsocketHeartbeatJs.prototype.createWebSocket = function(){
try {
this.ws = new WebSocket(this.opts.url);
this.initEventHandle();
} catch (e) {
this.reconnect();
throw e;
}
};
WebsocketHeartbeatJs.prototype.reconnect = function(){
if(this.lockReconnect || this.forbidReconnect) return;
this.lockReconnect = true;
this.onreconnect();
//没连接上会一直重连,设置延迟避免请求过多
setTimeout(() => {
this.createWebSocket();
this.lockReconnect = false;
}, this.opts.reconnectTimeout);
};
this.lockReconnect = false
是不是应该放在 this.createWebSocket()
前面?
createWebSocket 报错后,运行 reconnect 方法,this.lockReconnect 是 undefined,this.lockReconnect 被置为 true, 注册一个 setTimeout 方法,reconnectTimeout 后,执行该方法,运行 this.createWebSocket() ,再报错,再运行 reconnect 方法,this.lockReconnect 此时为 true,直接 return。不会再运行 createWebSocket 方法进行重连。
是不是需要在 setTimeout 方法里 this.createWebSocket 前,就把 this.lockReconnect 置为 false ?
请问如何传入websocket constructor里的protocal参数?
后端有需求心跳信息每次需要传不同的id,能否把pingMsg调整为支持函数的形式,代码类似如下:
this.ws.send(typeof this.opts.pingMsg === 'function' ? this.opts.pingMsg(): this.opts.pingMsg);
const httpUrl = getValueByKeys(window, "SITE_CONFIG.apiURL").replace('http','ws')
const options = {
url: ${httpUrl}/sys/apple/ws/${id}
,
pingTimeout: 15 * 1000,
pongTimeout: 10 * 1000,
reconnectTimeout: 2000,
// repeatLimit: 20,
}
const socket = new WebsocketHeartbeatJs(options)
socket.onopen = () => {
console.log('websocket连接成功')
}
socket.onmessage = async (evt) => {
const res = evt.data
let data = {}
try {
console.log('onmessage:', evt.data)
} catch (err) {
console.log('websocket error: ', err)
}
}
socket.onreconnect = async (evt: any) => {
console.log("reonnectting...", evt)
}
why the client reconnect to server periodically?
the server has already implemented the protocol stated by you, that is send pong when receiving ping.
That isn’t usually need messages of Pong that most people .
对于多数人来说,不需要pong消息
So, I hope @zimv
to add a filter for onmessage
.
所以希望作者大大为onmessage
加入一个过滤
We can setting a pongMsg
, like pingMsg
too, and to filter pongMsg
.
我们可以像pingMsg
一样设置pongMsg
, 之后过滤 pongMsg
This is my idea.
websocket-heartbeat-js/lib/index.js
Line 68 in dad676c
this.ws.onmessage = (event) => {
if (event.data !== this.opts.pongMsg) {
this.onmessage(event);
}
this.heartCheck();
};
同时建立多个webscoket连接,用工厂模式会产生闭包。用数组就不会。大佬你知道还有什么好的办法吗
现在不断的关闭重连,如何看到close的原因?
websocketHeartbeatJs.onclose = function () {
console.log('close......');
}
没有参数
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.