Coder Social home page Coder Social logo

websocket-heartbeat-js's People

Contributors

dependabot[bot] avatar webrsb avatar zimv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

websocket-heartbeat-js's Issues

源码的一个疑问

this.pongTimeoutId = setTimeout(() => {
            //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
            this.ws.close();
}, this.opts.pongTimeout);

为什么直接执行reconnect 会触发onclose导致重连两次

【BUG】重连逻辑存在漏洞

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);
};

WebSocket 应用逻辑

根据我的实际测试, 发现:

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 上.

一直在重连

一直尝试重连,而导致断开连接。
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 ?

protocal传参

请问如何传入websocket constructor里的protocal参数?

pingMsg能否支持函数?

后端有需求心跳信息每次需要传不同的id,能否把pingMsg调整为支持函数的形式,代码类似如下:

this.ws.send(typeof this.opts.pingMsg === 'function' ? this.opts.pingMsg(): this.opts.pingMsg);

why client reconnect to server periodically

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.

[Feature] Will add a filter abuot Pong messages for “onmessage” function

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.

this.ws.onmessage = (event) => {

this.ws.onmessage = (event) => {
  if (event.data !== this.opts.pongMsg) {
    this.onmessage(event);
  }
  this.heartCheck();
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.