Używam gniazda sieciowego przy użyciu PHP5 i przeglądarki Chrome jako klienta. Pobrałem kod ze strony http://code.google.com/p/phpwebsocket/ .
Uruchamiam serwer, a klient też jest podłączony. Ja też mogę rozmawiać. Teraz, kiedy ponownie uruchamiam serwer (zabijając go i uruchamiając ponownie), klient otrzymuje rozłączone informacje, ale automatycznie nie łączy się ponownie z serwerem, gdy wysyłam wiadomość.
Jak to osiągnąć? Na przykład, kiedy dostaję odłączone informacje, czy powinienem je sprawdzić i wysłać do JavaScript w celu odświeżenia strony lub ponownego połączenia?
źródło
start
rekurencyjnie, bez powrotu.Rozwiązanie podane przez Andrzeja nie działa idealnie, ponieważ w przypadku utraty połączenia serwer może wysłać kilka bliskich zdarzeń.
W takim przypadku ustawisz kilka setTimout. Rozwiązanie podane przez Andrzeja może działać tylko wtedy, gdy serwer będzie gotowy przed upływem pięciu sekund.
Następnie, w oparciu o rozwiązanie Andrew, przerobione, skorzystałem z setInterval dołączając identyfikator do obiektu okna (dzięki czemu jest on dostępny „wszędzie”):
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 */ /* ... */ }
źródło
setTimeout
jeśli zastosujesz do nich ideę "globalnego identyfikatora timera";)onclose
zdarzenie zostanie uruchomione ponownie.ReconnectingWebSocket
GitHub hostuje małą bibliotekę JavaScript, która zdobi interfejs API WebSocket, aby zapewnić połączenie WebSocket, które automatycznie nawiąże połączenie, jeśli połączenie zostanie porzucone.
Zminimalizowana biblioteka z kompresją gzip ma mniej niż 600 bajtów.
Oficjalne repozytorium jest dostępne tutaj:
https://github.com/joewalnes/reconnecting-websocket
Powódź serwera
Jeśli duża liczba klientów jest połączona z serwerem podczas ponownego uruchamiania. Warto zarządzać czasami ponownego łączenia klientów przy użyciu algorytmu wykładniczego wycofywania.
Algorytm działa w ten sposób:
Odniesienie:
http://blog.johnryding.com/post/78544969349/how-to-reconnect-web-sockets-in-a-realtime-web-app
źródło
Używam tego wzoru od jakiegoś czasu dla czystego waniliowego JavaScript i obsługuje on o kilka więcej przypadków niż inne odpowiedzi.
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); });
Spowoduje to ponowienie próby, gdy tylko serwer zamknie połączenie, a także sprawdzi połączenie, aby upewnić się, że jest aktywne również co 5 sekund.
Więc jeśli serwer nie działa, gdy to działa lub w czasie zdarzenia onclose, połączenie zostanie przywrócone, gdy znów będzie online.
UWAGA: Korzystanie z tego skryptu nigdy nie pozwoli Ci przestać próbować otworzyć połączenia ... ale myślę, że tego właśnie chcesz?
źródło
Poniżej znajdują się kody, których użyłem w swoim projekcie, które działają w 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(); }; }
źródło
Nie można komentować, ale następujące kwestie:
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);
Plus https://www.npmjs.com/package/back jest już wystarczająco dobry :)
źródło
function wsConnection(url){ var ws = new WebSocket(url); var s = (l)=>console.log(l); ws.onopen = m=>s(" CONNECTED") ws.onmessage = m=>s(" RECEIVED: "+JSON.parse(m.data)) ws.onerror = e=>s(" ERROR") ws.onclose = e=>{ s(" CONNECTION CLOSED"); setTimeout((function() { var ws2 = new WebSocket(ws.url); ws2.onopen=ws.onopen; ws2.onmessage = ws.onmessage; ws2.onclose = ws.onclose; ws2.onerror = ws.onerror; ws = ws2 } ).bind(this), 5000) } var f = m=>ws.send(JSON.stringify(m)) || "Sent: "+m; f.ping = ()=>ws.send(JSON.stringify("ping")); f.close = ()=>ws.close(); return f } c=new wsConnection('wss://echo.websocket.org'); setTimeout(()=>c("Hello world...orld...orld..orld...d"),5000); setTimeout(()=>c.close(),10000); setTimeout(()=>c("I am still alive!"),20000);
<pre> This code will create a websocket which will reconnect automatically after 5 seconds from disconnection. An automatic disconnection is simulated after 10 seconds.
źródło
Na koniec wykonuję automatyczne ponowne łączenie ws w vue + ts, podobnie jak poniżej:
private async mounted() { // Connect to WebSocket const sn = "sb1234567890"; const host = window.location.protocol == "https:" ? "wss://www.xxx.net" : process.env.DEV_TYPE === "fullstack" ? "ws://10.0.0.14:8528" : "ws://www.xxx.net:8528"; const wsUri = host + "/feed-home/" + sn; await this.startWs(wsUri, sn); // !!!Deprecated: failed to reconnect // let ws = new WebSocket(); // console.log(ws); // ws.onopen = async function(event) { // console.log(event, "openEvent"); // clearInterval(that.timer); // }; // ws.onclose = async function(event) { // console.log(event, "close"); // that.timer = setInterval(() => { // console.log("Heart Beat"); // ws.send("HeartBeat"); // // ws = new WebSocket("ws://10.0.0.14:8528/feed-home/" + sn); // console.log(ws); // }, 60000); // }; // ws.onmessage = async function(event) { // console.log(event, "ws"); // alert("get it!"); // await alert("please update!"); // await that.getHome(sn); // }; } private wsReconnected: boolean = false; // check whether WebSocket is reconnected private async startWs(uri: string, sn: string) { let that = this; let ws = new WebSocket(uri); ws.onopen = async () => { if (that.wsReconnected) { await that.getHome(sn); // Refresh api data after reconnected } ws.send("Current client version: " + window.version); }; ws.onmessage = async evt => { await that.getHome(sn); that.$message({ type: "success", message: evt.data, showClose: true, center: true, duration: 20 * 1000 }); }; ws.onclose = async () => { that.wsReconnected = true; await that.startWs(uri, sn); const sleep = (seconds: number) => { return new Promise(resolve => setTimeout(resolve, seconds * 1000) ); }; await sleep(10); // Try to reconnect in 10 seconds // !!!Deprecated: Use timer will cause multiply ws connections // if (!that.wsTimer) { // // Try to reconnect in 10 seconds // that.wsTimer = setInterval(async () => { // console.log("reconnecting websocket..."); // await that.startWs(uri, sn); // }, 10 * 1000); // } }; }
źródło
Zdarzenie zamknięcia po stronie klienta dla WebSocket ma właściwość wasClean , która była dla mnie przydatna. Wygląda na to, że jest ustawiona na true w przypadkach, gdy komputer kliencki przechodzi w tryb uśpienia itp. Lub gdy serwer jest nieoczekiwanie zatrzymany itp. Jest ustawiona na false, jeśli ręcznie zamkniesz gniazdo, w którym to przypadku nie chcesz otwierać gniazdo ponownie automatycznie. Poniżej kod z projektu Angular 7. Mam ten kod w usłudze, więc można go używać z dowolnego komponentu.
notifySocketClose(event) { if (!event.wasClean) { setTimeout(() => { this.setupSocket() }, 1000); } } setupSocket() { // my function to handle opening of socket, event binding etc. ..... ..... this.websocketConnection = this.websocketConnection ? this.websocketConnection : new WebSocket(socketUrl); this.websocketConnection.onclose = this.notifySocketClose.bind(this); } } ..... .....
źródło