Socket.io: Pengecualian JS dilemparkan saat hanya diam (WebSocket sudah dalam status TUTUP atau TUTUP.)

Dibuat pada 26 Mei 2018  ·  55Komentar  ·  Sumber: socketio/socket.io

Yang kamu ingin:

  • [x] laporkan bug
  • [ ] meminta fitur

Perilaku saat ini

Saat membiarkan soket terhubung, tetapi tidak melakukan aktivitas lain dalam program saya, saya melihat sesekali (tetapi cukup konsisten) pengecualian yang dilemparkan ke konsol browser, dari dalam mesin socket.io (khususnya di backo2/index.js baris 83. Kesalahan itu adalah:

WebSocket is already in CLOSING or CLOSED state.

socket-io-errors

Langkah-langkah untuk mereproduksi (jika perilaku saat ini adalah bug)

Saya memiliki dua tab terbuka dengan soket klien yang terhubung ke server yang sama (localhost) melalui https. Kedua klien duduk diam tanpa ada hal lain yang terjadi di browser atau server (kecuali untuk apa pun yang dilakukan socket.io ping keep-alive). Keduanya bergabung ke satu saluran (melalui join(..) di server). Jika tidak, tidak ada yang istimewa.

Inilah cara saya membuat instance soket server:

var httpsServer = https.createServer(..);
var io = require("socket.io")(httpsServer);
io.on("connection",onSocketConnection);

Dan di klien:

socket = io();
socket.on("connect",function(){
   console.log("socket connected");
});
socket.on("disconnect",function(){
   console.log("socket disconnected");
});

Perilaku yang diharapkan

Saya mengharapkan pemutusan dan koneksi ulang dari waktu ke waktu, tetapi saya tidak mengharapkan pengecualian JS palsu yang dilemparkan oleh perpustakaan ketika saya tidak melakukan hal lain melalui koneksi.

Mempersiapkan

  • OS: Mac OSX
  • browser: Chrome 66, simpul 10.2.1
  • versi socket.io: 2.1.1

Informasi lain (mis. stacktrace, masalah terkait, saran cara memperbaikinya)

Jejak tumpukan yang diperluas:

index.js:83 WebSocket is already in CLOSING or CLOSED state.
(anonymous) @ index.js:83
e.encodePacket @ index.js:83
(anonymous) @ index.js:83
r.write @ index.js:83
r.send @ index.js:83
r.flush @ index.js:83
r.sendPacket @ index.js:83
r.ping @ index.js:83
(anonymous) @ index.js:83
setTimeout (async)
r.setPing @ index.js:83
r.onPacket @ index.js:83
(anonymous) @ index.js:83
r.emit @ index.js:83
r.onPacket @ index.js:83
r.onData @ index.js:83
ws.onmessage @ index.js:83

Komentar yang paling membantu

Ada perubahan untuk pingTimeout default dari 60000(v2.0.4) menjadi 5000 (v2.1.0+) yang tidak cukup untuk beberapa browser seperti Chrome.

Solusi untuk masalah ini pada v2.1.0+ termasuk v2.2.0 terbaru adalah dengan mengganti pingTimeout default di server Anda ke nilai yang besar sebagai berikut:

const http = require('http');
const server = http.createServer();
const io = require('socket.io')(server, {
  pingTimeout: 60000,
});

ATAU

const io = require('socket.io')();
const http = require('http');
const server = http.createServer();
io.attach(server, {
  pingTimeout: 60000,
});

Semua 55 komentar

Mengalami masalah yang sama dan kodenya benar. Ini hanya terjadi di Chrome untuk saya. Mozilla bersih. Di chrome, kesalahan ini menghujani dan menduplikasi semua obrolan yang saya miliki. Saya mencoba menggunakan metode ini
socket.on('disconnect', () =>{ socket.disconnect(); });
Itu tidak memutuskan klien dari server. Repo jika diperlukan https://github.com/antoniab123456/Chat_app

masalah yang sama di sini
image

browser hanya idling, lalu muncul error.

Saya menggunakan Chrome dan mac OS

Ya teman-teman, ada yang bisa mengatasinya? Mungkin kita perlu baris kode lain untuk memperbaikinya?

Saya memiliki masalah yang sama dengan socket.io dan Chrome
MacOS 10.13.5
Chrome Versi 67.0.3396.87 (Builan Resmi) (64-bit)
Node: 10.3.0
Ekspres: 4.16.3
socket.io: 2.1.1

Di Firefox semuanya baik-baik saja.

Detail kesalahan di bawah ini:

index.js:83 WebSocket is already in CLOSING or CLOSED state.
(anonymous) | @ | index.js:83
  | e.encodePacket | @ | index.js:83
  | (anonymous) | @ | index.js:83
  | r.write | @ | index.js:83
  | r.send | @ | index.js:83
  | r.flush | @ | index.js:83
  | r.sendPacket | @ | index.js:83
  | r.ping | @ | index.js:83
  | (anonymous) | @ | index.js:83
  | setTimeout (async) |   |  
  | r.setPing | @ | index.js:83
  | r.onPacket | @ | index.js:83
  | (anonymous) | @ | index.js:83
  | r.emit | @ | index.js:83
  | r.onPacket | @ | index.js:83
  | r.onData | @ | index.js:83
  | ws.onmessage | @ | index.js:83

Ketika saya mengklik index.js:83 saya dibawa ke modul ini:

/**
 * Expose `Backoff`.
 */

module.exports = Backoff;

/**
 * Initialize backoff timer with `opts`.
 *
 * - `min` initial timeout in milliseconds [100]
 * - `max` max timeout [10000]
 * - `jitter` [0]
 * - `factor` [2]
 *
 * <strong i="16">@param</strong> {Object} opts
 * <strong i="17">@api</strong> public
 */

function Backoff(opts) {
  opts = opts || {};
  this.ms = opts.min || 100;
  this.max = opts.max || 10000;
  this.factor = opts.factor || 2;
  this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
  this.attempts = 0;
}

/**
 * Return the backoff duration.
 *
 * <strong i="18">@return</strong> {Number}
 * <strong i="19">@api</strong> public
 */

Backoff.prototype.duration = function(){
  var ms = this.ms * Math.pow(this.factor, this.attempts++);
  if (this.jitter) {
    var rand =  Math.random();
    var deviation = Math.floor(rand * this.jitter * ms);
    ms = (Math.floor(rand * 10) & 1) == 0  ? ms - deviation : ms + deviation;
  }
  return Math.min(ms, this.max) | 0;
};

/**
 * Reset the number of attempts.
 *
 * <strong i="20">@api</strong> public
 */

Backoff.prototype.reset = function(){
  this.attempts = 0;
};

/**
 * Set the minimum duration
 *
 * <strong i="21">@api</strong> public
 */

Backoff.prototype.setMin = function(min){
  this.ms = min;
};

/**
 * Set the maximum duration
 *
 * <strong i="22">@api</strong> public
 */

Backoff.prototype.setMax = function(max){
  this.max = max;
};

/**
 * Set the jitter
 *
 * <strong i="23">@api</strong> public
 */

Backoff.prototype.setJitter = function(jitter){
  this.jitter = jitter;
};




//////////////////
// WEBPACK FOOTER
// ./~/backo2/index.js
// module id = 41
// module chunks = 0

Baris 83 adalah:

this.jitter = jitter;

Saya memiliki masalah yang sama, dengan backo2.js dan pada baris 83. inilah kesalahan saya:
index.js:83 Uncaught TypeError: Gagal mengeksekusi 'readAsArrayBuffer' di 'FileReader': parameter 1 bukan tipe 'Blob'.
di n (index.js:83)
di n (index.js:83)
di n (index.js:83)
di n (index.js:83)
di n (index.js:83)
di n (index.js:83)
di Object.e.removeBlobs (index.js:83)
di s (index.js:83)
di r.encode (index.js:83)
di r.packet (index.js:83)
dan jangan khawatir tentang hal-hal lain, semuanya ada di baris 83, yaitu this.jitter = jitter;
Ini sangat mengganggu saya karena tidak ada solusi di google.

Adakah yang menemukan solusi sementara? @antoniab123456 apakah Anda dapat memperbaiki aplikasi obrolan Anda sehingga tidak menduplikasi obrolan Anda? Itu melakukan hal yang sama padaku.

Mempersiapkan
OS: Mac OSX
Browser: Chrome 67.0.3396.99 (Builan Resmi) (64-bit)
Simpul v10.5.0
Socket.io v2.1.1

Saya menghadapi masalah persis @getify yang disebutkan di chrome. Adakah yang menemukan pekerjaan untuk ini?

Permasalahan yang sama. Dapatkah seseorang tolong menanggapi ini?

Permasalahan yang sama.

Mempersiapkan
OS: Mac OSX
browser: Chrome 67.0.3396.99 (Builan Resmi) (64-bit), Node 9.6.1
versi socket.io: 2.1.1

@19smitgr idk apa yang Anda maksud dengan 'duplikat obrolan' yang terdengar di luar topik yang dapat diselesaikan dengan menyiarkan sebagai gantinya jika yang Anda maksud adalah 'pesan duplikat di layar yang sama'.

@kino2007 Saya tidak membuat aplikasi obrolan. Saya sebenarnya menggunakan soket web dengan permainan multipemain, dan soket web tidak menerima pesan pemutusan, jadi ketika pengguna terputus dan terhubung kembali karena kesalahan acak yang dibicarakan semua orang, itu akan memberi karakter ID soket baru, dan sprite lama dengan ID soket lama tidak dihapus karena hanya mendapatkan pesan "transport close" alih-alih pesan "disconnect".

Pada titik ini, bahkan jika saya mendapatkan pesan "transport close", saya hanya menghapus pengguna dari daftar pengguna saat ini dengan cara yang sama seperti jika saya mendapat pesan "disconnect".

Kesalahan yang sama di sini

Setelah pencarian cepat saya menemukan bahwa backo2 menyebabkan kesalahan.

Kemudian saya menggunakan versi dev socket.io dan menemukan bahwa Socket.prototype.onevent melempar kesalahan.

Saya memperbaikinya untuk saya:

Sebelumnya saya menggunakan ini:

socket.on('ping', alert);

Tapi kemudian saya mengubahnya menjadi ini:

socket.on('ping', msg => {
    alert(msg);
});

Dan itu berhasil!

Saya mempunyai masalah yang sama. Ada pembaruan tentang ini?

Sama disini.

socket.io & socket.io-client: "^2.1.1"
MacOS
Google Chrome sudah diperbarui
Versi 68.0.3440.106 (Builan Resmi) (64-bit)

Saya mengalami masalah yang sama. Juga, ini menduplikasi pesan yang saya kirim dari server ke klien.

screen shot 2018-08-30 at 4 51 49 pm

MacOS: 10.13.6
Socket.io: "^2.1.1"
Chrome: 68.0.3440.106

@abhyuditjain Anda dapat mencoba mengatur ulang semua pendengar menggunakan socket.removeAllListeners(); untuk menghindari beberapa pendaftaran pendengar yang dapat menyebabkan duplikasi pesan.

Ini tampaknya menjadi masalah yang berkelanjutan bagi beberapa orang dan belum ada solusi untuk ini. Ada update dari siapa saja?

@vkotu Jika saya menghapus semua pendengar, maka soket tidak terhubung kembali ke server saat diputuskan. Adakah cara untuk memperbaikinya?

cukup gunakan websocket- node, mudah digunakan dan berfungsi tanpa kesalahan apa pun dan ditambah lagi Anda tidak memerlukan perpustakaan eksternal untuk itu:
https://codeburst.io/why-you-don-t-need-socket-io-6848f1c871cd
https://medium.com/@martin.sikora/node -js-websocket-simple-chat-tutorial-2def3a841b61
https://www.npmjs.com/package/websocket

bukan iklan, hanya membantu, kecuali jika Anda memiliki keputusan untuk kesalahan ini :DDD sudah berlangsung selama berbulan-bulan05.09.2018, 13:15, "Abyudit Jain" [email protected] :@antoniab123456 Halaman ini untuk memposting masalah tentang ini gudang. Mohon jangan beriklan di sini.

—Anda menerima ini karena Anda disebutkan. Balas email ini secara langsung, lihat di GitHub, atau matikan utas.

-- Hormat kami, Antonia B. Customer Care Specialist @amoCRM Global

Menurunkan versi ke 2.0.3 "memperbaiki" masalah ini untuk saya.

@cozuya akan mengujinya. Akan memberi tahu Anda jika berhasil!

Menurunkan versi ke 2.0.3 "memperbaiki" masalah ini untuk saya.

tampaknya melakukan trik. Diuji selama 4 menit dan tidak ada kesalahan. Mari kita lihat berapa lama itu bertahan!

@cozuya terima kasih telah memposting ini!

Kesalahan yang sama di 2.1.1

Menurunkan versi ke 2.0.3 "memperbaiki" masalah ini untuk saya.

2.0.3 bekerja untuk saya! Terima kasih @cozuya

2.1.1 masih menghadapi masalah yang sama. Mencoba meningkatkan ping dan batas waktu tetapi tidak ada yang berubah

mengalami masalah yang sama di chrome dengan v2.1.1, saat browser tidak aktif untuk waktu yang lama (sekitar 20-30 menit)

2.1.1 masih menghadapi masalah yang sama. Mencoba meningkatkan ping dan batas waktu tetapi tidak ada yang berubah

turunkan ke v 2.0.3

Saya telah mencoba menggunakan socket.io dengan 2.0.4, terlihat normal.

Saya telah menemukan ada perubahan untuk pingTimeout dari 60000(v2.0.4) menjadi 5000 (v2.1.1)

Jika saya telah mengubah pingTimeout ke angka yang lebih besar seperti 10.000, sepertinya berhasil.

Saya kira itu mungkin terkait dengan browser yang tidak aktif di mana tab yang tidak aktif akan memiliki beberapa throttle.

Saya memiliki beberapa masalah. Apakah seseorang memecahkan masalah?

Saya harus menurunkan versi juga. Itu tidak berfungsi untuk chrome dan safari

Masalah yang sama disini. Chrome di bawah OSX.

Saya mengatasinya tidak menggunakan socket.removeAllListeners(); tetapi socket.off("whatever") untuk semua pendengar non-teknis saya selain "disconnect" dan seterusnya. Bekerja dengan baik. Pesan kesalahan di konsol browser mengganggu tetapi tidak layak untuk saya turunkan.

Saya harus mengatakan itu mengecewakan untuk melihat masalah ini tanpa perhatian apapun. Ini enam bulan dan terus bertambah.

Jadi alasan untuk menyambung kembali adalah waktu ping untuk saya. Bahkan dengan downgrade saya masih mendapatkan kesalahan.

Saya sepenuhnya setuju dengan perpustakaan yang sangat besar dengan basis kode yang luas namun tidak memperhatikan masalah ini!

Semoga seseorang segera mendapatkannya!

dikirim dari iPhone saya

Pada 28 November 2018, pukul 14:14, HorseBadorties [email protected] menulis:

Masalah yang sama disini. Chrome di bawah OSX.

Saya mengatasinya tidak menggunakan socket.removeAllListeners(); tapi socket.off("whatever") untuk semua pendengar non-teknis saya selain "disconnect" dan sebagainya. Bekerja dengan baik. Pesan kesalahan di konsol browser mengganggu tetapi tidak layak untuk saya turunkan.

Saya harus mengatakan itu mengecewakan untuk melihat masalah ini tanpa perhatian apapun. Ini enam bulan dan terus bertambah.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub, atau matikan utasnya.

Masalah yang sama .... terkejut belum ada perbaikan untuk ini.

Saya telah mengalami masalah ini. Dalam kasus saya pemutusan itu karena ping timeout . Namun, tidak beruntung mengapa sisi klien berhenti merespons ping.

io.on('connection', function(socket) {
  socket.on('disconnect', function(reason) {
  console.log(`Socket disconnected for: ${reason}`);
  }
});

https://socket.io/docs/server-api/#Event -%E2%80%98disconnect%E2%80%99 memiliki daftar alasan pemutusan.

Lebih Debug:
image
Satu pengamatan adalah bahwa acara ping pada klien adalah +30s dari yang terakhir. Setiap kali saya melihat pemutusan, itu adalah 30s+ yang merupakan interval detak jantung default + batas waktu ping. +26s , +28s , dan +29s muncul tanpa terputus.
Saat membandingkan dengan Safari, Safari lebih konsisten dalam melakukan ping setiap 25s dan tidak melihat adanya pemutusan.

Ada perubahan untuk pingTimeout default dari 60000(v2.0.4) menjadi 5000 (v2.1.0+) yang tidak cukup untuk beberapa browser seperti Chrome.

Solusi untuk masalah ini pada v2.1.0+ termasuk v2.2.0 terbaru adalah dengan mengganti pingTimeout default di server Anda ke nilai yang besar sebagai berikut:

const http = require('http');
const server = http.createServer();
const io = require('socket.io')(server, {
  pingTimeout: 60000,
});

ATAU

const io = require('socket.io')();
const http = require('http');
const server = http.createServer();
io.attach(server, {
  pingTimeout: 60000,
});

Mengapa 5000 tidak cukup? Saya melihat masalah ini di server dev lokal saya, dan latensi antara klien dan server pasti di bawah ambang batas itu. 5000ms sepertinya batas waktu yang masuk akal. Baunya seperti mungkin ada masalah dengan sistem ping-pong itu sendiri, dan itu hanya muncul ketika diturunkan.

Terima kasih telah memulai utas ini @getify (saya menggunakan socket.io v2.2.0)

Kepada siapa pun yang juga mengalami ini - SAYA TERLALU KOMENTAR JANGAN MEMBANTU :-) silakan pilih masalah ini dengan jempol untuk menunjukkan dukungan Anda 👍

Terima kasih @omardoma untuk menemukan pingTimeout dan saya setuju dengan @LunarMist bahwa kita harus menyelidiki sistem acara ping/pong .

Saya melakukan beberapa pengujian awal dengan Chrome, Firefox, & Safari (semuanya di MacOS).

Chrome & Safari keduanya tampaknya membatasi aktivitas dengan perilaku & batasan yang berbeda:

  • Chrome, setelah ~5 menit tidak aktif saat tab difokuskan atau segera saat tab masuk ke latar belakang. Ini disengaja oleh tim chromium (https://developers.google.com/web/updates/2017/03/background_tabs)
  • Safari, segera saat fokus aplikasi diubah ke aplikasi desktop lain (MacOS) atau saat tab masuk ke latar belakang. Terkait dengan #2924
  • Firefox, *tidak pernah ada masalah yang disebutkan di utas ini

Solusi

Saya menguji selama beberapa jam dengan ketiga browser ini, mengubah nilai pingTimeout & pingInterval . Apa yang saya temukan sebagai solusi:

  1. Menyetel pingTimeout >= 30000 ms

    • atau -

  2. Menyetel pingInterval <= 10000 ms

Saya percaya solusi terbaik untuk mengubah pingTimeout = 30000 . Default pingInterval adalah 25000 md dan meningkatkan frekuensi klien melakukan ping ke server setiap 10 detik dapat menjadi terlalu cerewet untuk proyek _pada skala_.


Apakah @darrachequesne atau anggota repo lainnya mendukung peningkatan default pingTimeout menjadi 30000 dari default saat ini 5000 ms yang diubah di v2.1 dari 60000 ms?

Bereaksi terhadap komentar Anda sendiri juga tidak membantu.

Klien adalah yang melakukan ping ke server dan bukan sebaliknya.

Saya pikir itu karena versi socket.io saat ini bergantung pada setTimeout di sisi klien, yang mungkin tidak dapat diandalkan seperti yang diharapkan.

Saya pikir meningkatkan pingTimeout untuk sementara akan memperbaiki masalah, tetapi kami akan menggunakan ping/pong dari server -> klien (bukan klien saat ini -> server) di v3.

Cukup gunakan kode berikut di ujung klien.

_socket.on('ping', () => {
socket.emit(data);
});_

Terima kasih @crobinson42! Solusi batas waktu ping bekerja sangat baik untuk saya. Saya hanya memiliki beberapa kekhawatiran tentang solusi itu. Jika Anda kehilangan koneksi internet kapan saja, dibutuhkan waktu hingga 30 detik untuk memicu peristiwa pemutusan dan untuk beberapa aplikasi, itu terlalu banyak. misalnya aplikasi obrolan yang ingin menonaktifkan input teks saat pengguna tidak terhubung.

Dalam hal ini, menambah interval ping akan berhasil, tetapi seperti yang Anda katakan, biayanya tinggi, apakah ada solusi untuk ini?

Harap beri tahu kami setelah ini diperbaiki, masalah yang sama untuk saya, versi saya r di bawah ini:

"socket.io": "2.2.0",
"socket.io-adapter": "~1.1.1",
"socket.io-client": "2.2.0",
"socket.io-parser": "~3.2.0",
"socket.io-redis": "^5.2.0",

Kode saya:
pelayan, {
jalur: '/socket.io',
serveClient: benar,
// di bawah ini adalah opsi engine.IO
pingInterval: 40000
pingWaktu habis: 25000,
upgradeTimeout: 30000, // nilai default adalah 10000ms, coba ubah ke 20k atau lebih
agen: palsu,
kue: palsu,
tolakTidak sah: salah,
rekoneksiDelay: 1000,
rekoneksiDelayMaks: 5000
}

klien saya:

rekoneksi: benar,
rekoneksiDelay: 1000,
rekoneksiDelayMax: 5000,
upaya penyambungan kembali: Tak terhingga,
//opsi situs kami
mengangkut: ["polling", "websocket"],
aman: benar,
tolakTidak sah: salah,
forceNew: benar,
batas waktu: 60000

Halo Faizan,
Anda dapat Menjalankan Kode ini sebagai -
** Saya telah Menggunakan Versi yang Sama seperti yang Diberikan Oleh Anda..

Sisi Server - Kode :

const server = membutuhkan('http').createServer();
const io = membutuhkan('socket.io')(server, {
// jalur: '/socket.io',
serveClient: benar,

pingInterval: 40000,
pingTimeout: 25000,
upgradeTimeout: 21000, // default value is 10000ms, try changing it to 20k or more
agent: false,
cookie: false,
rejectUnauthorized: false,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000

});

io.on('koneksi', fungsi(soket) {
socket.emit('selamat datang', { pesan: 'Selamat datang!', id: socket.id });
socket.on('Sunil', console.log);
});

server.listen(3000);

Kode Sisi Klien:

var klien = membutuhkan("socket.io-klien");
var socket = client.connect("http://localhost:3000", {
rekoneksi: benar,
rekoneksiDelay: 1000,
rekoneksiDelayMax: 5000,
upaya penyambungan kembali: Tak terhingga,
mengangkut: ["websocket"],
aman: palsu,
tolakTidak sah: salah,
forceNew: benar,
batas waktu: 6000
});

soket.koneksi();
socket.emit('Matahari', {
data: 'Halo'
});
socket.on('selamat datang', fungsi (data) {
konsol.log(data)
socket.emit('Matahari', {
data: 'Faizan',
id: data.id
});

socket.disconnect();

});

Salam
Sunil Yadav

Pada 09-Mei-2019, pukul 16.05, Faizan Zahid [email protected] menulis:

rekoneksi: benar,
rekoneksiDelay: 1000,
rekoneksiDelayMax: 5000,
upaya penyambungan kembali: Tak terhingga,
//opsi situs kami
mengangkut: ["polling", "websocket"],
aman: benar,
tolakTidak sah: salah,
forceNew: benar,
batas waktu: 60000

Mungkin solusi di sisi klien jika ada yang tertarik sampai masalah diperbaiki. Ini akan menyebabkan browser tidak mengosongkan memori dan dapat menyebabkan penggunaan memori yang berlebihan.

  • Seperti yang tercantum di sini, https://apple.stackexchange.com/questions/344183/safari-12-mac-does-includeinternaldebugmenu-1-still-work , pertama-tama berikan aplikasi Terminal akses disk penuh secara lokal dan mulai ulang terminal.
  • Buka jendela terminal, dan rekatkan dan jalankan perintah defaults write com.apple.Safari IncludeInternalDebugMenu 1
  • Mulai ulang Safari. Anda akan melihat menu Debug baru di kanan atas.
  • Di bawah Debug-> Miscellaneous Flags, aktifkan dua flag "Disable App Nap" dan "Disable Hidden Page Timer Throttling" dan restart Safari.

Jika ada yang punya solusi Chrome, itu akan membantu

Anda menggunakan Safari untuk webdev localhost? 🤔.

Anda menggunakan Safari untuk webdev localhost? 🤔.

Tidak juga, tetapi itu mengganggu dengan pemutusan konstan untuk menguji aplikasi saya. Ini memberikan solusi sementara hingga diperbaiki di 3.0. Ini bukan solusi. Saya memposting jika itu akan membantu seseorang selama dev.

Saya menggunakan pingInterval dan pingTimeouts yang sangat rendah untuk mendapatkan perubahan status offline waktu nyata, menyetelnya ke 30 detik akan menghentikan aliran saya ... adakah yang tahu cara untuk mengatasi masalah ini sehingga saya dapat menggunakan 'perbaikan' waktu tunggu yang lama untuk browser latar belakang tab?

Ada pembaruan tentang ini?

Saya menggunakan pingInterval dan pingTimeouts yang sangat rendah untuk mendapatkan perubahan status offline waktu nyata, menyetelnya ke 30 detik akan menghentikan aliran saya ... adakah yang tahu cara untuk mengatasi masalah ini sehingga saya dapat menggunakan 'perbaikan' waktu tunggu yang lama untuk browser latar belakang tab?

Anda harus memutuskan peristiwa pada soket untuk menangani kehadiran, ketika soket terputus, temukan pengguna dan tandai mereka sebagai offline di penyimpanan data Anda

Berikut adalah default dari dokumentasi. Sepertinya ping dikirim setiap 25 detik dan setiap ping memiliki 5 detik untuk diselesaikan.

pingWaktu habis | 5000 | berapa ms tanpa paket pong untuk mempertimbangkan koneksi tertutup
-- | -- | --
pingInterval | 25000 | berapa ms sebelum mengirim paket ping baru

Saya melihat kesalahan yang sama tetapi dalam konteks yang berbeda jadi saya akan menulis cepat dengan masalah dan solusi saya untuk orang lain yang berakhir di sini.

Skenario saya ada di Chrome untuk Android di mana koneksi terputus setelah mengunci layar.

Saya menggunakan token untuk mengidentifikasi pengguna yang sama di berbagai koneksi, yang saya kirim dari klien saat terhubung menggunakan pendekatan opsi kueri dan saya memperbarui token dengan yang baru diterima dari server:

// client
io('myAppUrl', {
  query: {
    token: localStorage.getItem('myKey') || ''
  }
});

io.on('reconnect_attempt', () => {
  io.opts.query = {
    token: localStorage.getItem('myKey') || ''
  };
});

io.on('my_custom_connection_successful_event', (token) => {
  localStorage.setItem('myKey', token);
});

Masalahnya adalah klien Chrome untuk Android akan mengirim token string kosong ke server saat tersambung kembali. Yang tidak saya harapkan karena saya menambahkan pendengar 'reconnect_attempt' yang memastikan untuk mengatur token terbaru dari localStorage .

Setelah beberapa jam melakukan debug dengan konsol yang mencatat semua kemungkinan acara klien, saya menyadari bahwa acara 'reconnect_attempt' tidak diaktifkan sama sekali dalam skenario saya untuk menghubungkan kembali. Setelah membuka kunci layar, saya mendapatkan urutan acara berikut:

  • putuskan sambungan (alasan: 'transportasi tutup')
  • menghubungkan kembali (usaha: 1)
  • sambungkan kembali
  • ping/pong dimulai lagi

Jadi tidak ada acara 'reconnect_attempt' yang diaktifkan yang menjelaskan mengapa token masih berupa string kosong (nilai awal ditetapkan saat terhubung).

Singkat cerita, solusi bagi saya adalah segera memperbarui variabel instan io.opts.query pada acara "koneksi berhasil" kustom saya yang diterima dari server dengan token baru:

// client
io('myAppUrl', {
  query: {
    token: localStorage.getItem('myKey') || ''
  }
});

io.on('my_custom_connection_successful_event', (token) => {
  localStorage.setItem('myKey', token);
  io.opts.query = {
    token: token
  };
});

Sekarang saya mengerti bahwa io.opts.query adalah variabel instan yang digunakan pada koneksi dan semua koneksi ulang berikutnya, jadi saya dapat memperbaruinya segera setelah saya mau. Saya tidak perlu menunggu acara terkait penyambungan kembali.

Saya merasa sedikit disesatkan oleh dokumen Dengan opsi kueri . Mungkin saya salah memahami use case dalam contoh itu? Tetapi jika mirip dengan kasus penggunaan saya, alih-alih contoh 'reconnect_attempt' , dokumen dapat menjelaskan bahwa io.opts.query adalah variabel instan yang dapat dimutasi dan nilainya saat ini digunakan pada semua koneksi ulang berikutnya. Jadi itu dapat diubah kapan pun Anda ingin menyegarkan token, bahkan pada acara khusus 'refresh_token' misalnya. Saya bisa mengerjakan PR jika menurut Anda itu ide yang bagus untuk meningkatkan dokumen.

Sunting:
Setelah penyelidikan lebih lanjut saya menyadari kesalahan saya adalah bahwa pendengar 'reconnect_attempt' telah dihapus dari bagian lain dari kode saya... :man_facepalming: Itu sebabnya saya tidak melihatnya di logging saya. Jadi ya, urutan kejadian untuk skenario koneksi ulang saya sebenarnya adalah:

  • putuskan sambungan (alasan: 'transportasi tutup')
  • reconnect_attempt (percobaan: 1)
  • menghubungkan kembali (usaha: 1)
  • sambungkan kembali
  • ping/pong dimulai lagi

Namun, kesadaran saya bahwa io.opts.query dapat diubah kapan pun Anda mau masih valid. :keringat_senyum:

Apakah masih baik-baik saja untuk menurunkan versi? Saya mengaktifkan 2.0.3 tetapi sepertinya tidak berhasil.

Halo, saya menghadapi masalah yang sama tetapi dengan dua kesalahan. Saya mencoba solusi @omardoma . Adakah yang bisa membantu?
Os - Ubuntu 18.04
Simpul - 12.16.2
npm - 6.14.5
socket.io - 2.3.0
kode saya -

app.js

const speech = require('@google-cloud/speech');
const speechClient = new speech.SpeechClient(); // Creates a client
const environmentVars = require('dotenv').config();
const io = require('socket.io')();
const http = require('http');
const server = http.createServer();
io.attach(server, {
  pingTimeout: 60000,
});



console.log(io)



// =========================== SOCKET.IO ================================ //

io.on('connection', function (client) {
  console.log('Client Connected to server');
  let recognizeStream = null;

file ejs

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js" integrity="sha256-bQmrZe4yPnQrLTY+1gYylfNMBuGfnT/HKsCGX+9Xuqo=" crossorigin="anonymous"></script>
<script src="/js/client.js"></script>

file js

const socket = io.connect("http://localhost:8080");

Saya menggunakan socket.io versi 2.3.0. Saya menggunakan koneksi websocket ke klien. Ketika klien saya memiliki peringatan browser (yang sinkron) di UI dan jika pengguna tidak mengabaikan peringatan selama lebih dari 30 detik (pingTimeout + pingInterval), saya melihat pesan 'Websocket sudah dalam status TUTUP atau TUTUP' dan mendapatkan pesan putuskan acara dengan alasan pingTimeout. Saya tidak ingin soket web ini terputus ketika UI memiliki peringatan. Jika saya meningkatkan pingTimeout menjadi 10 menit, pemutusan tidak terjadi selama 10 menit. Tapi dari apa yang saya baca di komentar di atas, ini mungkin berdampak negatif (klien mungkin tidak tahu ada pemutusan sampai 10 menit). Tetapi saya perhatikan bahwa jika ada gangguan jaringan, dll., kami terputus dengan alasan penutupan transportasi. Jadi apakah boleh meningkatkan pingTimeout+pingInterval ini? Apakah ada skenario khusus ketika pemutusan tidak terdeteksi? Atau ada cara lain untuk memperbaiki ini?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat