Socket.io: Fahrplan fĂŒr v3

Erstellt am 18. Mai 2018  Â·  51Kommentare  Â·  Quelle: socketio/socket.io

Diese Liste ist offen fĂŒr VorschlĂ€ge!

  • [ ] Verbessern Sie die Dokumentation

Das ist offensichtlich der grĂ¶ĂŸte Schmerzpunkt des Projekts.

  • [x] Kehrt die Richtung des Ping-Pong-Mechanismus um

Derzeit gibt der Client ein ping aus und wartet auf ein pong vom Server, wobei er sich auf setTimeout() verlĂ€sst, um zu prĂŒfen, ob die Verbindung noch besteht oder nicht. Es gibt jedoch Berichte ĂŒber gedrosselte Timer auf der Browserseite, die zufĂ€llige VerbindungsabbrĂŒche auslösen können.

Eine Lösung wÀre, dass ping vom Server an den Client ausgegeben wird, aber das ist eine Breaking Change, die auch andere Client-Implementierungen beschÀdigen wird.

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

  • [x] Aktualisieren Sie den Quellcode in jedem Projekt auf ES6

  • [x] Migrieren Sie auf Webpack 4 (oder einen anderen Bundler, falls erforderlich)

  • [ ] Entfernen Sie die Sticky-Session-Anforderung, wenn Sie mehrere Knoten verwenden

  • [ ] StandardmĂ€ĂŸig Websocket verwenden und XHR-Polling als Fallback verwenden

Derzeit wird die Abfrage zuerst eingerichtet und dann, wenn möglich, auf Websocket aktualisiert.

  • [x] Machen Sie die Methode generateId asynchron

Dies ist auch eine bahnbrechende Änderung. Verwandte: https://github.com/socketio/engine.io/pull/535

  • [ ] Aktualisieren Sie die Typescript-Bindungen, falls erforderlich

  • [ ] Triage-Probleme

Derzeit kein Veröffentlichungsdatum, da ich nicht sicher bin, wie viel Zeit ich diesen Punkten in den nÀchsten Wochen widmen kann. Aber jede Hilfe ist willkommen!

Hilfreichster Kommentar

[email protected] und [email protected] wurden veröffentlicht :fire:

Ein paar Anmerkungen:

  • die öffentliche API Ă€ndert sich nicht viel (ein paar Methoden wurden jedoch entfernt, siehe hier und hier als Referenz)
  • Die Codebasis wurde auf TypeScript migriert, aber einige Eingaben fehlen, insbesondere auf der Client-Seite.
  • die Breaking Changes in Engine.IO v4 ( hier aufgefĂŒhrt) wurden aufgenommen
  • Die Client-Bundle-GrĂ¶ĂŸe hat sich etwas erhöht, obwohl es weniger AbhĂ€ngigkeiten gibt, ich werde darauf eingehen

Jedes Feedback ist willkommen!

Alle 51 Kommentare

Sieht nach einem tollen Plan aus.

Ich wechsle von nodejs zu golang und habe festgestellt, dass es keine socket.io 2-Implementierung gibt.
https://github.com/googollee/go-socket.io/issues/188

Was halten Sie von der Golang-Server-UnterstĂŒtzung fĂŒr v3? Gerne beteilige ich mich an dieser Entwicklung.

@theromis sprechen Sie von einem Golang-Client (der eine Verbindung zum Node.js-Server herstellt) oder einem tatsÀchlichen Golang-Server? (Ich denke, hier wurde auch etwas gearbeitet: https://github.com/graarh/golang-socketio)

@darrachequesne Vielen Dank fĂŒr die schnelle Antwort, ja, ich spreche von serverseitigem Golang-Socketio.
Das von Ihnen erwÀhnte Projekt ist fast tot (letztes Commit vor mehr als einem Jahr).
https://github.com/googollee/go-socket.io Projekt sucht Betreuer.
Und keiner von ihnen unterstĂŒtzt socket.io v2.
Ich dachte, die grĂ¶ĂŸten Nodejs-Socketio-Entwickler könnten auch an der Golang-Entwicklung interessiert sein :)

Aktualisierter Java-Client wÀre auch schön.

Ein socket.io-Paket fĂŒr serverseitigen Swift wie https://github.com/vapor wĂ€re auch sehr nett, da es bereits einen Swift-Client gibt.

Klingt so, als ob serverseitig socket.io in einer nativen Sprache wie C/C++ geschrieben wird, es ĂŒberall verwendet werden kann, einschließlich nodejs, golang, java, rust und was auch immer ...
Was ist falsch an diesem Ansatz?
Meine persönliche Meinung socket.io ist wie de facto Standard fĂŒr die moderne Welt. Warum nicht ideal machen?

Eine Sache, die mich immer an socket.io gestört hat und die in der nÀchsten Hauptversion behoben werden könnte, könnte https://github.com/socketio/socket.io/issues/2124 und https://github.com sein

Es gab eine historische Inkonsistenz bei der Handhabung von Namespaces und Middlewares.
Außerdem macht das client , das ein reconnect -Ereignis ausgibt, meiner Meinung nach mehr Sinn, nachdem es sich mit namespace verbindet, anstatt nur das Wiederverbindungsereignis des Managers zu sein ... Zum Beispiel , wenn ein Authentifizierungsfehler in einer Sub-Namespace-Middleware auftritt, erhĂ€lt der Client immer noch ein Wiederverbindungsereignis, was meiner Meinung nach kontraintuitiv ist.

Ab der Node-Version 10.5 gibt es einen neuen Worker-Thread, der sich derzeit im experimentellen Zustand befindet, aber wenn er veröffentlicht wird, kann er meiner Meinung nach eine bessere Möglichkeit fĂŒr die Verwendung von socket.io sein, anstatt den Redis-Server zu verwenden.

Profi:

  • weniger AbhĂ€ngigkeit (redis)
  • native UnterstĂŒtzung von Multi-Threading
  • mehr Kontrolle

Nachteil:

  • funktioniert nur ab dieser nodejs-Version, die den Worker-Thread (10.x || 11) freigibt. Aber das lĂ€sst sich umgehen.

@Zwei ist interessant! Es wĂŒrde fĂŒr Worker auf demselben Host funktionieren, aber was ist mit mehreren Hosts?

@perrin4869 gute Idee :+1:

Ich habe hier viele Ideen hinterlassen: #3311 bitte lesen :) Werde das hier schließen und die Diskussion fortsetzen.

@MickL hÀtten Sie etwas Zeit, um das socket.io- Repository beispielsweise auf Typescript zu migrieren?

Ich fĂŒrchte, mein Wissen ĂŒber Netzwerktechnologie und Informationssicherheit ist begrenzt. Ich verlasse mich auf High-Level-Frameworks wie Express oder Socket.io.

Soweit ich sehe, ist socket.io bereits OOP geschrieben und gut dokumentiert, so dass es ein Kinderspiel wĂ€re, es einfach zu portieren. Meine Idee war es, so modular wie möglich vorzugehen, damit jemand wie ich einfacher etwas beitragen kann und der Kunde baumerschĂŒtterbar ist. Es könnte auch eine Idee sein, reaktiver zu werden, um die Dinge einfacher zu machen. Wie auch immer, ich bin nicht genug in den Code, also könnten beide Ideen in diesem Projekt möglicherweise keinen Sinn machen.

@darrachequesne ist eine gute Frage. Ich werde darĂŒber nachdenken.

Benötigen Sie Nodejs 8 und höher, da frĂŒhere Versionen bestenfalls gewartet werden, siehe https://nodejs.org/en/about/releases/ , zumindest sollte nodejs 4 fallen gelassen werden (ich habe aus .travis.yml bemerkt, dass Sie es unterstĂŒtzen es)

Wurde in einem Branch/Repo mit 3.0-bezogenen Arbeiten begonnen? Ich schaue nur, ob es einen Ort gibt, an dem man darĂŒber informiert bleiben kann, wie es lĂ€uft oder einen Beitrag leistet.

Ich wĂŒrde mir eine verbesserte UnterstĂŒtzung fĂŒr die Fehlerbehandlung auf der Serverseite wĂŒnschen. Dies wurde in einigen anderen Ausgaben angesprochen, aber genauer gesagt wĂ€re es großartig, wenn:

  1. ZusĂ€tzlich zum Standard wurde eine benutzerdefinierte Fehlerbehandlungs-Middleware unterstĂŒtzt. Dies könnte in etwa so aussehen wie bei Express (das als letztes in der Kette von app.use() angehĂ€ngt werden kann, Ă€hnlich wie socket.use() , Middlewares): https://expressjs.com/en/guide/error -handhabung.html

Das Problem besteht derzeit darin, dass es keine Möglichkeit gibt, einem Fehler irgendeine Art von Nachverfolgung oder Protokollierung hinzuzufĂŒgen, sobald er nexted war.

  1. Da der 'error'-Namespace auf der schwarzen Liste steht, socket.emit('error', err) wird der Client nicht hören), kann ich nicht emit einen Fehler irgendwo auf dem Server feststellen, der nicht einfach ist Zugriff auf next() (dh innerhalb von socket.on('event') ). Dies macht es schwierig, eine einheitliche Fehlerbehandlungslösung zu erstellen.

  2. next(err) sollte statt eines Strings ein Error -Objekt senden. Ich verstehe, dass es dafĂŒr eine Problemumgehung gibt (https://github.com/socketio/socket.io/issues/3371), indem eine magische .data -Eigenschaft zu jedem Objekt hinzugefĂŒgt wird, das Sie next() nennen an. Dies ist jedoch nicht dokumentiert und nicht intuitiv.

Im Allgemeinen erscheint next(err) wie eine unnötige Blackbox mit sehr begrenzter FehlerbehandlungskapazitÀt.

Danke fĂŒr deine MĂŒhe und bleib dran!

@darrachequesne Gibt es ein Update zu v3, das RealitĂ€t ist? Seit 2018 sehe ich diesbezĂŒglich keine Fortschritte.

Ein kurzes Update: Mein aktueller Vertrag wurde kĂŒrzlich aktualisiert, und ich sollte in der Lage sein, einen Tag pro Woche (1/5) der Projektpflege zu widmen. Daher sollte die Arbeit an v3 in KĂŒrze wieder aufgenommen werden.

Wirklich daran interessiert, bei diesem Projekt auf die eine oder andere Weise zu helfen.

Wenn es eine Möglichkeit gibt, herauszufinden, wie ich dies tun kann, lassen Sie es mich wissen - ich möchte nur möglicherweise keine Dinge reparieren, damit sie nicht zusammengefĂŒhrt werden! Also lieber auf eine Anleitung warten, falls Hilfe benötigt wird. Prost

  • Komprimierung (gzip, zlib, defalte/inflate)
  • Überarbeitungsmechanismus zum Senden von BinĂ€rdaten (jetzt 2 Pakete ... ws Text und ws Binary)
  • Metadaten bei Verbindung senden (Komprimierung verwenden?)
  • Coder/Encoder als Plugins enthalten benutzerdefinierte (messagepack, protobuf usw.), wir könnten Generika verwenden, wenn der Code in Typoskript umgeschrieben wird
  • Zertifikat-Pinning (server-/clientseitig)

@blackkopcap

Komprimierung (gzip, zlib, defalte/inflate)

Komprimierung wird bereits unterstĂŒtzt (https://github.com/socketio/engine.io/blob/a05379b1e87d2e4cde40d3e30b134355883f4108/lib/transports/polling.js#L249-L298). Die WebSocket-Komprimierung ( perMessageDeflate ) wird in v3 jedoch standardmĂ€ĂŸig deaktiviert, da sie viel zusĂ€tzlichen Speicher benötigt.

Überarbeitungsmechanismus zum Senden von BinĂ€rdaten (jetzt 2 Pakete ... ws Text und ws Binary)

Völlig einverstanden. Karte hier hinzugefĂŒgt

Metadaten bei Verbindung senden (Komprimierung verwenden?)

Ich bin mir nicht sicher ob ich das verstehe. Könnten Sie bitte den Anwendungsfall erlÀutern?

Coder/Encoder als Plugins enthalten benutzerdefinierte (messagepack, protobuf usw.), wir könnten Generika verwenden, wenn der Code in Typoskript umgeschrieben wird

Sie sollten bereits in der Lage sein, Ihren eigenen Parser wie socket.io-msgpack-parser bereitzustellen

Zertifikat-Pinning (server-/clientseitig)

:+1:, hier hinzugefĂŒgt.

@michaelegregious

  1. ZusĂ€tzlich zum Standard wurde eine benutzerdefinierte Fehlerbehandlungs-Middleware unterstĂŒtzt. Dies könnte in etwa so aussehen wie bei Express (das als letztes in der Kette von app.use() angehĂ€ngt werden kann, Ă€hnlich wie socket.use() , Middlewares): https://expressjs.com/en/guide/error -handhabung.html

Das wĂ€re in der Tat großartig. Hier hinzugefĂŒgt

  1. Da der 'error'-Namespace auf der schwarzen Liste steht ( socket.emit('error', err) wird vom Client nicht gehört), kann ich nicht emit einen Fehler irgendwo auf dem Server erkennen, der nicht einfach ist Zugriff auf next() (dh innerhalb von socket.on('event') ). Dies macht es schwierig, eine einheitliche Fehlerbehandlungslösung zu erstellen.

Nicht sicher, was wir tun könnten. Haben Sie einen Vorschlag?

  1. next(err) sollte statt eines Strings ein Error -Objekt versenden. Ich verstehe, dass es dafĂŒr eine Problemumgehung gibt (https://github.com/socketio/socket.io/issues/3371), indem eine magische .data -Eigenschaft zu jedem Objekt hinzugefĂŒgt wird, das Sie next() nennen an. Dies ist jedoch nicht dokumentiert und nicht intuitiv.

Stimme voll und ganz zu :+1: , hier hinzugefĂŒgt

Wir haben bereits Engine.IO v4 veröffentlicht, das in Socket.IO v3 enthalten sein wird. Die Versionshinweise finden Sie hier .

Ich habe das, was ich in diesem Thread finden konnte, dem Projekt hier hinzugefĂŒgt, um einen Überblick ĂŒber den Fortschritt zu geben. Zögern Sie nicht zu kommentieren!

Folgendes hatte ich im Sinn, um https://github.com/socketio/socket.io/issues/2124 zu reparieren

Der Client sendet nun ein CONNECT -Paket, wenn er Zugriff auf den Standard-Namespace ( / ) erhalten möchte (keine implizite Verbindung mehr).

Dies wĂŒrde bedeuten, dass die fĂŒr den Standard-Namespace registrierten Middlewares nicht mehr fĂŒr Clients gelten, die Zugriff auf einen nicht standardmĂ€ĂŸigen Namespace erhalten möchten

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

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

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

Auf der Client-Seite sollten wir meines Erachtens auch klar zwischen der Option query fĂŒr den Manager (die in den Abfrageparametern enthalten ist) und der Option query fĂŒr den Socket (die wird im Paket CONNECT gesendet).

Im Augenblick:

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

fĂŒhrt zu Anfragen wie GET /socket.io/?transport=polling&abc=def und auch zu einem CONNECT-Paket wie { "type": 0, "nsp": "admin?abc=def"}

Da es außerdem kein CONNECT -Paket fĂŒr den Standard-Namespace gibt, wird das query des Sockets in diesem Fall derzeit ignoriert.

Ich schlage vor, es stattdessen in authQuery umzubenennen.

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

wĂŒrde zu Anfragen wie GET /socket.io/?transport=polling&abc=def und einem CONNECT-Paket wie { "type": 0, "nsp": "/", "data": { abc: '123' } } fĂŒhren

@perrin4869 wĂŒrde es Sinn machen?

Bearbeiten: In Bezug auf Kompromisse gibt es beim Start mehr HTTP-Anforderungen ...

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

WĂ€hrend wir derzeit haben:

// 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 Vielen Dank, dass Sie dies berĂŒcksichtigen! Es ist schön, hier einen Abschluss zu bekommen, endlich in der Lage, den Code zu vereinfachen, den ich damals hatte: D
Es ist lange her, also erinnere ich mich nicht genau, aber das klingt nach der Lösung, die ich anstrebte
Aus Neugier, was ist der Grund fĂŒr die Kompromisse?

Nach der Idee, wie js-Formen funktionieren: https://web.archive.org/web/20200201163000/https ://mathiasbynens.be/notes/shapes-ics. WĂ€re es nicht besser, Arrays zum Speichern von Referenzen fĂŒr Socket-Verbindungen zu verwenden, um die Leistung zu verbessern? Immer mehr Verbindungen, unzĂ€hlige IDs und die Verwendung von Objekten, um dies zu tun, mit jeder neuen Verbindung wird eine neue Form generiert und mehr Speicher verbraucht, abhĂ€ngig von der Lebensdauer eines Knotens und der Anzahl der Verbindungen, die er haben kann, wird dies wahrscheinlich sein einige negative Auswirkungen auf die Leistung.

@perrin4869 Die Kompromisse ergeben sich aus der aktuellen Implementierung, da wir zuerst die Engine.IO-Verbindung herstellen und dann mit der Socket.IO-Verbindung fortfahren. Was ergibt, wenn der HTTP-Long-Polling-Transport aktiviert ist (was die Standardeinstellung ist):

  • eine HTTP GET-Anforderung zum Abrufen des Engine.IO-Handshakes
  • eine HTTP-POST-Anforderung zum Senden des Socket.IO CONNECT -Pakets
  • eine HTTP GET-Anfrage, um das Socket.IO CONNECT -Paket vom Server abzurufen
  • und dann das Upgrade auf WebSocket

Aber es ist sicherlich verbesserungswĂŒrdig. Als Referenz wurde die Änderung hier und hier implementiert.

Außerdem wird das Ereignis reconnect nicht mehr von der Socket-Instanz (clientseitig) ausgegeben ( hier ).

@ferco0 verwenden wir jetzt ein Map anstelle eines einfachen Objekts (https://github.com/socketio/socket.io/commit/84437dc2a682add44bb57d03f703cfc955607352). Gilt Ihr Kommentar in diesem Fall immer noch?

[email protected] und [email protected] wurden veröffentlicht :fire:

Ein paar Anmerkungen:

  • die öffentliche API Ă€ndert sich nicht viel (ein paar Methoden wurden jedoch entfernt, siehe hier und hier als Referenz)
  • Die Codebasis wurde auf TypeScript migriert, aber einige Eingaben fehlen, insbesondere auf der Client-Seite.
  • die Breaking Changes in Engine.IO v4 ( hier aufgefĂŒhrt) wurden aufgenommen
  • Die Client-Bundle-GrĂ¶ĂŸe hat sich etwas erhöht, obwohl es weniger AbhĂ€ngigkeiten gibt, ich werde darauf eingehen

Jedes Feedback ist willkommen!

@darrachequesne das ist ok.

@darrachequesne Viele npm-Open-Source-Projekte versuchen, die Anzahl der AbhĂ€ngigkeiten zu verringern. Es ist ein gewisser Trend innerhalb der Community. Der Hauptgrund dafĂŒr ist, dass viele Organisationen verlangen, dass Lizenzen aller verwendeten AbhĂ€ngigkeiten ĂŒberprĂŒft werden, wenn sie in Projekten verwendet werden, um keine rechtlichen Probleme zu bekommen. Weniger AbhĂ€ngigkeiten zu haben hilft dabei natĂŒrlich. Als Beispiel wurde Helm (ein großartiges Sicherheitspaket fĂŒr den Express-Webserver) in der neuesten Version 4.0 auf eine Null-AbhĂ€ngigkeits-Installation umgestellt.

Gibt es vor diesem Hintergrund einen Plan, die Anzahl der AbhÀngigkeiten in socket.io in Release 3 zu verringern?

@thernstig das ist eine gute Frage! Wir haben tatsÀchlich versucht, die Anzahl der AbhÀngigkeiten in Socket.IO v3 zu reduzieren:

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

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

Hier ist der AbhĂ€ngigkeitsbaum fĂŒr den 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

Ich denke, dass wir nur den dist/ -Ordner des socket.io-client -Pakets benötigen, daher könnte es sinnvoll sein, ein socket.io-client-dist $-Paket ohne AbhÀngigkeiten zu erstellen. Was denken Sie?

Hinweis: Steckdose. [email protected] und Sockel. [email protected] wurden veröffentlicht

Ich habe einige Beispiele mit ES-Modulen und TypeScript hinzugefĂŒgt.

@darrachequesne Das ĂŒberlasse ich ganz deinem Ermessen 😄

@michaelegregious in Bezug auf Ihren Kommentar , ich weiß, es ist eine ganze Weile her, aber hatten Sie eine bestimmte API im Sinn?

Ich stimme zu, dass die aktuelle API verbessert werden könnte. Es wurde implementiert, um einen Catch-All-Listener zu haben (wird hier besprochen), und nicht mit Blick auf die Fehlerbehandlung.

Wir könnten auch eine Möglichkeit hinzufĂŒgen, Benutzer vor unbehandelten Ereignissen zu warnen (404-Antworten in Express, http://expressjs.com/en/starter/faq.html#how-do-i-handle-404-responses).

@darrachequesne schön zu hören, dass du an der nĂ€chsten Version von socket.io arbeitest !! Vielen Dank im Voraus fĂŒr all Ihre Arbeit an dieser Bibliothek.

Socket teste ich gerade. [email protected] und Socket. [email protected] und ich versuche, die neue Syntax zu verwenden, um einem Raum beizutreten und an Steckdosen in diesem Raum zu senden.

Ich kann den Server nicht dazu bringen, mit Ihrem Beispiel in der Änderungsprotokolldatei an den Client-Socket zu senden.

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

Im Anhang sind Screenshots, die die auf dem Client verwendete Socket-js-Datei und den Code fĂŒr den node.js-Server zeigen

clientseitige js-Datei
Screen Shot 2020-10-28 at 12 04 43 AM

clientseitiges socket.on-Ereignis
Screen Shot 2020-10-28 at 12 07 08 AM

serverseitige Join-Syntax innerhalb von io.on("connect",
Screen Shot 2020-10-28 at 12 06 36 AM

Ich habe alle Methoden im letzten Screenshot ausprobiert, um es an den Client zu senden, und nichts funktioniert.

Bitte lassen Sie mich wissen, wenn Sie weitere Informationen benötigen.

Danke

@darrachequesne Ich habe auf 3.0.0-rc2 heruntergestuft und trete dem Raum bei, indem ich join mit der Callback-Methode namens "room1" verwende, die ausgelöst wird, aber keines der Emit-Ereignisse an den Client gesendet wird

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

Ich habe auch 3.0.0-rc2 deinstalliert und socket.io 2.3.0 fĂŒr Server und Client installiert und bestĂ€tigt, dass der obige Code wie erwartet funktioniert. Ich glaube also, dass bei den 3.0.0 rc-Versionen etwas kaputt ist

@szarkowicz Hmm ... Ich kann das von Ihnen beschriebene Verhalten nicht reproduzieren: https://github.com/socketio/socket.io-fiddle/tree/issue/v3

Der folgende Code scheint wie erwartet zu funktionieren:

socket.join("room1");

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

Bekommst du einen Fehler in der Konsole? Erhalten Sie ein connect -Ereignis auf der Client-Seite?

@darrachequesne danke fĂŒr die BestĂ€tigung. Ich habe es auf die Verwendung des redisAdapter zurĂŒckgefĂŒhrt, der das Problem verursacht. Sobald ich den folgenden Code auskommentiere, funktioniert die rc3-Version von socket.io wie erwartet.

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

Haben Sie versucht, redis mit der v3 von socket.io zu verwenden?

Danke

@szarkowicz ja, Sie haben absolut Recht, der Redis-Adapter muss aktualisiert werden, um mit Socket.IO v3 kompatibel zu sein, er wird direkt nach der Veröffentlichung von 3.0.0 aktualisiert (was bald sein sollte).

Auf jeden Fall vielen Dank fĂŒr das Feedback :+1:

@darrachequesne okay hört sich gut an!!! Ich werde if vorerst einfach nicht verwenden und ohne es weiter testen.

Gibt es eine Zeit, zu der Sie glauben, dass v3 veröffentlicht wird?

Keine Sorge - nochmals vielen Dank, dass Sie sich bei mir gemeldet haben und an allen Verbesserungen fĂŒr die nĂ€chste Version gearbeitet haben!!

@darrachequesne Vielen Dank fĂŒr diese Updates! Sorry fĂŒr meine verspĂ€tete Antwort! Wir verwenden socket.io nicht in meinem aktuellen Projekt (obwohl wir es möglicherweise in Zukunft integrieren werden), aber die Problemumgehung, die ich in meinem letzten Projekt verwendet habe, war die Verwendung socket.emit('err', err) anstelle des privilegierten Namespace socket.emit('error', err) .

Hier ist die Notiz, die ich in die Readme-Datei unserer App eingefĂŒgt habe, um das Problem zu erklĂ€ren:

#### 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.)

Wenn Sie also noch einmal darĂŒber nachdenken, wenn Sie bereits die Möglichkeit zum HinzufĂŒgen einer benutzerdefinierten Middleware zu next(err) integriert haben, ist es auch möglich, die Verwendung des socket.emit('error', err) -Namespace fĂŒr die manuelle Verwendung auf der Server?

Ich schaue auf diesen Code zurĂŒck und alle meine Event-Handler sehen so aus (wenn es hilfreich ist zu sehen):

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

Oh! Noch eine Sache, an die ich mich erinnere. Hier ist eine Problemumgehung, die ich verwendet habe, um ausgehende Ereignisse zum Zweck der Protokollierung/Fehlerbehandlung ĂŒberwachen zu können:

  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.

So habe ich die ausgehende Middleware verwendet, wenn es hilfreich ist, sie zu sehen:

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;
  }
}

Nochmals vielen Dank fĂŒr all Ihre harte Arbeit! Ich versuche das nĂ€chste mal schneller zu antworten.

  1. Da der 'Fehler'-Namespace auf der schwarzen Liste steht ( socket.emit('error', err) wird vom Client nicht gehört), kann ich nicht emit einen Fehler irgendwo auf dem Server erkennen, der nicht einfach ist Zugriff auf next() (dh innerhalb von socket.on('event') ). Dies macht es schwierig, eine einheitliche Fehlerbehandlungslösung zu erstellen.

Nicht sicher, was wir tun könnten. Haben Sie einen Vorschlag?

@michaelegregious danke fĂŒr die Beispiele, die Sie bereitgestellt haben. (und kein Problem fĂŒr die Verzögerung!)

Technisch gesehen bin ich mir nicht sicher, ob wir die Fehler abfangen können, die von einem asynchronen Listener ausgelöst werden:

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

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

Daher denke ich, dass es besser ist, den Benutzer die Fehler selbst behandeln zu lassen, entweder mit dem von Ihnen bereitgestellten Code ( socket.emit("err", err); ) oder mit einer BestÀtigungsfunktion:

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

Was denken Sie?

Was ist derzeit fĂŒr v3 implementiert:

  • "error" wird in "connect_error" umbenannt und ist nur auf Namespace-Middleware-Fehler beschrĂ€nkt:
// server
io.use((socket, next) => {
  next(new Error("unauthorized"));
});
// client
socket.on("connect_error", (err) => {
  // err instanceof Error === true
  // err.message === "unauthorized"
})

Das bedeutet auch, dass „Fehler“ kein reservierter Ereignisname mehr ist.

  • socket.use() wird entfernt und durch socket.onAny() ersetzt (Server und Client)
// server
io.on("connect", (socket) => {
  socket.onAny((event, ...args) => {

  });
});

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

Klingt es gut fĂŒr dich? Hast du irgendwelche VorschlĂ€ge?

Hallo allerseits!

Steckdose. [email protected] und Sockel. [email protected] sind aus. Sie können sie mit npm i socket.io<strong i="10">@beta</strong> socket.io-client@beta testen.

Wir planen, 3.0.0 bis nÀchste Woche zu veröffentlichen. Der Migrationsleitfaden wurde erstellt: https://socket.io/docs/migrating-from-2-x-to-3-0/ (einige Details fehlen, wie die reservierten Ereignisse auf der Client-Seite)

Feedback ist wie immer willkommen!

Ich habe Zweifel, ich weiß nicht, ob hier der richtige Ort dafĂŒr ist, aber es ist möglich, die Socket-ID bei der Verbindung zu definieren, um beispielsweise die Client-ID von db zu verwenden? Das Ändern der "id"-Prop des Socket-Objekts in der Verbindungs-Middleware fĂŒhrt zur Synchronisierung mit dem Client?

@darrachequesne Danke fĂŒr das RC4-Update.
Mit Version 3.0.0.rc4 - 2 Fragen:

  1. Was ist der beste Weg, um die Anzahl oder Liste der Steckdosen (Clients) in einem Raum zu erhalten?
  2. Wie bekomme ich am besten eine Liste aller aktuellen Zimmer?

Ich werde in den nĂ€chsten Tagen viele Tests mit rc4 durchfĂŒhren.

Nochmals vielen Dank fĂŒr all Ihre harte Arbeit.

@ferco0 derzeit nicht möglich, die Socket#id wird hier generiert . Was passiert in Ihrem Beispiel (Client-ID von db), wenn derselbe Benutzer einen neuen Tab öffnet? (da die Socket#id eindeutig sein muss)

@szarkowicz

  1. Was ist der beste Weg, um die Anzahl oder Liste der Steckdosen (Clients) in einem Raum zu erhalten?

io.allSockets() => alle Socket-IDs abrufen (funktioniert mit mehreren Servern) (na ja, sobald der Redis-Adapter aktualisiert ist)
io.in("room1").allSockets() => Alle Socket-IDs im Raum abrufen

(in Socket.IO v2 hieß es io.clients() )

  1. Wie bekomme ich am besten eine Liste aller aktuellen Zimmer?

DafĂŒr gibt es derzeit keine API, abgesehen vom Eingraben in den Adapter: io.of("/").adapter.rooms ( hier )

Außerdem verfĂŒgt der Redis-Adapter ĂŒber eine allRooms -Methode, die sich jedoch nicht in der öffentlichen API widerspiegelt.

Okay, ich weiß die Informationen sehr zu schĂ€tzen, um die Kunden und RĂ€ume fĂŒr beide mit Redis und Non Redis zu bekommen. Ich werde wahrscheinlich nur mit socket.io v3 testen, bis der Redis-Adapter aktualisiert ist.

Migrieren Sie auf Webpack 4 (oder einen anderen Bundler, falls erforderlich)

Alternativ können Sie sich auch https://github.com/formium/tsdx ansehen.
Ich wollte vor einigen Monaten mit tsdx eine Neufassung von socket.io & engine.io in Typescript pushen, fand aber keine Zeit dafĂŒr :smile:

:rocket: Socket.IO v3.0.0 ist da! :rocket: Die Release Notes finden Sie hier: https://socket.io/blog/socket-io-3-release/

Danke an alle Beteiligten in diesem Thread fĂŒr eure Ideen/Feedback :heart:

@darrachequesne , das macht fĂŒr mich alles Sinn. Ich habe das Thema vergessen bzgl. asynchrone Middleware (in meinem aktuellen Projekt haben wir fĂŒr jede Express-Route eine wrap() -Funktion erstellt, um genau dieses Problem zu lösen, damit keine Fehler durchs Raster fallen).

Danke fĂŒr alle Verbesserungen!

Klingt es gut fĂŒr dich? Hast du irgendwelche VorschlĂ€ge?

asynchrone Middleware

@michaelegregious könntest du bitte eine Funktionsanfrage dafĂŒr öffnen? Danke!

Ich werde dieses Thema jetzt schließen. Diskussion ĂŒber die Veröffentlichung: https://github.com/socketio/socket.io/discussions/3674

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen