Socket.io: Peta jalan untuk v3

Dibuat pada 18 Mei 2018  Β·  51Komentar  Β·  Sumber: socketio/socket.io

Daftar ini terbuka untuk saran!

  • [ ] Tingkatkan dokumentasi

Itu jelas merupakan titik sakit utama dari proyek ini.

  • [x] Membalikkan arah mekanisme ping-pong

Saat ini klien mengeluarkan ping dan menunggu pong dari server, mengandalkan setTimeout() untuk memeriksa apakah koneksi masih hidup atau tidak. Tetapi ada laporan tentang pengatur waktu yang dibatasi di sisi browser, yang dapat memicu pemutusan secara acak.

Solusinya adalah ping dipancarkan dari server ke klien, tetapi itu adalah perubahan besar yang juga akan merusak implementasi klien lainnya..

Terkait: https://github.com/socketio/engine.io/issues/312

  • [x] Perbarui kode sumber ke ES6 di setiap proyek

  • [x] Migrasi ke webpack 4 (atau bundler lain, jika perlu)

  • [ ] Hapus persyaratan sesi lengket saat menggunakan banyak node

  • [ ] Default ke websocket, dan gunakan polling XHR sebagai fallback

Saat ini polling dibuat terlebih dahulu, dan kemudian ditingkatkan ke websocket jika memungkinkan.

  • [x] Jadikan metode generateId tidak sinkron

Yang ini juga merupakan perubahan yang melanggar. Terkait: https://github.com/socketio/engine.io/pull/535

  • [ ] Perbarui binding TypeScript, jika perlu

  • [ ] Masalah triase

Tidak ada tanggal rilis untuk saat ini, karena saya tidak yakin berapa banyak waktu yang dapat saya dedikasikan untuk poin-poin itu di minggu-minggu berikutnya. Tetapi bantuan apa pun diterima!

Komentar yang paling membantu

[email protected] dan [email protected] telah diterbitkan :fire:

Beberapa catatan:

  • API publik tidak banyak berubah (beberapa metode telah dihapus, lihat di sini dan di sini untuk referensi)
  • basis kode telah dimigrasikan ke TypeScript, tetapi beberapa pengetikan hilang, terutama di sisi klien.
  • perubahan besar di Engine.IO v4 (tercantum di sini ) telah disertakan
  • ukuran bundel klien telah meningkat sedikit, meskipun memiliki lebih sedikit ketergantungan, saya akan menggali ini

Umpan balik diterima!

Semua 51 komentar

Sepertinya rencana yang bagus.

Saya beralih dari nodejs ke golang, dan ternyata tidak ada implementasi socket.io 2.
https://github.com/googollee/go-socket.io/issues/188

Apa pendapat Anda tentang dukungan server golang untuk v3? Saya akan dengan senang hati mengambil bagian dalam pengembangan ini.

@theromis apakah Anda berbicara tentang klien golang (yang akan terhubung ke server Node.js) atau server golang yang sebenarnya? (Saya pikir beberapa pekerjaan telah dilakukan di sini juga: https://github.com/graarh/golang-socketio)

@darrachequesne Terima kasih atas balasan cepat, ya saya sedang berbicara tentang sisi server golang-socketio.
Proyek yang Anda sebutkan hampir mati (komit terakhir lebih dari setahun).
https://github.com/googollee/go-socket.io proyek mencari pengelola.
Dan tidak ada yang mendukung socket.io v2.
Saya pikir mungkin pengembang nodejs socketio terbesar asli bisa tertarik dengan pengembangan golang juga :)

Klien Java yang diperbarui akan menyenangkan juga.

Paket socket.io untuk sisi server Swift seperti https://github.com/vapor juga akan sangat bagus karena sudah ada klien Swift.

Kedengarannya seperti jika sisi server socket.io akan ditulis dalam beberapa bahasa asli seperti C/C++ dapat digunakan di mana saja termasuk nodejs, golang, java, rust dan apa pun...
Apa yang salah dengan pendekatan ini?
socket.io pendapat pribadi saya seperti standar de facto untuk dunia modern. Mengapa tidak membuatnya ideal?

Satu hal yang selalu mengganggu saya tentang socket.io yang dapat diatasi dalam rilis besar berikutnya adalah https://github.com/socketio/socket.io/issues/2124 dan https://github.com /socketio/socket.io/issues/2343

Ada inkonsistensi historis dalam penanganan namespace dan middlewares.
Juga, menurut pendapat saya, client memancarkan acara reconnect lebih masuk akal, setelah itu terhubung ke namespace daripada hanya menjadi acara penyambungan kembali Manajer... Misalnya , jika ada beberapa kesalahan otentikasi di middleware sub namespace, klien masih akan mendapatkan acara reconnect yang menurut saya kontra-intuitif.

Dari simpul versi 10.5 ada Utas Pekerja baru, yang saat ini dalam status eksperimental, tetapi ketika dirilis, saya pikir itu bisa menjadi cara yang lebih baik untuk menggunakan socket.io daripada menggunakan server redis.

Pro:

  • lebih sedikit ketergantungan (redis)
  • dukungan asli dari multi threading
  • lebih banyak kontrol

Menipu:

  • hanya akan berfungsi dari versi nodejs yang merilis utas pekerja (10.x || 11). Tapi ini bisa ditangani.

@Dua menarik! Ini akan berfungsi untuk pekerja di Host yang sama, tetapi bagaimana dengan banyak host?

@perrin4869 ide bagus :+1:

Saya meninggalkan banyak ide di sini: #3311 silakan baca :) Akan menutup yang satu itu dan melanjutkan diskusi di sini.

@MickL apakah Anda punya waktu untuk memigrasi repositori socket.io ke TypeScript, sebagai contoh?

Saya khawatir pengetahuan saya tentang teknologi jaringan dan keamanan informasi terbatas. Saya mengandalkan kerangka kerja tingkat tinggi seperti Express atau Socket.io.

Sejauh yang saya lihat socket.io sudah ditulis OOP dan didokumentasikan dengan baik sehingga tidak perlu repot untuk porting saja. Ide saya adalah untuk menjadi se-modular mungkin sehingga orang seperti saya dapat berkontribusi lebih mudah dan klien sangat mudah digoyahkan. Juga menjadi lebih reaktif bisa menjadi ide untuk membuat segalanya lebih sederhana. Pokoknya saya tidak cukup ke dalam kode sehingga kedua ide itu mungkin tidak masuk akal dalam proyek ini.

@darrachequesne pertanyaan yang bagus. Saya akan memikirkannya.

Memerlukan Nodejs 8 dan di atasnya karena versi sebelumnya paling baik dalam pemeliharaan, lihat https://nodejs.org/en/about/releases/ , setidaknya nodejs 4 harus dihapus (saya perhatikan dari .travis.yml yang Anda dukung dia)

Apakah pekerjaan terkait 3.0 telah dimulai di cabang/repo mana pun? Hanya memeriksa apakah ada tempat untuk tetap mendapat informasi tentang perkembangan atau kontribusinya.

Saya ingin melihat peningkatan dukungan untuk penanganan kesalahan di sisi server. Ini telah diangkat dalam beberapa masalah lain, tetapi lebih khusus lagi, akan lebih bagus jika:

  1. Ada dukungan untuk middleware penanganan kesalahan khusus selain default. Ini bisa terlihat seperti Express (yang dapat ditambahkan sebagai yang terakhir dalam rantai app.use() , mirip dengan socket.use() , middlewares): https://expressjs.com/en/guide/error -handling.html

Masalahnya, saat ini, adalah tidak ada cara untuk menambahkan jenis pelacakan atau pencatatan apa pun ke kesalahan setelah nexted .

  1. Selain itu, karena ruang nama 'kesalahan' dimasukkan dalam daftar hitam, socket.emit('error', err) tidak akan didengar oleh klien), saya tidak dapat emit kesalahan dari suatu tempat di server yang tidak mudah akses ke next() (yaitu dari dalam socket.on('event') ). Hal ini membuat sulit untuk membuat solusi penanganan kesalahan yang seragam.

  2. next(err) harus mengirimkan objek Error daripada string. Saya mengerti bahwa ada solusi untuk ini (https://github.com/socketio/socket.io/issues/3371) dengan menambahkan properti .data ajaib ke objek apa pun yang Anda panggil next() di. Ini tidak didokumentasikan, bagaimanapun, dan tidak intuitif.

Secara umum, next(err) tampak seperti kotak hitam yang tidak perlu dengan kapasitas penanganan kesalahan yang sangat terbatas.

Terima kasih atas kerja keras Anda, dan teruslah melakukannya!

@darrachequesne Setiap pembaruan pada v3 menjadi kenyataan? Saya belum melihat kemajuan apa pun sejak 2018.

Pembaruan singkat: kontrak saya saat ini baru saja diperbarui, dan saya harus dapat mendedikasikan satu hari per minggu (1/5) untuk pemeliharaan proyek. Jadi pekerjaan pada v3 harus segera dilanjutkan.

Sangat ingin membantu proyek ini dengan satu atau lain cara.

Jika ada cara untuk mengidentifikasi bagaimana saya bisa melakukan ini, beri tahu saya - saya hanya tidak ingin memperbaiki hal-hal agar tidak digabungkan! Jadi lebih baik menunggu bimbingan, jika bantuan diinginkan. Bersulang

  • kompresi (gzip, zlib, defalte/inflate)
  • mekanisme pengerjaan ulang pengiriman data biner (2 paket sekarang ... teks ws dan biner ws)
  • kirim metadata saat koneksi (gunakan kompresi?)
  • coders/encoder sebagai plugin termasuk yang khusus (messagepack, protobuf, dll), kita bisa menggunakan obat generik jika kode akan ditulis ulang ke TypeScript
  • penyematan sertifikat (sisi server/klien)

@blackkopcap

kompresi (gzip, zlib, defalte/inflate)

Kompresi sudah didukung (https://github.com/socketio/engine.io/blob/a05379b1e87d2e4cde40d3e30b134355883f4108/lib/transports/polling.js#L249-L298). Kompresi WebSocket ( perMessageDeflate ) akan dinonaktifkan secara default di v3, karena membutuhkan banyak memori ekstra.

mekanisme pengerjaan ulang pengiriman data biner (2 paket sekarang ... teks ws dan biner ws)

Setuju. Kartu ditambahkan di sini

kirim metadata saat koneksi (gunakan kompresi?)

Saya tidak yakin saya mengerti. Bisakah Anda menjelaskan kasus penggunaan?

coders/encoder sebagai plugin termasuk yang khusus (messagepack, protobuf, dll), kita bisa menggunakan obat generik jika kode akan ditulis ulang ke TypeScript

Anda seharusnya sudah dapat menyediakan parser Anda sendiri, seperti socket.io-msgpack-parser

penyematan sertifikat (sisi server/klien)

:+1:, ditambahkan di sini .

@michaelegregious

  1. Ada dukungan untuk middleware penanganan kesalahan khusus selain default. Ini bisa terlihat seperti Express (yang dapat ditambahkan sebagai yang terakhir dalam rantai app.use() , mirip dengan socket.use() , middlewares): https://expressjs.com/en/guide/error -handling.html

Itu akan sangat bagus. Ditambahkan di sini

  1. Selain itu, karena namespace 'kesalahan' masuk daftar hitam ( socket.emit('error', err) tidak akan didengar oleh klien), saya tidak dapat emit kesalahan dari suatu tempat di server yang tidak mudah akses ke next() (yaitu dari dalam socket.on('event') ). Hal ini membuat sulit untuk membuat solusi penanganan kesalahan yang seragam.

Tidak yakin apa yang bisa kami lakukan. Apakah anda punya saran?

  1. next(err) harus mengirimkan objek Error daripada string. Saya mengerti bahwa ada solusi untuk ini (https://github.com/socketio/socket.io/issues/3371) dengan menambahkan properti .data ajaib ke objek apa pun yang Anda panggil next() di. Ini tidak didokumentasikan, bagaimanapun, dan tidak intuitif.

Sangat setuju :+1: , ditambahkan di sini

Kami telah merilis Engine.IO v4, yang akan disertakan dalam Socket.IO v3. Anda dapat menemukan catatan rilis di sini .

Saya telah menambahkan apa yang dapat saya temukan di utas ini ke proyek di sini , untuk memberikan gambaran umum tentang kemajuannya. Jangan ragu untuk berkomentar!

Inilah yang ada dalam pikiran saya untuk memperbaiki https://github.com/socketio/socket.io/issues/2124

Klien sekarang akan mengirim paket CONNECT ketika ingin mendapatkan akses ke namespace default ( / ) (tidak ada lagi koneksi implisit).

Yang berarti bahwa middlewares yang terdaftar untuk namespace default tidak akan berlaku lagi untuk klien yang ingin mendapatkan akses ke namespace non-default

// server-side
io.use((socket, next) => {
  // not triggered anymore
});

io.of('/admin').use((socket, next => {
  // triggered
});

// client-side
const socket = io('/admin');

Di sisi klien, saya pikir kita juga harus membuat perbedaan yang jelas antara opsi query untuk Manajer (yang termasuk dalam parameter kueri) dan opsi query untuk Soket (yang dikirim dalam paket CONNECT ).

Sekarang:

const socket = io('/admin', {
  query: {
    abc: 'def'
  }
});

menghasilkan permintaan seperti GET /socket.io/?transport=polling&abc=def dan juga paket CONNECT seperti { "type": 0, "nsp": "admin?abc=def"}

Selain itu, karena tidak ada paket CONNECT untuk namespace default, query dari Socket saat ini diabaikan dalam kasus tersebut.

Saya mengusulkan untuk mengganti namanya menjadi authQuery sebagai gantinya.

const socket = io({
  query: {
    abc: 'def'
  },
  authQuery: {
    abc: '123'
  }
});

akan menghasilkan permintaan seperti GET /socket.io/?transport=polling&abc=def dan paket CONNECT seperti { "type": 0, "nsp": "/", "data": { abc: '123' } }

@ perrin4869 apakah masuk akal?

Sunting: mengenai pengorbanan, akan ada lebih banyak permintaan HTTP saat startup ...

Server > Client: Engine.IO handshake
Client > Server: Socket.IO connect
Server > Client: Socket.IO connect

Sementara saat ini kami memiliki:

// without middleware on the default namespace (only 1 GET request)
Server > Client: Engine.IO handshake + Socket.IO connect
// with at least a middleware (2 GET requests)
Server > Client: Engine.IO handshake
Server > Client: Socket.IO connect

@darrachequesne Terima kasih telah mempertimbangkan ini! Sangat menyenangkan untuk mendapatkan penutupan di sini, akhirnya dapat menyederhanakan kode yang saya miliki saat itu: D
Sudah lama jadi saya tidak ingat persisnya, tapi ini terdengar seperti solusi yang saya cari
Karena penasaran, apa alasan untuk trade-off?

Mengikuti gagasan tentang cara kerja bentuk js: https://web.archive.org/web/20200201163000/https://mathiasbynens.be/notes/shapes-ics . Untuk meningkatkan kinerja, bukankah lebih baik menggunakan array untuk menyimpan referensi untuk koneksi soket? Semakin banyak koneksi, id yang tak terhitung jumlahnya dan menggunakan objek untuk melakukan ini dengan setiap koneksi baru, bentuk baru dihasilkan dan lebih banyak memori dikonsumsi, tergantung pada masa pakai node dan jumlah koneksi yang dapat dimilikinya, ini mungkin akan dimiliki beberapa dampak kinerja negatif.

@perrin4869 trade-off berasal dari implementasi saat ini, karena kami pertama kali membuat koneksi Engine.IO dan kemudian kami melanjutkan dengan koneksi Socket.IO. Yang memberi, jika transportasi polling panjang HTTP diaktifkan (yang merupakan default):

  • permintaan HTTP GET untuk mengambil jabat tangan Engine.IO
  • permintaan HTTP POST untuk mengirim paket Socket.IO CONNECT
  • permintaan HTTP GET untuk mengambil paket Socket.IO CONNECT dari server
  • dan kemudian tingkatkan ke WebSocket

Tapi itu pasti bisa ditingkatkan. Sebagai referensi, perubahan diterapkan di sini dan di sini .

Selain itu, acara reconnect tidak akan dipancarkan oleh instance Socket (sisi klien) lagi ( di sini ).

@ferco0 sekarang kita akan menggunakan Map alih-alih objek biasa (https://github.com/socketio/socket.io/commit/84437dc2a682add44bb57d03f703cfc955607352). Apakah komentar Anda masih berlaku, dalam hal ini?

[email protected] dan [email protected] telah diterbitkan :fire:

Beberapa catatan:

  • API publik tidak banyak berubah (beberapa metode telah dihapus, lihat di sini dan di sini untuk referensi)
  • basis kode telah dimigrasikan ke TypeScript, tetapi beberapa pengetikan hilang, terutama di sisi klien.
  • perubahan besar di Engine.IO v4 (tercantum di sini ) telah disertakan
  • ukuran bundel klien telah meningkat sedikit, meskipun memiliki lebih sedikit ketergantungan, saya akan menggali ini

Umpan balik diterima!

@darrachequesne tidak apa-apa.

@darrachequesne Banyak proyek open source npm mencoba mengurangi jumlah dependensi. Ini agak menjadi tren di masyarakat. Alasan utamanya adalah banyak organisasi memerlukan pemeriksaan lisensi semua dependensi yang digunakan saat digunakan dalam proyek, agar tidak mengalami masalah hukum. Memiliki lebih sedikit ketergantungan tentu saja membantu dalam hal ini. Sebagai contoh, Helm (paket keamanan hebat untuk server web Express) beralih ke instalasi tanpa ketergantungan pada rilis terbaru 4.0.

Dengan mengingat hal itu, apakah ada rencana untuk mengurangi jumlah dependensi di socket.io di rilis 3?

@thernstig itu pertanyaan yang bagus! Kami memang mencoba mengurangi jumlah dependensi di Socket.IO v3:

npm i [email protected] => 48 packages
npm i [email protected] => 33 packages

npm i [email protected] => 37 packages
npm i [email protected] => 20 packages

Berikut adalah pohon ketergantungan untuk server:

[email protected]
β”œβ”€β”€ [email protected]
β”œβ”€β”¬ [email protected]
β”‚ └── [email protected]
β”œβ”€β”¬ [email protected]
β”‚ β”œβ”€β”¬ [email protected]
β”‚ β”‚ β”œβ”€β”¬ [email protected]
β”‚ β”‚ β”‚ └── [email protected]
β”‚ β”‚ └── [email protected]
β”‚ β”œβ”€β”€ [email protected] deduped
β”‚ β”œβ”€β”€ [email protected]
β”‚ β”œβ”€β”¬ [email protected]
β”‚ β”‚ β”œβ”€β”€ [email protected]
β”‚ β”‚ └── [email protected]
β”‚ β”œβ”€β”€ [email protected] deduped
β”‚ β”œβ”€β”€ [email protected]
β”‚ └── [email protected]
β”œβ”€β”€ [email protected]
β”œβ”€β”¬ [email protected]
β”‚ β”œβ”€β”€ @types/[email protected]
β”‚ β”œβ”€β”€ [email protected]
β”‚ β”œβ”€β”€ [email protected]
β”‚ β”œβ”€β”€ [email protected]
β”‚ β”œβ”€β”€ [email protected] deduped
β”‚ β”œβ”€β”¬ [email protected]
β”‚ β”‚ β”œβ”€β”€ [email protected]
β”‚ β”‚ β”œβ”€β”€ [email protected] deduped
β”‚ β”‚ β”œβ”€β”€ [email protected] deduped
β”‚ β”‚ β”œβ”€β”€ [email protected] deduped
β”‚ β”‚ β”œβ”€β”€ [email protected]
β”‚ β”‚ β”œβ”€β”€ [email protected]
β”‚ β”‚ β”œβ”€β”¬ [email protected]
β”‚ β”‚ β”‚ └─┬ [email protected]
β”‚ β”‚ β”‚   └── [email protected]
β”‚ β”‚ β”œβ”€β”€ [email protected]
β”‚ β”‚ β”œβ”€β”€ [email protected]
β”‚ β”‚ └── [email protected]
β”‚ β”œβ”€β”€ [email protected]
β”‚ └── [email protected] deduped
└─┬ [email protected]
  β”œβ”€β”€ [email protected] deduped
  └── [email protected] deduped

Saya pikir kita hanya membutuhkan folder dist/ dari paket socket.io-client , jadi mungkin masuk akal untuk membuat socket.io-client-dist tanpa ketergantungan. Bagaimana menurutmu?

Catatan: soket. [email protected] dan soket. [email protected] telah diterbitkan

Saya telah menambahkan beberapa contoh dengan modul ES dan TypeScript .

@darrachequesne Saya menyerahkan itu sepenuhnya pada kebijaksanaan Anda

@michaelegregious tentang komentar Anda, saya tahu ini sudah cukup lama, tetapi apakah Anda memiliki API tertentu dalam pikiran?

Saya setuju bahwa API saat ini dapat ditingkatkan. Itu diimplementasikan sebagai cara untuk memiliki pendengar yang menangkap semua (dibahas di sini ), dan bukan dengan mempertimbangkan penanganan kesalahan.

Kami juga dapat menambahkan cara untuk memperingatkan pengguna tentang peristiwa yang tidak ditangani (404 tanggapan di Express, http://expressjs.com/en/starter/faq.html#how-do-i-handle-404-responses).

@darrachequesne senang mendengar Anda mengerjakan versi socket.io berikutnya !! Terima kasih sebelumnya untuk semua pekerjaan Anda di perpustakaan ini.

Saat ini saya sedang menguji socket. [email protected] dan soket. [email protected] dan saya mencoba menggunakan sintaks baru untuk bergabung dengan ruangan dan memancarkan ke soket di ruangan itu.

Saya tidak bisa membuat server memancarkan ke soket klien menggunakan contoh Anda di file log perubahan.

socket.join("room1"); io.to("room1").emit("hello");

Terlampir adalah tangkapan layar yang menunjukkan file socket js yang digunakan pada klien dan kode untuk server node.js

file js sisi klien
Screen Shot 2020-10-28 at 12 04 43 AM

soket sisi klien. pada acara
Screen Shot 2020-10-28 at 12 07 08 AM

sisi server bergabung dengan sintaks di dalam io.on("connect",
Screen Shot 2020-10-28 at 12 06 36 AM

Saya mencoba semua metode di sceenshot terakhir untuk membuatnya dipancarkan ke klien dan tidak ada yang berhasil.

Tolong beri tahu saya jika Anda membutuhkan info lagi.

Terima kasih

@darrachequesne Saya menurunkan versi ke 3.0.0-rc2 dan bergabung dengan ruang menggunakan join dengan metode panggilan balik yang disebut "room1" yang dipicu tetapi tidak ada peristiwa emisi yang dikirim ke klien

socket.join("room1", () => { console.log('old way to join'); io.to("room1").emit("hello", {}); io.in("room1").emit("hello", {}); });

Saya juga menghapus 3.0.0-rc2 dan menginstal socket.io 2.3.0 untuk Server dan Klien dan memastikan kode di atas berfungsi seperti yang diharapkan. Jadi saya yakin ada yang rusak dengan versi 3.0.0 rc

@szarkowicz Hmm... Saya tidak dapat mereproduksi perilaku yang Anda gambarkan: https://github.com/socketio/socket.io-fiddle/tree/issue/v3

Kode berikut tampaknya berfungsi seperti yang diharapkan:

socket.join("room1");

io.to("room1").emit('hello', 1, '2', {
  hello: 'you'
});

Apakah Anda mendapatkan kesalahan di konsol? Apakah Anda mendapatkan acara connect di sisi klien?

@darrachequesne terima kasih atas konfirmasinya. Saya telah melacaknya kembali menggunakan redisAdapter yang menyebabkan masalah. Setelah saya mengomentari kode berikut, versi rc3 dari socket.io berfungsi seperti yang diharapkan.

let redisAdapter = require('socket.io-redis');
io.adapter(redisAdapter({ host: 'localhost', port: 6379 }));

Sudahkah Anda mencoba menggunakan redis dengan v3 socket.io?

Terima kasih

@szarkowicz ya, Anda benar sekali, adaptor Redis perlu diperbarui agar sesuai dengan Socket.IO v3, itu akan diperbarui tepat setelah rilis 3.0.0 (yang seharusnya segera sekarang).

Bagaimanapun, terima kasih banyak atas umpan baliknya :+1:

@darrachequesne oke kedengarannya bagus!!! Saya tidak akan menggunakan if untuk saat ini dan terus menguji tanpanya.

Apakah Anda punya waktu ketika Anda berpikir v3 akan dirilis?

Jangan khawatir - sekali lagi terima kasih telah menghubungi saya dan telah mengerjakan semua peningkatan untuk versi berikutnya!!

@darrachequesne Terima kasih banyak atas pembaruan ini! Maaf atas tanggapan saya yang tertunda! Kami tidak menggunakan socket.io dalam proyek saya saat ini (meskipun kami dapat mengintegrasikannya di masa mendatang), tetapi solusi yang saya gunakan dalam proyek terakhir saya adalah menggunakan socket.emit('err', err) daripada menggunakan namespace yang diistimewakan socket.emit('error', err) .

Inilah catatan yang saya masukkan ke dalam readme aplikasi kami untuk menjelaskan masalah ini:

#### Error Handling Patterns
Most of the communication between client and server in the app happens via `socket.io`. For server-side error-handling, `socket.io` exposes [Express](https://expressjs.com/en/guide/error-handling.html)-like middleware via `socket.use(socket, next)`. Middlewares can be chained to separate concerns for authentication, logging, etc.

Unlike `Express`, however, `socket.io`'s native `next(err)` does not support addition of custom error handlers. Calling `next(err)` immediately breaks out of the middleware chain. Additionally, the privileged `error` namespace (emitted by `next(err)` and received by the client via `socket.on('error', err)`) is not available for use via the standard `socket.emit('error', err)` on the server. 

For these reasons, the server instead emits all errors to the client via `socket.emit('err', err)`. We use a `./CustomError` Class (inheriting from the native JS Error) to namespace our errors, and then rely on a switch to properly route errors on the client. (This also allows us to track and log outgoing errors via custom middleware on the server.)

Jadi, dalam memikirkan hal ini lagi, jika Anda telah memasukkan kemampuan untuk menambahkan middleware khusus ke next(err) , apakah mungkin juga mengizinkan penggunaan namespace socket.emit('error', err) untuk penggunaan manual pada server?

Saya melihat kembali kode itu dan semua event handler saya terlihat seperti ini (jika berguna untuk dilihat):

    socket.on('quotes', async (params) => {
      try {
        await dispatchQuotes(socket, params);
      } catch (err) {
        socket.emit('err', err);
      }
    });

Oh! Satu hal lagi yang saya ingat. Berikut ini adalah pekerjaan di sekitar saya dulu dapat memantau acara keluar untuk tujuan logging/penanganan kesalahan:

  ioServer.on('connection', (socket: Socket) => {
    const emitter = socket.emit;

    // We modify socket.io's native 'emit' method to monitor outgoing
    // events, since socket.use() (middleware) only tracks incoming events.
    socket.emit = (...args: any) => {
      emitter.apply(socket, args);
      outgoingErrorMiddleware(socket, args, app);
    };

etc.

Inilah cara saya menggunakan middleware keluar jika bermanfaat untuk dilihat:

export function outgoingErrorMiddleware(socket: SocketIO$Socket, packet: Packet, app: App) {
  const [eventName, err] = packet;
  const { metrics } = app.locals;
  if (eventName === 'err') {
    logger.error(err);
    metrics.errors += 1;
  }
}

Terima kasih sekali lagi untuk semua kerja keras Anda! Saya akan mencoba untuk merespon lebih cepat lain kali.

  1. Selain itu, karena namespace 'kesalahan' masuk daftar hitam ( socket.emit('error', err) tidak akan didengar oleh klien), saya tidak dapat emit kesalahan dari suatu tempat di server yang tidak mudah akses ke next() (yaitu dari dalam socket.on('event') ). Hal ini membuat sulit untuk membuat solusi penanganan kesalahan yang seragam.

Tidak yakin apa yang bisa kami lakukan. Apakah anda punya saran?

@michaelegregious terima kasih atas contoh yang Anda berikan. (dan tidak ada masalah untuk penundaan!)

Secara teknis, saya tidak yakin kami dapat menangkap kesalahan yang dilemparkan oleh pendengar async:

socket.on("test", async () => {
  throw new Error("catch me?");
});

try {
  socket.emit("test");
} catch (e) {
  // won't catch the error
}

Jadi saya pikir lebih baik membiarkan pengguna menangani kesalahan sendiri, baik dengan kode yang Anda berikan ( socket.emit("err", err); ), atau dengan fungsi pengakuan:

socket.on('quotes', async (params, cb) => {
  try {
    await dispatchQuotes(socket, params);
  } catch (err) {
    cb(err);
  }
});

Bagaimana menurutmu?

Apa yang saat ini diterapkan untuk v3:

  • "error" diganti namanya menjadi "connect_error", dan terbatas pada kesalahan middleware Namespace saja:
// server
io.use((socket, next) => {
  next(new Error("unauthorized"));
});
// client
socket.on("connect_error", (err) => {
  // err instanceof Error === true
  // err.message === "unauthorized"
})

Yang juga berarti bahwa "kesalahan" bukan lagi nama acara yang dicadangkan.

  • socket.use() dihapus dan diganti dengan socket.onAny() (server dan klien)
// server
io.on("connect", (socket) => {
  socket.onAny((event, ...args) => {

 Β });
});

// client
socket.onAny((event, ...args) => {
  // ...
});

Apakah kedengarannya bagus untuk Anda? Apakah anda memiliki saran?

Halo semuanya!

stopkontak. [email protected] dan soket. [email protected] keluar. Anda dapat mengujinya dengan npm i socket.io<strong i="10">@beta</strong> socket.io-client@beta .

Kami berencana untuk merilis 3.0.0 minggu depan. Panduan migrasi telah dibuat: https://socket.io/docs/migrating-from-2-x-to-3-0/ (beberapa detail hilang, seperti acara yang dipesan di sisi klien)

Seperti biasa, umpan balik diterima!

Saya ragu, saya tidak tahu apakah di sini adalah tempat yang tepat untuk itu, tetapi mungkin untuk menentukan id soket pada koneksi, misalnya, untuk menggunakan id klien yang berasal dari db? Mengubah prop "id" dari objek soket pada middleware koneksi membuat sinkronisasi dengan klien?

@darrachequesne Terima kasih atas pembaruan RC4.
Dengan versi 3.0.0.rc4 - 2 Pertanyaan:

  1. Apa cara terbaik untuk mendapatkan jumlah atau daftar soket (klien) di sebuah ruangan?
  2. Apa cara terbaik untuk mendapatkan daftar semua kamar saat ini?

Akan melakukan banyak pengujian selama beberapa hari ke depan dengan rc4.

Terima kasih sekali lagi untuk semua kerja keras Anda.

@ ferco0 saat ini tidak memungkinkan, Socket#id dihasilkan di sini . Dalam contoh Anda (ID klien dari db), apa yang terjadi jika pengguna yang sama membuka tab baru? (karena Socket#id harus unik)

@szarkowicz

  1. Apa cara terbaik untuk mendapatkan jumlah atau daftar soket (klien) di sebuah ruangan?

io.allSockets() => dapatkan semua id soket (berfungsi dengan banyak server) (baik, setelah adaptor Redis diperbarui)
io.in("room1").allSockets() => dapatkan semua id soket di kamar

(itu bernama io.clients() di Socket.IO v2)

  1. Apa cara terbaik untuk mendapatkan daftar semua kamar saat ini?

Saat ini tidak ada API untuk itu, selain menggali adaptor: io.of("/").adapter.rooms ( di sini )

Selain itu, adaptor Redis memiliki metode allRooms , tetapi tidak tercermin dalam API publik.

Oke sangat menghargai info untuk mendapatkan klien dan kamar untuk keduanya dengan Redis dan Non Redis. Saya mungkin akan mulai menguji hanya dengan socket.io v3 sampai adaptor Redis diperbarui.

Migrasi ke webpack 4 (atau bundler lain, jika perlu)

Anda dapat melihat https://github.com/formium/tsdx sebagai alternatif.
Saya ingin mendorong penulisan ulang socket.io & engine.io di TypeScript beberapa bulan yang lalu menggunakan tsdx, tidak dapat menemukan waktu untuk melakukannya :senyum:

:rocket: Socket.IO v3.0.0 sudah keluar! :rocket: Catatan rilis dapat ditemukan di sini: https://socket.io/blog/socket-io-3-release/

Terima kasih kepada semua orang yang terlibat dalam utas ini atas ide/umpan balik Anda :heart:

@darrachequesne , itu semua masuk akal bagi saya. Saya lupa tentang masalah itu kembali. async middlewares (dalam proyek saya saat ini, kami telah membuat fungsi wrap() untuk setiap rute Express untuk menangani masalah yang sebenarnya, sehingga tidak ada kesalahan yang lolos dari celah).

Terima kasih untuk semua perbaikan!

Apakah kedengarannya bagus untuk Anda? Apakah anda memiliki saran?

async middlewares

@michaelegregious bisakah Anda membuka permintaan fitur untuk itu? Terima kasih!

Saya akan menutup masalah ini sekarang. Diskusi tentang rilis: https://github.com/socketio/socket.io/discussions/3674

Apakah halaman ini membantu?
0 / 5 - 0 peringkat