Socket.io: Cara yang tepat bagi klien untuk menyambung kembali setelah server melakukan socket.disconnect( true )

Dibuat pada 9 Mar 2016  ·  35Komentar  ·  Sumber: socketio/socket.io

Server : node + socket.io

var io = require( 'socket.io' )( 3000 );

io.on( 'connection', function ( socket ) ...

// at some point if client auth fails, server may kick him out:

socket.disconnect( true );

Klien : html/js + socket.io 1.4.5

socket = io.connect( 'http://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: 99999
} );

socket.on( 'connect', function () {
    console.log( 'connected to server' );
} );

socket.on( 'disconnect', function () {
    console.log( 'disconnected to server' );
} );

Di atas disederhanakan tetapi itu adalah dasarnya. Sambungan ulang berfungsi dengan baik jika saya menjalankan klien saat server mati. Klien mencoba terhubung ke server dan ketika saya akhirnya menjalankan server, koneksi sudah stabil.

Pada titik tertentu mungkin terjadi bahwa server memutuskan untuk memutuskan sambungan klien, terutama karena dia keluar dengan membatalkan token dan permintaan pada db memerintahkan untuk melakukannya, atau token autentikasi kedaluwarsa atau apa pun.

Dalam keadaan ini saya ingin mengembalikan polling server oleh klien karena pengguna mungkin ingin login lagi dan dia memiliki hak untuk terhubung kembali ke server.

Jika saya menyegarkan halaman (klien) di browser, itu berfungsi dengan baik tetapi ini adalah solusi yang buruk.

Saya pikir penyebabnya adalah properti "Manager.skipReconnect" yang disetel ke true setelah melakukan disconnect(), jadi saya bertanya apa cara yang tepat untuk memulai kembali polling koneksi ulang oleh klien setelah server memutus klien.

Menemukan beberapa jawaban di stackoverflow tentang ini tetapi semuanya tidak berhasil, semua hal yang harus dieksekusi di klien:

  • socket.io.reconnect();
  • socket.socket.reconnect(); // ??
  • socket = io.connect( ' http://127.0.0.1 :3000', ... // mengaktifkan kembali cuplikan koneksi sepertinya ide yang buruk

Bisakah Anda membantu saya tentang masalah ini?

Terima kasih

Komentar yang paling membantu

Untuk saat ini, saya berhasil dengan cara ini dan tampaknya stabil:

Klien :

var app = {
...
socket: null,
connect: function() {
  var self = this;
  if( self.socket ) {
    self.socket.destroy();
    delete self.socket;
    self.socket = null;
  }
  this.socket = io.connect( 'http://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: Infinity
  } );
  this.socket.on( 'connect', function () {
    console.log( 'connected to server' );
  } );
  this.socket.on( 'disconnect', function () {
    console.log( 'disconnected from server' );
    window.setTimeout( 'app.connect()', 5000 );
  } );
}
...
} // var app

Semua 35 komentar

Untuk saat ini, saya berhasil dengan cara ini dan tampaknya stabil:

Klien :

var app = {
...
socket: null,
connect: function() {
  var self = this;
  if( self.socket ) {
    self.socket.destroy();
    delete self.socket;
    self.socket = null;
  }
  this.socket = io.connect( 'http://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: Infinity
  } );
  this.socket.on( 'connect', function () {
    console.log( 'connected to server' );
  } );
  this.socket.on( 'disconnect', function () {
    console.log( 'disconnected from server' );
    window.setTimeout( 'app.connect()', 5000 );
  } );
}
...
} // var app

Menggunakan pendekatan serupa dari:

  this.socket = io.connect( 'ws://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: Infinity
  } );

Sayangnya, ini menyebabkan soket menggunakan protokol http, bukan soket web.

Masih mencari pendekatan yang baik untuk koneksi soket web yang persisten.

Apakah saya melewatkan sesuatu???

Juga tertarik pada solusi untuk ini.

socket.connect()
bekerja untuk saya pada versi 1.5.1 . Semoga membantu.

@sconway Bisakah Anda mencerahkan kami? Setiap kode mungkin?

Hai, yang di sana,

Punya pertanyaan yang sama, menemukan solusi ini, saat ini sedang diuji, tampaknya merupakan solusi yang kuat atau solusi yang kuat ... (keduanya disediakan)

http://stackoverflow.com/questions/10437584/socket-io-reconnect

Bisakah kita memperbaikinya di socket.io itu sendiri?

Saya memutakhirkan ke versi 2.0.3 dan pengaturan autoreconnect default berfungsi, tidak ada masalah di sini.

Ketika apakah Server atau Klien memanggil metode disconnect() klien menghancurkan soket, menghapus semua event handler dan manajer menghapusnya dari array penghubung. Ini tidak akan terjadi ketika pemutusan karena alasan lain.
Solusi yang bagus dapat dibaca parameter alasan
.on('disconnect', reason => { if(reason === 'io server disconnect') { //you should renew token or do another important things before reconnecting socket.connect(); } });
Atau lebih baik periksa apakah soket masih ada di daftar penghubung manajer
.on('disconnect', () => { if(socket.io.connecting.indexOf(socket) === -1){ //you should renew token or do another important things before reconnecting socket.connect(); } })

Saya melakukannya seperti @DrLightman dan itu bekerja dengan sempurna!

var WebSocketServer = {
    isConnected: false,
    socket: null,
    interval: null,
    connect() {
        if (this.socket) {
            this.socket.destroy();
            delete this.socket;
            this.socket = null;
        }
        this.socket = io.connect('http://localhost:9010', {
            reconnection: false
        });
        this.socket.on('connect', () => {
            this.isConnected = true;
            this.socket.emit('authentication', { user_id: 2751, token: "abc" });
            this.socket.on('authenticated', function() {

            });
        });

        this.socket.on('disconnect', () => {
            this.isConnected = false;
            this.interval = window.setInterval(() => {
                if (this.isConnected) {
                    clearInterval(this.interval);
                    this.interval = null;
                    return;
                }
                WebSocketServer.connect()
            }, 5000);
        });

        return this.socket;
    }
}

var socket = WebSocketServer.connect();

@DrLightman ini adalah bagaimana saya melakukannya dan bekerja dengan sempurna di browser atau Aplikasi Android/IOS
var io= new socketio.connect('http://192.168.43.79:3000',{'forceNew':true});

@pablodgonzalez saya punya pertanyaan yang sama, solusi Anda berhasil?

@programmerCs Ya, memang. Dalam produksi tanpa masalah yang terdeteksi.

Masalah ini menyelesaikan banyak masalah saya
Terimakasih semuanya

Punya masalah yang sama ketika saya ingin memaksa klien untuk menyegarkan tokennya karena kedaluwarsa saat terhubung ke server.

Saya akhirnya mengirim acara ke klien, memintanya untuk menyegarkan tokennya. Tidak ada soket yang ditutup dengan melakukan ini, jadi ini menghindari masalah dan berfungsi dengan baik!

...sekarang saatnya untuk mendorong itu ke produksi! :keringat_dingin: :senyum:

Sepertinya solusi paling sederhana adalah mendengarkan acara 'putuskan' dari emitor dan panggil fungsi setTimeout() tetapi bagaimana dengan acara yang dapat dibuat klien saat terputus dari server? Sepertinya perlu selalu melakukan pemeriksaan tambahan jika koneksi dibuat sebelum menyiarkan emisi apa pun pada klien.

@qassa jika Anda memerlukan konfirmasi tentang emisi, Anda harus menggunakan parameter panggilan balik. Sebaliknya jika Anda membutuhkan jaminan penerimaan suatu acara, Anda tidak boleh menggunakan socket.io tetapi beberapa perpustakaan/protokol antrian seperti nyamuk/mqtt atau apa pun.
setTimeout adalah opsi tetapi soket yang terputus (oleh server atau klien) adalah soket yang segera dihancurkan. Jadi, jika Anda membutuhkan jaminan koneksi ulang yang mudah dan cepat mengapa menggunakan setTimeout jika Anda belum memiliki instance objek socket dan dapat memanggil connect()?

Seseorang dari proyek BENAR-BENAR PERLU DOKUMENTASI ini...

Biar saya luruskan, apakah server memutuskan klien karena alasan tertentu atau karena kehilangan koneksi jaringan? Jika hanya jaringan maka Socketio(klien) akan mencoba menyambung kembali tanpa batas! , jika dikonfigurasi seperti ini io=new socketio(‘http://yourserver.com’, {'forceNew':true}); bagaimanapun itu akan tetap terhubung kembali, tetapi jika Anda menempatkan listerner untuk memutuskan sambungan dari server, cukup panggil io.disconnect() pada klien

Dari: CxRes [mailto:[email protected]]
Dikirim: 01 Februari 2018 21:50
Kepada: socketio/socket.io [email protected]
Cc: devyaz [email protected] ; Komentar [email protected]
Subjek: Re: [socketio/socket.io] Cara yang tepat bagi klien untuk menyambung kembali setelah server melakukan socket.disconnect( true ) (#2476)

Seseorang dari proyek BENAR-BENAR PERLU DOKUMENTASI ini...


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub https://github.com/socketio/socket.io/issues/2476#issuecomment-362381171 , atau nonaktifkan utas https://github.com/notifications/unsubscribe-auth/ ATfQSQQ1LJ90E6FqsdmiMktpp2AdoLuxks5tQhVQgaJpZM4HsVs7 . https://github.com/notifications/beacon/ATfQSYqwkgtrHZk9FASNZUl69ps9ZYYCks5tQhVQgaJpZM4HsVs7.gif

@devyaz aku cinta kamu

Dokumentasi diperbarui dengan jawaban @ pablodgonzalez : https://github.com/socketio/socket.io-client/commit/afb952d854e1d8728ce07b7c3a9f0dee2a61ef4e

Terima kasih banyak!

Gunakan versi 0.8.3 dari io.socket hapus versi baru 1.0.0

compile('io.socket:socket.io-client:0.8.3') {
    exclude group: 'org.json', module: 'json'
}

Menggunakan pendekatan serupa dari:

  this.socket = io.connect( 'ws://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: Infinity
  } );

Sayangnya, ini menyebabkan soket menggunakan protokol http, bukan soket web.

Masih mencari pendekatan yang baik untuk koneksi soket web yang persisten.

Apakah saya melewatkan sesuatu???

gunakan wss://

Menggunakan pendekatan serupa dari:

  this.socket = io.connect( 'ws://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: Infinity
  } );

Sayangnya, ini menyebabkan soket menggunakan protokol http, bukan soket web.
Masih mencari pendekatan yang baik untuk koneksi soket web yang persisten.
Apakah saya melewatkan sesuatu???

gunakan wss://

halo, bro. bagaimana bisa jika hanya menggunakan wss. itu hanya berfungsi sebagai koneksi soket web yang persisten, memiliki pertanyaan yang sama tentang menjaga dan menyambungkan kembali cepat dengan ws bukan polling.

Ketika apakah Server atau Klien memanggil metode disconnect() klien menghancurkan soket, menghapus semua event handler dan manajer menghapusnya dari array penghubung. Ini tidak akan terjadi ketika pemutusan karena alasan lain.
Solusi yang bagus dapat dibaca parameter alasan

.on('disconnect', reason => { 
  if(reason === 'io server disconnect') {
    //you should renew token or do another important things before reconnecting
    socket.connect();
  }
});

Atau lebih baik periksa apakah soket masih ada di daftar penghubung manajer

.on('disconnect',  () => {
  if(socket.io.connecting.indexOf(socket) === -1){
    //you should renew token or do another important things before reconnecting
    socket.connect();
  }
})

Bisakah Anda menjelaskan mengapa lebih baik memeriksa apakah soket masih ada dalam daftar penghubung manajer? Dokumen yang diperbarui hanya mengambil solusi pertama Anda yaitu memeriksa alasan pemutusan sambungan. Terima kasih.

Hai @emclab , hanya karena jika dalam versi yang lebih baru pengembang menambahkan beberapa alasan baru, dan untuk kasus Anda tidak penting "alasannya" maka cari saja soket di daftar koneksi. jika tidak ada, maka Anda harus menyambungkan kembali secara manual.
Dalam beberapa kasus penting untuk mengetahui alasannya, dan merupakan kasus yang lebih kuat, membaca dan bertindak sesuai tetapi mungkin bukan yang paling umum.
Penafian: jika Anda menggunakan cara kedua, Anda tidak aman dari refactors atau beberapa perubahan mekanisme di versi yang lebih baru, jadi itu tidak jauh lebih baik tetapi jauh lebih sederhana.
Salam!

Saya tidak dapat memutuskan sambungan soket ke aplikasi ionik. Saya memiliki socket.on ke dalam konstruktor halaman umum di penyedia. Saya ingin memutuskan soket ke fungsi pada file yang sama dari tempat aplikasi logout dipanggil.

Tapi saya bisa mencabut soket. Saya multiple socket.on('event') pada multiple emit into application.
Adakah yang bisa membantu saya?

Socket.disconnect() harus dilakukan

Pada Senin, 11 November 2019 06:16 krunal9421, [email protected] menulis:

Saya tidak dapat memutuskan sambungan soket ke aplikasi ionik. saya sudah
socket.on ke dalam konstruktor halaman umum di penyedia. aku ingin
lepaskan soket ke fungsi pada file yang sama dari tempat aplikasi
logout disebut.

Tapi saya bisa mencabut soket. Saya multiple socket.on('event')
pada beberapa memancarkan ke dalam aplikasi.
Adakah yang bisa membantu saya?


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/socketio/socket.io/issues/2476?email_source=notifications&email_token=AE35ASNI2K4DWOB4P2HPSATQTDMC7A5CNFSM4B5RLM52YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVX65issue
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AE35ASJPORGOSYQAEJEHHG3QTDMC7ANCNFSM4B5RLM5Q
.

@devyaz Saya tidak dapat memutuskan soket menggunakan socket.disconnect().
Saya telah membagikan kode sampel saya dengan ini.
https://i.stack.imgur.com/wrIEv.png.

Saya telah menulis kode ke dalam file umum.

Apakah Anda mencoba memutuskan sambungan dari server atau sisi pengguna? yaitu server harus
putuskan pengguna. Karena jika server kehilangan klien, itu memicu pemutusan
peristiwa. Tetapi klien dapat memutuskan sambungan dari server dengan menelepon
socket.disconnect

Pada Rabu, 20 November 2019 05:39 krunal9421, [email protected] menulis:

@devyaz https://github.com/devyaz Saya tidak dapat memutuskan soket
menggunakan socket.disconnect().
Saya telah membagikan kode sampel saya dengan ini.
https://i.stack.imgur.com/wrIEv.png.

Saya telah menulis kode ke dalam file umum.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/socketio/socket.io/issues/2476?email_source=notifications&email_token=AE35ASK4NY4SKG5JWSBDKCTQUSWNVA5CNFSM4B5RLM52YY3PNVWWK3TUL52HS4DFVREXG43VMVBWJKEEOR555WWZJKEEOR555WWZJKEEOR555WWZJ2EEOR555AIWZH27ment
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AE35ASIFTISGTIAQQ7UKCJDQUSWNVANCNFSM4B5RLM5Q
.

menggunakan ini di sisi klien.

Lakukan this.socketstatus.disconnect() dalam fungsi logout Anda dan saya pikir
anda harus menghapus fungsi ".on("connected",.....)"

Pada Jumat, 22 Nov 2019 11:50 krunal9421, [email protected] menulis:

menggunakan ini di sisi klien.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/socketio/socket.io/issues/2476?email_source=notifications&email_token=AE35ASJTREAYRMF4THBK3FDQU6TOLA5CNFSM4B5RLM52YY3PNVWWK3TUL52HS4DFVREXG43VMVBW3COMEEN565057WZZW63LNMVXHJKT5LNMVXHJKT
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AE35ASJGKVGVUQNK454C63DQU6TOLANCNFSM4B5RLM5Q
.

Setelah kehilangan koneksi, soket terhubung kembali ke server. Setelah itu, terus menampilkan _io.socket.engineio.client.EngineIOException: xhr post error_ di Android .
Sebagian besar jawaban dari StackOverflow tidak berfungsi.
Saya terjebak dengan masalah ini T_T.... Tolong saya!

Saya mencoba menerapkan kode ini di node.js + javaScript wepapp saya tetapi ketika browser ponsel saya berada di latar belakang, di tab yang tidak aktif atau layar yang terkunci, sambungannya terputus setelah beberapa menit.

Saya mencoba menyambungkan kembali ke soket ketika terputus (dengan tanggapan ping timeout atau transport closed ) tetapi tidak mungkin. Apakah ini perilaku normal pada browser ponsel? karena di laptop atau desktop browser berfungsi seperti yang diharapkan.

Ada yang bisa bantu saya?

Terima kasih

Hai @asiermusa tetapi di web Anda harus menggunakan pekerja web untuk menghindari penangguhan proses. Saya sungguh-sungguh tidak tahu apakah itu cukup untuk mencapai itu.

Bersulang!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat