Socket.io: Safari menjatuhkan koneksi soket web karena tidak aktif saat halaman tidak fokus

Dibuat pada 25 Apr 2017  ·  26Komentar  ·  Sumber: socketio/socket.io

Yang kamu ingin:

  • [x] laporkan bug
  • [] minta fitur

Perilaku saat ini

Tidak yakin apakah ini masalah yang diketahui (saya mencoba mencari tetapi tidak menemukan apa pun). Safari untuk Mac tampaknya menghentikan koneksi websocket secara diam-diam karena tidak aktif / menganggur jika halaman / tab tidak berada dalam fokus.

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

Jadikan tab / halaman Safari tidak fokus; catat acara websocket.

Perilaku yang diharapkan

Websockets harus tetap hidup melalui fungsi heartbeat. Tidak melihat perilaku ini di browser lain jadi tidak mungkin kode saya.

Mendirikan

  • OS: Mac OSX 10.12.4 (16E195)
  • browser: Safari 10.1 (12603.1.30.0.34)
  • versi socket.io: 1.7.3

Informasi lain (misalnya stacktraces, masalah terkait, saran cara memperbaikinya)

Apakah ini mungkin semacam fitur hemat daya yang mengesampingkan / mengabaikan detak jantung?

bug

Komentar yang paling membantu

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

Kami akan menyertakan ini di v3, karena ini adalah perubahan yang dapat merusak.

Terkait: https://github.com/primus/primus/issues/348

Semua 26 komentar

Menjalankan server dengan DEBUG = * menunjukkan hal berikut:
socket.io:client client close with reason ping timeout +0ms
socket.io:socket closing socket - reason ping timeout +0ms

yang saya anggap berarti Safari menutup koneksi, bukan server soket atau contoh klien. Namun yang paling aneh adalah saya perhatikan Safari kadang-kadang menghubungkan kembali sekitar 30 detik hingga 1 menit kemudian tetapi di lain waktu tidak dan tetap terputus sampai halaman dibawa ke fokus. Sangat menyebalkan untuk mencoba dan men-debug dengan perilaku yang tidak konsisten seperti itu.

Tampaknya kadang-kadang terhubung kembali secara sporadis kemudian (seperti 10 menit). Sekali lagi, sama sekali tidak konsisten di bawah lingkungan pengujian yang identik.

@twistedpixel penundaan sumber ), sehingga dapat menjelaskan perilakunya.

Bagaimana dengan memaksa untuk menyambung kembali saat jendela mendapatkan fokus lagi?

window.addEventListener("focus", () => socket.connect());

Ini mungkin terkait dengan https://github.com/primus/primus/issues/348.

Terima kasih atas infonya tetapi masalah utamanya adalah saya perlu soket web terhubung secara permanen karena digunakan untuk mengirim peringatan kepada pengguna saat mereka pergi. Oleh karena itu, fokus jendela untuk menghubungkan kembali tidak ideal.

Saya pikir itu sebenarnya sesuatu yang lebih bermasalah khusus untuk mesin / pemasangan saya. Saya memperhatikan perilaku awalnya di iMac saya, jadi saya memutuskan untuk hanya menghapus MacBook saya dengan versi baru Safari dan saya tidak melihat perilaku di sana sama sekali. Saya membiarkan tab diminimalkan sepanjang hari dan tidak terputus sekali. Oleh karena itu, saya mencoba kembali ke iMac dan menghapus semua plugin internet dan menonaktifkan semua ekstensi tetapi saya masih melihat perilaku ini.

Apple tampaknya tidak menyediakan cara apa pun untuk menginstal ulang Safari sepenuhnya selain menghapus preferensinya dan file tertentu lainnya. Atau menyeka mesin. Sebagian dari diri saya ingin memulai dari awal, tetapi pengembang dalam diri saya akan benci jika tidak mengetahui apa penyebabnya.

Sebenarnya, untuk poin Anda tentang koneksi ulang eksponensial: pasti koneksi ulang pertama akan, seperti yang Anda katakan, sekitar 500ms setelah terputus ... jadi mengapa server mengabaikannya? Pasti ada sesuatu yang mencegahnya mengaktifkan re-connect.

Agak aneh karena jika saya menempelkan socket.connect() dalam acara pemutusan hubungan, itu menghubungkan lagi dengan baik. Itu harus melakukannya setiap beberapa menit tetapi tetap melakukannya tanpa gagal. Jadi saya benar-benar bingung mengapa re-connect tidak terjadi! Saya akan menggali lebih dalam dan melihat apakah saya bisa mencari tahu alasannya.

Sayangnya, ini adalah perilaku browser yang khas saat ini, bahkan di desktop.

Saya rasa saya tahu apa yang terjadi. Safari memang masalahnya.

Saya pikir semua browser membatasi nilai setTimeout dan setInterval pada 1000 saat tab tidak fokus. Safari - bodohnya - membatasi pada 1000 dan melakukan sesuatu seperti menambahkan penundaan secara eksponensial yang menghasilkan setiap iterasi dua kali lipat dari yang terakhir. Inilah mengapa koneksi mati; batas waktu internal socket.io ditunda / dijatuhkan, menjelaskan mengapa menghubungkan kembali tidak terjadi pada saat yang seharusnya.

Jadi pada dasarnya, Apple telah memutuskan untuk melawan arus, seperti biasa, yang mengakibatkan pengalaman pengguna yang buruk. Mereka sangat pandai saat ini.

Saya belum menemukan mengapa itu memengaruhi iMac dan bukan MacBook (saya mengharapkan sebaliknya) tetapi saya akan terus menguji dan melihat apakah saya dapat menunjukkan alasan yang tepat.

@twistedpixel bukan hanya Safari. Lihat http://blog.strml.net/2017/01/chrome-56-now-aggressively-throttles.html

Di Primus kami mengatasi masalah ini dengan membalik arah pesan detak jantung (https://github.com/primus/primus/pull/534).

@lpinca Sepanjang waktu saya mencoba untuk mencari tahu masalah ini, saya bertanya-tanya tentang hal itu. Terimakasih atas infonya! Saya telah melihat Primus tetapi saya tidak ingin memfaktor ulang seluruh basis kode saya secepat ini. Tampaknya itu sepadan dengan usaha.

@twistedpixel maksud saya adalah bahwa hal yang sama mungkin dapat dilakukan di Engine.IO sehingga tidak perlu bermigrasi ke Primus.

FWIW, Safari Tech Preview tampaknya tidak terpengaruh oleh pembatasan tambahan. Mungkin Apple membalikkan keputusan mereka. Ini masih mencekik hingga 1000ms tetapi sepertinya tidak menambahkan apa-apa lebih jauh.

Saya mengalami masalah yang sama di iOS 12 Safari. Jika saya membuka kembali safari saya, koneksi websocket hilang. Apakah ada solusi yang bersih untuk menjaga soket tetap hidup?

AFAIK iOS Safari menangguhkan proses tertentu saat Safari berada di latar belakang (untuk mencegah pengurasan baterai) dan koneksi websocket hampir pasti merupakan salah satu proses tersebut. Kemungkinan Anda tidak akan menemukan solusi di perangkat seluler.

BAIK. Tetapi saya masih dapat menyambung kembali jika saya menambahkan pendengar acara seperti onwindowfocus atau sesuatu?

Adakah yang sudah menerapkan solusi? kami tertarik untuk melihat opsi dan bertanya-tanya apakah orang lain sudah bereksperimen

Daripada menggunakan peristiwa fokus, Anda harus menggunakan API Visibilitas Halaman untuk mendeteksi ketika jendela aplikasi seluler telah di-background.

Saya mengalami masalah dengan Azure SignalR dan terima kasih kepada saran @techpeace yang saat ini menggunakan API Visibilitas Halaman untuk menutup koneksi di halaman, sembunyikan dan sambungkan kembali saat halaman terlihat, tetapi mengalami masalah dengan peralihan tab yang cepat, yang dapat mengirim banyak acara. Saat ini melihat ke dalam debouncing kejadian .. Juga saran umum yang ditemukan di web mencegah segala jenis penanganan berdasarkan deteksi agen pengguna .. jadi solusi saya adalah menggunakan API visibilitas halaman terlepas dari agen pengguna.

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 md

Saya percaya solusi terbaik adalah mengubah pingTimeout = 30000 . Default pingInterval adalah 25000 ms dan meningkatkan frekuensi server melakukan ping ke klien setiap 10 detik bisa jadi terlalu cerewet untuk proyek _at scale_.

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

Kami akan menyertakan ini di v3, karena ini adalah perubahan yang dapat merusak.

Terkait: https://github.com/primus/primus/issues/348

@darrachequesne saya juga menghadapi bahwa ketika di ponsel jika layar ponsel saya dalam keadaan siaga dan saya membuka browser lagi di ponsel, soket io memutus obrolan. tolong perbaiki ini. itu akan sangat melegakan.

ada pembaruan tentang bug ini di soket io?

di aplikasi saya ketika pengguna mencoba mengunggah file dari browser seluler mereka, dan ketika kotak dialog unggah terbuka, soket io memutuskan hubungan mereka jika mereka membutuhkan waktu 15 detik atau lebih untuk memilih file.

jika mereka beralih ke halaman atau tab lain, setelah 15 detik, soket io kembali memutusnya, apakah tetap ada untuk memperbaikinya dan menjaga soket io tetap hidup / terhubung meskipun pengguna tidak pada halaman / dokumen terfokus?

@rachmandiri

Saya telah memperbaiki masalah ini dengan API Visibilitas.

Masalah utama dengan Safari bagi saya - tidak ada waktu untuk menutup soket pada visible.hidden === true, jadi Anda perlu menutup websocket setelah perangkat tidak terkunci, dan memulainya lagi.

@ JustFly1984 Apakah Anda memiliki beberapa kode contoh untuk itu. Saya memiliki deteksi visibilitas yang berfungsi dengan baik, tetapi saya tidak bisa mendapatkan soket untuk menyambung kembali.

Jadi sekarang ini juga terjadi dengan MacOS Safari, FYI.

@calendee @anilanar kami tidak menggunakan sockets.io, hanya websockets murni, dan juga kami menggunakan React.js, jadi kodenya cukup rumit. Ide utamanya adalah kita memiliki dua <ContextProvider /> untuk setiap api, visibilitas di atas, websockets di bawah, dan websockets menggunakan konteks dari visibilitas.

Terima kasih telah menghubungi saya kembali JustFly1984. Sebenarnya, pada akhirnya, saya tidak membutuhkan API visibilitas. Saya hanya perlu menambahkan waktu tunggu. Setelah saya melakukan ini, saya tidak lagi memiliki masalah koneksi di Safari iOS.

// Establish a Socket.io connection
// Initialize our Feathers client application through Socket.io
// with hooks and authentication.
client.configure(feathers.socketio(socket), {
  timeout: 2000,
});
// Use localStorage to store our login token
client.configure(feathers.authentication(), {
  timeout: 2000,
});
Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

adammw picture adammw  ·  4Komentar

stnwk picture stnwk  ·  4Komentar

chfeizy picture chfeizy  ·  3Komentar

kootoopas picture kootoopas  ·  4Komentar

gCurtisCT picture gCurtisCT  ·  4Komentar