我正在使用使用PHP5和Chrome浏览器作为客户端的Web套接字。 我已将网站的代码记录下来。服务器在WebSocket中重新启动时重新连接客户端
我运行服务器,客户端也连接。我也可以聊天。 现在,当我重新启动服务器(通过将其重新启动并重新启动服务器)时, 客户端将获取断开连接的信息,但是当我发送消息时,它自动不会与服务器重新连接。
如何实现这一目标?就像我收到断开连接的信息一样,我是否应该检查并将其发送到JavaScript以刷新页面或重新连接?
我正在使用使用PHP5和Chrome浏览器作为客户端的Web套接字。 我已将网站的代码记录下来。服务器在WebSocket中重新启动时重新连接客户端
我运行服务器,客户端也连接。我也可以聊天。 现在,当我重新启动服务器(通过将其重新启动并重新启动服务器)时, 客户端将获取断开连接的信息,但是当我发送消息时,它自动不会与服务器重新连接。
如何实现这一目标?就像我收到断开连接的信息一样,我是否应该检查并将其发送到JavaScript以刷新页面或重新连接?
当服务器重新启动时,Web Socket连接关闭,因此将触发JavaScript onclose
事件。这是一个尝试每五秒重新连接的示例。
function start(websocketServerLocation){
ws = new WebSocket(websocketServerLocation);
ws.onmessage = function(evt) { alert('message received'); };
ws.onclose = function(){
// Try to reconnect in 5 seconds
setTimeout(function(){start(websocketServerLocation)}, 5000);
};
}
安德鲁给出的解决方案是不完美的工作,因为在失去连接的情况下,服务器可能会发送多个关闭事件。
在这种情况下,你会设置几个setTimout的。如果服务器在五秒钟之前准备就绪,Andrew提供的解决方案可能只能工作。
然后,根据安德鲁解决方案,返工,我利用的setInterval的ID附加到window对象(这种方式它是可用“无处不在”):
var timerID=0;
var socket;
/* Initiate what has to be done */
socket.onopen=function(event){
/* As what was before */
if(window.timerID){ /* a setInterval has been fired */
window.clearInterval(window.timerID);
window.timerID=0;
}
/* ... */
}
socket.onclose=function(event){
/* ... */
if(!window.timerID){ /* Avoid firing a new setInterval, after one has been done */
window.timerID=setInterval(function(){start(websocketServerLocation)}, 5000);
}
/* That way, setInterval will be fired only once after losing connection */
/* ... */
}
我一直在用这个有一段时间是纯粹的香草JavaScript,它支持比其他答案更多的情况。
document.addEventListener("DOMContentLoaded", function() {
'use strict';
var ws = null;
function start(){
ws = new WebSocket("ws://localhost/");
ws.onopen = function(){
console.log('connected!');
};
ws.onmessage = function(e){
console.log(e.data);
};
ws.onclose = function(){
console.log('closed!');
//reconnect now
check();
};
}
function check(){
if(!ws || ws.readyState == 3) start();
}
start();
setInterval(check, 5000);
});
这将尽快服务器关闭连接重试,它会检查连接,以确保它是由每5秒钟也。
因此,如果服务器在运行时或onclose事件发生时未启动,则该连接在其恢复联机后仍会恢复。
注意:使用此脚本不会允许您永远停止尝试打开连接......但我认为这就是您想要的?
以下是我在我的项目中使用的代码,其工作100%。
var name = sessionStorage.getItem('name');
wsUri = "ws://localhost:8080";
var websocket;
$(function() {
init();
$("#chat_text_box").on("keypress", function(e) {
if (e.keyCode == 13) { //For Enter Button
e.preventDefault();
var mymessage = $('#chat_text_box').val();
if(mymessage){
var msg = { type: 'chat_text', data : { name:name, msg:mymessage } };
console.log(msg);
websocket.send(JSON.stringify(msg));
$('#chat_text_box').val('');
}
return false;
}
});
});
function init() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(ev) { /*connection is open */ }
websocket.onmessage = function(ev) {
var data = JSON.parse(ev.data); //PHP sends Json data
var type = data.type;//alert(JSON.stringify(data));
switch(type) {
case "chat_text":
var text = "<div><span class='user'>"+data.data.sender_name+" : </span><span class='msg'>"+data.data.msg+"</span></div>";
$('#chat-messages').append(text);
break;
default:
break;
}
};
websocket.onerror = function(ev){};
websocket.onclose = function(ev) { init(); };
}
GitHub上托管该装饰的WebSocket的API提供一个WebSocket连接,如果连接中断,将自动重新连接一个小型的JavaScript库。
使用gzip压缩的缩小库小于600字节。
官方资料库,请访问:
https://github.com/joewalnes/reconnecting-websocket
如果当它重新启动大量的客户端连接到服务器。 通过使用指数退避算法来管理客户端的重新连接时间可能是值得的。
该算法是这样的:
参考:
http://blog.johnryding.com/post/78544969349/how-to-reconnect-web-sockets-in-a-realtime-web-app
ReconnectingWebSocket不处理利用该算法重新连接。
https://github.com/gamestdio/websocket.js使用指数退避 – vgoklani 2016-05-19 11:43:42
很好的答案,尤其是因为它提到服务器关闭Web套接字连接后服务器负载过高的风险,并且所有客户端(可能是数百或成千上万)尝试同时重新连接。除了指数退避之外,您还可以随机化0到10秒之间的延迟。这也会将负载分散到服务器上。 – 2017-03-17 15:03:35
不能发表评论,但以下几点:
var socket;
const socketMessageListener = (event) => {
console.log(event.data);
};
const socketOpenListener = (event) => {
console.log('Connected');
socket.send('hello');
};
const socketCloseListener = (event) => {
if (socket) {
console.error('Disconnected.');
}
socket = new WebSocket('ws://localhost:8080');
socket.addEventListener('open', socketOpenListener);
socket.addEventListener('message', socketMessageListener);
socket.addEventListener('close', socketCloseListener);
};
socketCloseListener();
// for testing
setTimeout(()=>{
socket.close();
},5000);
我有同样的问题和解决方案的工作非常出色。感谢名单! – 2011-12-01 13:50:00
你应该在这里使用一个匿名函数:'function(){start(websocketServerLocation)}'而不是一个字符串,所以你不会触发'eval()' – 2012-06-22 20:15:08
我希望有更优雅的方式,而不需要构造一个新的对象并定义事件动作... – ciembor 2013-02-10 23:05:27