Monday 20 November 2017

Websocketpp Binary Options


Posted in Protokolle Vor kurzem hatte ich einen Websocket-Server zu einem C-Projekt hinzufügen. Einige Untersuchungen zeigten, dass die Optionen hier zuviel sind. Es gibt einige C-basierte Optionen, und man kann natürlich das Websocket-Modul aus den POCO-Bibliotheken 1 auswählen, wenn man einen C-Ansatz wünscht. Da dieses spezielle Projekt in C geschrieben wird, ist eine reine C-Lösung, vorzugsweise unabhängig, bevorzugt. Schließlich wählte ich die (kreativ benannte) Websocket-Bibliothek 2, auch als Websocketpp bezeichnet. Hauptargumente hier waren, wie erwähnt, eine objektorientierte C-Lösung ohne signifikante Abhängigkeiten sowie eine einfache Implementierung, da sie eine Header-only-Bibliothek ist. Websocket ist eine ziemlich modulare Bibliothek, die starken Einsatz von Templating, um verschiedene Konfigurationen, Endpunkte und ähnliches zu einem zusammenhängenden Ganzen zusammenzubauen. Als Basis für das Transportmodul können beispielsweise Iostreams (sehr langsam) und ASIO gewählt werden. Für letztere können Sie zwischen Boost ASIO und Stand-alone-ASIO wählen. Es gibt auch die Möglichkeit, keine C11-Features zu verwenden und stattdessen die Boost-Alternativen zu verwenden. Da es sich bei diesem Projekt um eine Reihe von Compile-Targets handelte, die nicht alle einen C11-fähigen Compiler enthielten, hatte die endgültige Konfiguration eine Boost-Abhängigkeit mit ihrer ASIO - und Systembibliothek sowie verschiedene andere Header-only-Abhängigkeiten zur Folge. Nach dem Start der eigentlichen Integration der Bibliothek in mein Projekt habe ich jedoch festgestellt, dass die Qualität der Dokumentation sehr8230 suboptimal ist. Die Dokumentation ist aufgeteilt zwischen der GitHub-Site und der eigenen Website von author8217, wobei die meisten dieser Dokumente vollständig und völlig veraltet sind. Erst nach signifikanten Mengen an Versuch und Irrtum gelang es mir, eine voll funktionsfähige Umsetzung zu erreichen. Um anderen die Mühe zu ersparen, möchte ich hiermit eine (vereinfachte und geänderte) Version meiner Implementierung vorstellen. Ich hoffe, es wird nützlich sein. Let8217s bewegen sich in die Header-Datei unserer Implementierung: Mit diesen beiden werden wir aus der Websocket-Serverrolle auswählen und die ASIO-Konfiguration ohne TLS-Feature zur Verfügung stellen, dh keine verschlüsselten Verbindungen. Unsere Klassendefinition implementiert eine statische Klasse. Dadurch können wir die Websocket-Funktionalität aus mehreren Klassen nutzen. Websocket ist threadsicher, so dass wir uns nur darum kümmern müssen, ist der Multi-Thread-Zugriff auf unsere eigenen Datenstrukturen und Variablen. Bei der Implementierung sehen wir zunächst die üblichen statischen Initialisierungen und das Namespace-Mischen: Als nächstes wird die Bibliothek und die Serverinstanz initialisiert: Wenn wir die ASIO-Transportoption verwenden, rufen wir hier ihre init-Methode auf. Vielleicht möchten wir die Logging-Ausgabe auf unsere eigene Logging-Methode umleiten. Websocket8217s Basic Logger ermöglicht es uns, eine ostream Alternative für die Standard-std :: cout und std :: cerr gesetzt. Wir werden das später noch genauer betrachten. Als nächstes setzen wir die Message-Handler. Dies sind alle Rückruf-Methoden, die wir in einem Moment definieren werden. Wenn die Konfiguration abgeschlossen ist, können wir mit dem Transport-Framework anfangen zuzuhören. Dies geschieht mit dem Aufruf von listen () auf dem Server-Objekt. Diese Methode ist nicht ausnahmslos, so dass wir sie mit einem try / catch-Block umgeben. Schließlich nehmen wir Verbindungen an. Wir müssen nur den Server richtig jetzt starten, was in der folgenden Funktion erfolgt ist: Wieder ist dies eine andere Methode, die isn8217t Ausnahme-frei, so dass wir es mit einem try / catch-Block umgeben müssen. Der andere Anhaltspunkt hier ist, dass, wenn wir den Server an einem gewissen Punkt beenden, müssen wir für diesen (blockierenden) run () Aufruf warten, bevor wir zum Beispiel einen Thread beenden zu warten. Das Herunterfahren des Websocket-Servers ist ziemlich offensichtlich: Zuerst hören wir auf zu hören. Das bedeutet, dass wir keine neuen Verbindungen mehr akzeptieren werden. Als nächstes gehen wir durch alle Web-Verbindungen, die wir noch haben und schließen jeden einzelnen von ihnen. Schließlich nennen wir stop () auf dem Server-Objekt. Diese isn8217t unbedingt notwendig, aber es wird sicherstellen, dass das Transport-Backend vollständig heruntergefahren ist und alle verbleibenden Verbindungen kraftvoll beendet. Let8217s auf, um tatsächlich akzeptieren neue Verbindungen. Dazu können wir eine Anzahl von Handlern 3 verwenden, einschließlich open () und validate. Ich wählte die Validierung Handler, da es erlaubt, eingehende Verbindungen zu filtern und ablehnen, die nicht authentisch authentifizieren oder wie: Dieser Code zeigt, wie die Verbindung hinter einem Verbindungshandle von Websocket zu erhalten und zu extrahieren die URI einschließlich ihrer Abfrage-Parameter-String aus es. Hier nehmen wir an, dass der Verbindungsclient eine stringbasierte ID bereitstellen muss, obwohl man auch einen anderen Identifier verwenden kann, basierend auf der Implementierung. Wir verwenden pthreadbasierte Sperren um die websockets-Karte, um sicherzustellen, dass kein gleichzeitiger Zugriff auf diese Datenstruktur stattfindet und fügen Sie das neue Websocket-Handle mit seiner ID als Schlüssel ein. Wir können auch die failed () und close () Handler implementieren: Für den Fail-Handler können wir die Verbindung wie zuvor erhalten und das Fehlercode-Objekt extrahieren, um den Grund für den Fehler zu erlernen. Der Handler sollte im Allgemeinen ziemlich langweilig sein, aber es kann informativ sein, die Bestätigung in einem Protokoll oder so einer erfolgreich abgeschlossenen Verbindung zu haben. Wir müssen nur sehen, wie man Daten an eine solche Steckdose sendet. Diese Funktion erhält das entsprechende Verbindungshandle auf der Grundlage der ID und schreibt dann die bereitgestellten Daten zu dieser Verbindung. Die getWebsocket () - Methode ist ein trivialer STL-mapbasierter Find - und Iterationsaufwand und isn8217t wird hier weiter dokumentiert. Vergessen Sie nicht, die Karte zu sperren, während Sie die Find - und Iterator-Aktionen auf ihr ausführen. Schließlich, wie man eine Steckdose zu schließen: Hier erhalten wir wieder die richtige Verbindung zu behandeln, nur diesmal verwenden wir die 8216close8217-Methode anstelle von 8216send8217. Wir können einen engen Grund mit einem String zu senden, oder senden Sie einfach eine leere Zeichenfolge. Schließlich wird die ID aus der websockets map gelöscht und das nun ungültige Verbindungshandle mit ihr. Damit haben wir alles, was wir für den Websocket-Server benötigen, bis auf eine Sache: die Umleitung der Logging-Ausgabe von Websocket. Wir haben früher gesehen, dass wir die setostream () - Methode auf den Protokollschnittstellen verwenden. In der Klassendeklaration sahen wir diesen mysteriösen Typ 8216LogStream8217 und einen Ostream, und wieder in den statischen Initialisierungen. Was hier passiert, ist, dass diese LogStream-Klasse eine benutzerdefinierte Implementierung von std :: streambuf ist, die einem std :: ostream-Objekt zugewiesen wird, das dann die Standardausgabe-Websocket8217s-Protokollierung ersetzt. Für die eigentliche Streambuf-Implementierung würde man so etwas verwenden: Wir überschreiben einfach die virtuelle overflow () - Methode in der streambuf-Klasse. In der Standardimplementierung überschreitet der Standardpuffer für jedes Zeichen, das in die streambuf-Klasse geschrieben wurde, und somit wird für jedes Zeichen die Überlaufmethode aufgerufen. Mit einem String als Puffer erfassen wir jedes empfangene Zeichen und prüfen, ob es ein Zeilenvorschubzeichen ist oder nicht. Wenn es ist, haben wir eine komplette Zeile, die wir dann schreiben können, was auch immer Logging-Funktionalität, die wir in unserem Projekt verwenden. Danach leeren wir den Pufferstring und fahren mit der neuen Zeile fort. Abschließend muss ich sagen, dass trotz der Bemühungen, die es kostete mich, um eine funktionierende Integration von Websocket in meinem Projekt zu bekommen, ich glaube, es hat sich gelohnt. Technisch ist es eine gut gestaltete Bibliothek mit vielen coolen Features und dank seiner Template-basierten Natur Leichtigkeit der Erweiterung und Konfiguration, um unterschiedliche Zwecke zu erfüllen. Seine Hauptschwäche ist einfach die veraltete, fehlende und gelegentlich falsche Dokumentation und Beispiele. Hoffentlich wird dieser Artikel zumindest ein Teil des Problems beheben Java in vieler Hinsicht ist eine sehr exzentrische Programmiersprache. Das Lesen der designer8217s Antworten auf Fragen zu seinem Design führen zu interessanten Ideen, wie die unsigned Integer-Typen wäre verwirrend und fehleranfällig für den durchschnittlichen Programmierer. Es gibt auch den Gedanken, daß Java rein objektorientiert ist, obwohl es viele primitive Typen und Begriffe hat, die in ihren Tiefen lauern. Sein Design stellt sehr unangenehm Fragen für Entwickler, die zu lesen, zu schreiben und in der Regel handhaben binäre Daten und Dateien, wie die gesamte Sprache scheint auf Text-basierte Formate wie XML orientiert werden. Dies führt zu solchen Problemen wie die Implementierung eines grundlegenden binären Netzwerkprotokolls. Viele Netzwerk - und Kommunikationsprotokolle sind binär, da es dadurch einfacher und schneller zu analysieren, leichter zu übertragen und in der Regel weniger anfällig für Interpretationen ist. Die Frage ist hierbei, wie ein solches Protokoll in einer Sprache implementiert werden kann, die mit den Begriffen der vorzeichenlosen Ganzzahlen, der Operatorüberladung und ähnlichem nicht vertraut ist. Die eleganteste Antwort, die ich bis jetzt gefunden habe, ist, niedriges Niveau zu bleiben, und ich meine wirklich niedriges Niveau. Wir behandeln Java8217s eingebaute signierte Ganzzahlen, als ob sie unsigned mit bitweisen Operatoren sind, wo nötig, und verwenden Sie Byte-Arrays, um zwischen Java und der Außenwelt zu übersetzen. Der Byte-Typ in Java ist eine 8-Bit-Ganzzahl mit einem Bereich von -128 bis 127. Für unsere Zwecke ignorieren wir das Vorzeichenbit und behandeln es als vorzeichenlose 8-Bit-Integer. Die Netzwerkkommunikation erfolgt in Byteströmen, wobei die Empfangsseite diese gemäß einem vordefinierten Protokoll interpretiert. Dies bedeutet, dass auf der Java-Seite auf die Netzwerk-Socket schreiben müssen wir die erforderlichen Bytes in ein vorbereitetes Byte-Array setzen. Da Java-Arrays feste Größe wie in C haben, macht es am sinnvollsten, entweder ein Byte-Array pro Feld zu verwenden oder das gesamte Array zuzuordnen und die Bytes darin zu kopieren. Das Schreiben erfolgt über den OutputStream in den Java Socket, den wir in einen BufferedOutputStream umwandeln. Alle ASCII-Zeichenfolgen im Protokoll definieren wir als einzelne Bytes. Glücklicherweise gehen die ASCII-Codes nur auf 127 (0x7F) und passen somit in den positiven Teil des Java8217s-Bytetyps. Für Werte, die sich in den negativen Bereich des Bytes erstrecken, müssen wir möglicherweise Bitmaskierung verwenden, um mit dem Vorzeichenbit umzugehen oder die Konvertierung selbst durchzuführen. Wir definieren die Protokollversion als int (BE signiert, 32-bit), die wir mit einem einfachen Guss in ein Byte umwandeln und die höheren drei Bytes abziehen. Achten Sie wiederum auf den Wert der int. Wenn es8217s höher als 127 ist, müssen Sie erneut mit dem Vorzeichen-Bit umgehen oder einen Überlauf riskieren. In diesem Beispiel implementieren wir ein low-endian (LE) Protokoll. Dies bedeutet, dass bei der Umwandlung in ein Byte-Array von einer 16-Bit oder größer Integer, müssen wir die LSB zuerst platzieren, wie es in der Funktion intToByteArray () getan wird. Wir fügen auch eine Nachricht Länge Indikator am Anfang der Nachricht we8217re Senden in Form eines int, erweitert die Nachricht um 4 Bytes. Das Lesen und die Interpretation ist ähnlich: Dies ist eine kurze und naive Beispiel, die nur eine einzige Antwort lesen muss, überspringen die Nachricht Länge Indikator und das Lesen nur fünf Bytes. In einer komplexeren Anwendung konvertieren Sie die einzelnen Abschnitte des Bytearrays in die entsprechenden Formate (Strings, Ints usw.) und verifizieren diese. Hierfür würden Sie eine Funktion verwenden, die vom LE-order-Byte-Array in BE-order int wie folgt invertiert: In vielerlei Hinsicht ist es ironisch, dass Bitverschiebungen und bitweise Operatoren der Weg sind, um mit einer Sprache zu gehen, die sich selbst als hoch profiliert - Level-Sprache, aber das ist das Ergebnis der Design-Entscheidungen. Obwohl es wahr ist, dass der obige Byte-Array-orientierte Code von fancy-Klassen eingekapselt werden könnte, die die Langeweile aus der Implementierung eines solchen Protokolls herausnehmen würden, würden sie im Wesentlichen genau das gleiche tun, wie oben beschrieben. Mit dem kommenden Java 8 Release werden unsigned Integers erstmals in einer begrenzten Weise eingeführt, aber für die meisten Projekte (einschließlich Android-basierte) it8217s nicht eine Option, um es zu aktualisieren. Als Referenz wird der obige Code in einem aktuellen Projekt I8217m bearbeitet und ist soweit ich mich bewusst funktionieren. Ich kann jedoch keine Haftung für irgendetwas haywire, Anwendungen abstürzen, Heiraten zerrissen oder Haustiere in Brand gesetzt zu akzeptieren. Jede weitere Überprüfung und Behandlung von Fehlern ist wahrscheinlich eine großartige Idee, um den Code robuster zu machen. Unter den schrecklichsten und offiziell klingende Begriffe in der Computertechnik finden wir das Wort 8216protocol8217. Seine Bedeutung wirklich isn8217t, dass beängstigend, aber. Genau wie in anderen Kontexten verwendet, bedeutet alles, ist eine Sammlung von Vereinbarungen über, wie man über etwas gehen. In diesem Fall reden wir über Kommunikationsprotokolle, Protokolle, die es zwei oder mehr Geräten und / oder Anwendungen ermöglichen, miteinander zu kommunizieren. Ganz wie, wie Menschen ihre eigenen Kommunikationsprotokolle, im Grunde entwickelt haben. Wir machen auch ein Handshake-Teil, in dem wir die Verbindung initialisieren, egal ob es einander anlächelt, das schöne / schreckliche Wetter anmerkt oder etwas Bestimmtes verlangt, je nachdem, ob es vorherigen Kontakt gab oder nicht. Mögliche Ausfallmodi beinhalten das Ignorieren (Server-Time-out), das Erschüttern im Gesicht nach einer fehlgeschlagenen Abhollinie (Connection Closed By Host) oder unterbrochen durch den muskulären Freund girl8217 (Connection Reset By Peer) sowie die Adressierung der Falsche Person (Verbindung verweigert). Nach erfolgreichem Aufbau der Verbindung werden Informationen ausgetauscht. Für den Menschen ist sowohl beim Handshake als auch bei der Kommunikation die Form des Informationsaustausches eine sogenannte Sprache, eine eher organische und ungezwungene Menge von Silben, die, wenn sie in die richtige Reihenfolge gebracht werden (8216spelling8217 und 8216grammar8217), verwendet werden können, um Verständnis in der empfangenden Partei hervorzurufen . Um auch auf dieses Niveau zu kommen, brauchten die Menschen Zehntausende von Jahren, um eine Reihe von Grunzen und anderen zufälligen Geräuschen in etwas zusammenhängendes zu entwickeln. Es genügt zu sagen, dass menschliche Kommunikationsprotokolle sind aufwändig, ungenau, mit Missverständnissen gefüllt und sind ein klares Beispiel dafür, wie man nicht ein Kommunikationsprotokoll Endlich endet die Verbindung. Auch für den Menschen kann dies viele Formen annehmen, in der Regel nicht zu einer sauberen Kündigung und kann viele weitere Minuten zu einer Verbindung hinzufügen. Aren8217t wir freuen uns jetzt, dass wir ein Kommunikationsprotokoll für Computer Design Alle Scherz beiseite, die Gestaltung eines Kommunikationsprotokolls ist ziemlich einfach. Die erste Wahl, die wir machen müssen, ist, ob wir wollen, dass das Protokoll binär oder textbasiert ist. Textbasierte Protokolle beinhalten das HTTP-Protokoll, mit dem wir Webseiten durchsuchen können. Hauptvorteil davon ist, dass es einfach für Menschen, es zu schreiben und zu debuggen. Hauptnachteil ist, dass it8217s weniger präzise und genau, dass in der Regel können Sie can8217t parse es in einem go, can8217t sofort überprüfen, dass es als Ganzes gültig ist und mit dem falschen Text Kodierung kann die Dinge ziemlich schlecht. You8217ll schnell feststellen, dass it8217s eine umständliche und fehleranfällige Art und Weise, um über ein Kommunikationsprotokoll gehen. It8217s kein Wunder, dass they8217re ziemlich selten verwendet, vor allem mit Netzwerk-Anwendungen aus irgendeinem Grund. Textbasierte Protokolle haben den Vorteil, dass sie nicht von Endianness 1 betroffen sind, was die Byte-Reihenfolge ist, die von einem bestimmten System verwendet wird. Little Endian ist, was Intel-und AMD-Prozessoren verwenden und bedeuten, dass die am wenigsten wichtige (kleine) Bits an der Vorderseite eines Bytes platziert werden, während Big Endian ist das Gegenteil. Dies bedeutet, dass, wenn wir die Zahl 14 (hexidecimal 0x0E) nehmen, in kleinen Endian eine resultierende 4-Byte-Ganzzahl wie folgt aussieht: 0E 00 00 00, während bei Big Endian wie folgt aussieht: 00 00 00 0E. Verwirrend Little Endian mit großen oder umgekehrt wird dazu führen, dass die Auslegung der Zahl falsch und macht unsere kleine Zahl von 14 in eine viel größere Anzahl von 917.504. Hoppla. Um dieses Problem mit binären Protokollen zu lösen, die in gemischten Endian-Umgebungen verwendet werden können, fügen wir eine magische Zahl an die Vorderseite des Headers, in der Regel zwei Byte mit bekannten Werten. Ein Beispiel ist mit 8216MM8217 wie in TIFF-Datei Header zu zeigen, Big Endian (MSB) und 8216ll8217 auf kleine Endian (LSB) Byte-Reihenfolge anzuzeigen. Wir können dann eine andere Parsing-Routine eingeben oder die Byte-Reihenfolge während des Parsens tauschen. Schreiben aus dem Protokoll selbst ist eine ziemlich einfache und in meiner Erfahrung Spaß Aufgabe, aber ich kann nur ein bisschen verrückt. Es ist am einfachsten, wenn Sie wissen, was die Anforderungen für das Protokoll sind, aber im Allgemeinen beginnen wir mit der Endianness-Indikator bei Bedarf, dann eine oder mehrere Indikatoren identifizieren die Header als das, was erwartet wird. Ich benutze allgemein den Namen meiner Firma gefolgt von dem Protokollnamen. Danach folgen die Daten. Abschnitte innerhalb der Daten haben ihre eigenen Textüberschriften, um Korruption zu erkennen. Wenn Offsets aren8217t wie z. B. mit Textzeichenfolgen festgelegt sind, geht eine vorzeichenlose Ganzzahl vor den Daten vor, um die Länge des Segments anzugeben. Das Grundprotokoll sieht also folgendermaßen aus: Um ein UDS-Protokoll 8216LIST8217 an den Server zu senden, verwenden wir den folgenden Code, dieser mit einem QByteArray: Habe ich schon erwähnt, dass bitweise Operatoren wichtig sind Im Umgang mit Low-Level-Interaktionen wie Kommunikationsprotokolle, sie sind von unschätzbarem Wert und ein gutes tun, um sie zu studieren. Schließlich kommentiert I8217d die Variable 8216size8217. Bei Netzwerkprotokollen ist es hart für den empfangenden Socket zu wissen, wann das Ende der Daten erreicht wurde. Setzt man die Größe der gesamten Daten an der Vorderseite des Headers so, so kann er genau wissen, wie viel Daten noch empfangen werden müssen, wenn das Datenende erreicht ist und wenn ein Download unvollständig ist. Das Analysieren des Protokolls ist im Wesentlichen das Gegenteil von dem Zusammensetzen. It8217s getan in einer linearen Weise, mit Prüfungen für jeden Wert gelesen. Wenn es richtig gemacht wird, ist es sehr robust und ziemlich narrensicher. Sowieso sind diese die Grundlagen des Setzens eines Kommunikationsprotokolls zusammen. It8217s sehr einfach, absolut nicht beängstigend und sogar ziemlich lustig Gehen Sie es ausprobieren einige time. Server Initiated Messages Einer der wichtigsten Gründe für eine WebSocket über andere Arten von HTTP-Anforderungen zu verwenden ist, um Ihren Server zu schieben Content auf den Client zur Zeit Wenn der Client nicht explizit nach etwas gefragt hat. Die Antwort auf eine WebSocket-Nachricht mit WebSocket ist unkompliziert, wie das Echoserver-Beispiel zeigt. Wenn Sie jedoch Nachrichten auf der Grundlage von Ereignissen auf der Serverseite senden möchten, benötigen Sie ein bisschen mehr Code. Wir werden zwei Beispiele anschauen. Der erste ist ein Broadcast-Server, der zweite ein Telemetrieserver. Broadcast-Server Es ist ähnlich dem Echoserver, dass eingehende Nachrichten zurückgespiegelt werden, aber anders darin, dass sie zurück zu allen verbundenen Clients und nicht nur zum Absender zurückgesendet werden. Um eine Nachricht zu senden, benötigen wir ein Token, das die Verbindung identifiziert. Das Token in WebSocket ist die connectionhdl. Im echoserver Beispiel wurde die connectionhdl vom Onmessage Callback versorgt. Alle Handler-Rückrufe enthalten eine connectionhdl, die die Verbindung identifiziert, die den Handler initiiert hat. Für einen Broadcast-Server muss onmessage anrufen, sendet für jede Verbindung und nicht nur für den Absender. Um dies zu erreichen, müssen wir eine Liste aller herausragenden Verbindungen pflegen. Dies kann durch Speichern einer Liste von connectionhdls, die von dem onopen-Handler aufgefüllt und durch onclose beschnitten werden, durchgeführt werden. Für jede empfangene Nachricht wird diese Nachricht dann in einer Schleife zu jedem connectionhdl in der Liste kopiert. Hinweis: Dies ist ein einfaches und vereinfachtes Programm. Fehlerprüfung von Codepfaden wurde entfernt, um die Kernlogik deutlicher darzustellen. Nicht alle solche Programme müssen für alle Fehler zu überprüfen. Sie sollten prüfen, und behandeln Sie die für Ihre Anwendung geeigneten. Zweitens wird dieser vereinfachte Broadcast-Server nicht gut skalieren. WebSocket-Handler blockieren Kernnetzwerkfunktionen. Während dieses Programm seine Send-Schleife in onmessage ausführt, werden keine neuen Verbindungen verarbeitet und keine neuen Nachrichten empfangen. Dies funktioniert gut mit kleinen Anzahl von Verbindungen, aber brechen schlecht, wenn skaliert. Um Reaktionen bei hohen Nachrichtenraten oder hohen Konkurrenzniveaus aufrechtzuerhalten, sollten Handler Verarbeitungsanforderungen an andere Worker-Threads weiterleiten, um die Arbeit tatsächlich durchzuführen. Das Broadcast-Serverbeispiel, das in der Bibliotheksquelle enthalten ist, korrigiert diese beiden Probleme. Wenn Sie daran interessiert sind, ein höheres Leistungsbeispiel mit Fehlerprüfung zu betrachten, verweisen wir auf diesen Code. Programm-Quell-Telemetrieserver Während der Broadcast-Server Nachrichten an Verbindungen sendet, die nicht angefordert werden, da Daten bereit sind, beginnt alles mit einer Nachricht von einer Verbindung. Wenn Sie Daten auf der Grundlage eines von dem Server tatsächlich eingeleiteten Ereignisses und nicht einer Antwort auf einen eingehenden Eingang übertragen möchten, gibt es einige Optionen. Countserver: Thread oder externe Ereignis-Schleife Diese Methode verwendet einen separaten Thread (eine externe Ereignis-Schleife in einem anderen Thread wird auch funktionieren). Count-Server verwendet einen anderen Thread zum Einschlafen für eine Zeit und dann inkrementieren einen Zähler und sendet den neuen Wert an alle verbundenen Clients. Hinweis: Wie das Broadcast-Server oben, ist dies ein vereinfachtes Programm. Es enthält den Kern des Programms für Klarheit, aber nicht detaillierte Fehlerprüfung Code. Transport :: asio ontimer TODO: Hinweise dazu onewebsocketpp Hervorgehobene Änderungen Minor Breaking changes Eine neue erforderliche Methode wurde der Transport - und Socket-Policy-APP hinzugefügt. Eine Implementierung ist optional. Die gesamte Verkehrspolitik wurde aktualisiert. Autoren von benutzerdefinierten Transporten müssen mindestens eine leere Methode mit der richtigen Signatur hinzufügen. Eine C11-abhängige Abhängigkeitsbereinigung hat die Abhängigkeit von libboost-datetime für libboost-chrono für C03-Compiler mit Boost Version 1.49 und höher getauscht. C11-Compiler benötigen keine libboost-datetime mehr. C03-Compiler mit Boost 1.48 und älter sind nicht betroffen und benötigen noch libboost-datetime. Fügt nicht blockierende HTTP-Handler hinzu Nicht blockierende HTTP-Handler bieten signifikante Leistungsverbesserungen für Anwendungen, die eine längere HTTP-Antwort benötigen, ohne WebSocket-Datenverkehr zu sperren. Weitere Informationen finden Sie in der HTTP-Handler-Handbuchseite. Asio Transport TLS / Sicherheitsbezogene Verbesserungen Asio Transport unterstützt nun ausgehende Verbindungen mit SNI, wenn die zugrundeliegende Version von openssl es unterstützt. Zusammengesetzte Beispiele mit dem TLS-fähigen Asio Config zeigen nun, wie die Einhaltung der von Mozillas empfohlenen TLS-Einstellungen erreicht werden kann. Echoservertls kompiliert mit der modernen Fahne und eine moderne Version von openssl gibt nun den SSL Labs Server-Test mit einer Note von A. Standalone Asio jetzt unterstützt Asio Transport kann optional Standalone-Asio anstatt Boost Asio. Dies ermöglicht die Verwendung des Asio-Transportes mit einer C11-Build-Umgebung ohne Boost-Bibliotheken. Um zu aktivieren, definieren Sie ASIOSTANDALONE vor allen WebSocket - oder Asio-Headern. Raw / iostream-Transportvektorierter Schreib-Handler Der Roh / Iostream-Transport kann nun optional einen Handler für vektorierte oder Scatter / Gather-Schreibvorgänge registrieren. Dies führt zu weniger Rückrufen und ermöglicht eine effizientere Verpackung von mehreren kleinen Schriften in einem einzigen TCP-Paket oder TLS-Datensatz. Wenn kein vectored write Handler gesetzt ist, wird der Standard Write Handler mehrmals aufgerufen. Diese Version enthält eine Reihe von Bug-Fixes und Code / api Hauswirtschaft. Es gibt eine kleine Handvoll kleinere API brechende Änderungen von 0.3.0. Trotzdem sollte ein Upgrade von 0.3.0 auf 0.4.0 für alle Benutzer einfach sein und wird sehr gefördert. Brechen von Änderungen Ausnahmetyp ändern Die primäre Unterbrechungsänderung ist die Änderung der Art von Ausnahmen, die WebSocket auslöst. Vor der Version 0.4.0 wurden Ausnahmen mit einem benutzerdefinierten Typ websocketpp :: lib :: errorcode ausgelöst. Dies stellte eine Reihe von Problemen vor, die sich nicht auf die Standardstd :: exception base und nicht auf die Semantik von std :: exception stützen. Ab Version 0.4.0 werden alle Ausnahmen, die von WebSocket ausgelöst werden, vom Typ websocketpp :: exception, die von std :: exception ableitet. Dies normalisiert alle Exception-Typen unter der Standard-Exception-Hierarchie und ermöglicht WebSocket-Ausnahmen in der gleichen Anweisung wie andere gefangen werden. Der zuvor ausgegebene Fehlercode wird in das Ausnahmeobjekt eingehüllt und kann über die Methode websocketpp :: exception :: code () aufgerufen werden. Benutzerdefinierte Protokollrichtlinienänderung Die API für das Erstellen benutzerdefinierter Protokollierungsrichtlinien wurde aktualisiert, um etwas allgemeiner zu sein. Insbesondere ist die Verwendung von std :: ostream nicht mehr vorgeschrieben. Daher müssen alle benutzerdefinierten Protokollierungsrichtlinien einige Konstruktoren ändern / hinzufügen, die der neuen API entsprechen. Alle Protokollierungsstrategien, die mit WebSocket gebündelt wurden (die stub / none-Richtlinie und der Standard-Ostream-Protokollierer) wurden aktualisiert. Wenn Sie nur die Standardprotokollierungsrichtlinien verwenden, müssen Sie keine Änderungen vornehmen. Utility-Methoden-Signaturen Drei Utility-Methoden haben ihre Signaturen aktualisiert. Diese Methoden sind nicht Teil der öffentlichen API von WebSockets, aber einige Benutzer können die gebündelten Versionen anstelle von dem Verwenden ihrer eigenen Bibliotheken für Bequemlichkeit verwenden. Wenn Sie eine dieser Utility-Methoden verwenden, müssen Sie möglicherweise Ihre Call-Websites aktualisieren: Seit dem letzten Update gibt es zwei Versionen von 0,3.x Alpha. Es wurden keine wesentlichen Merkmale hinzugefügt. Einige Kleinigkeiten wurden hinzugefügt und viele Fehler wurden behoben. Die wichtigsten Hinweise finden Sie im Folgenden, die vollständigen Release Notes finden Sie im Repository selbst sowie auf der Seite Change Log. Hervorgehobene Änderungen Entfernt die Abhängigkeit von boost / std ltregexgt-Bibliothek. Dies bringt die volle C11-Kompatibilität zu GCC 4.6 und vermeidet die Notwendigkeit der Bündelung der ziemlich großen Boost-Regex-Binärdatei für platzbeschränkte eingebettete Anwendungen. Die HTTP-Header-Verarbeitung der Groß - / Kleinschreibung wurde überarbeitet. Fall, der für das Lesen von Headern verwendet wird, wird pro HTTP 1.1-Spezifikation ignoriert. Fall für Header, die Sie festlegen, wird beibehalten, um mit anderen HTTP-Implementierungen, die bestimmte Fälle erfordern, zu helfen. Bibliothekslizenzen für Drittparteien wurden in der COPYING-Datei konsolidiert. Sha1-Bibliothek wurde ersetzt durch eine andere unter einer BSD-Lizenz anstatt eine Freeware-Lizenz, um Bedenken über mehrdeutige Lizenzformulierung Adresse. Alle gebündelten Bibliotheken verwenden jetzt Expat MIT oder BSD Lizenzierung. Der Asio-Transport führt eine Stoplisten-Methode ein, um es einem Server zu ermöglichen, neue Verbindungen zu akzeptieren. Iostream transport führt setsecure ein. Setremoteendpoint. Eof Und fatalerror Methoden, damit Benutzer dieses Transportes Informationen über die Verbindung über die Bibliothek zu übertragen. Aktualisierungen schließen Code-Typen und Validierung basierend auf aktuellen Updates der IANA-Registry. Aktualisiert auf asiatische Transport-Thread-Sicherheit und führt wieder Stränge ein, damit ioservice-Thread-Pools wieder funktionieren. Entfernt unbenutzten experimentellen Code. Dies sollte den Speicherverbrauch reduzieren und die Leistung verbessern, insbesondere bei der Erstellung und Vernichtung von Verbindungen. Roadmap für 0.4.x Das Alpha4 Release heute wird wahrscheinlich das letzte 0.3.x Alpha sein. Das nächste Release wird mit 0.4.x markiert, da es einige (sehr kleine) brechende AIP-Änderungen geben wird. Der 0.3.x-Zweig ist jetzt komplett. Es wurde veröffentlicht und getaggt als 0.3.x-alpha2 auf dem Master-Zweig auf GitHub. Dazu gehören Code, die verwendet werden, um die experimentellen und 0.3.x-cmake Zweige werden. Diese Zweige sind jetzt veraltet und werden in naher Zukunft gelöscht. Alle Veröffentlichungen von diesem Zeitpunkt an werden auf dem Master-Zweig und semantisch versioniert. Detaillierte Änderungsprotokolle sind sowohl auf der Änderungsprotokollseite als auch in changelog. md im Repository verfügbar. Doxygen Dokumentation für die 0.3.x Niederlassung ist jetzt bei doxygen. websocketpp. org verfügbar Autobahn Berichte für die 0.3.x Niederlassung sind jetzt auf autobahn. websocketpp. org WebSocket jetzt unterstützt explizite Proxies für ausgehende Client-Verbindungen (beide ws und wss) Detailliert Changes changes. Changes changes....................................................................................................................................................... Die geschlossenen Codes, die Gründe und den zugrunde liegenden Fehlercode von geschlossenen Verbindungen Explizite Outgoing-Proxy-Unterstützung Korrigiert eine Anzahl von Problemen mit dem Ende des Verbindungsverhaltens, insbesondere für Clients. TLS-Shutdown blockiert nicht mehr Hybi00 Nahbereichsunterstützung Viele Dokumente können entfernt werden ungenutzte Dateien und andere Dead-Code Roadmap für die endgültige Version 0.3.x weiterhin Reinigung von Code-Stil Bugfixes mehr Dokumentation mehr Tests Roadmap für 0.4.x 0.4.x wird rückwärts sein Kompatibel mit 0.3.x Implementieren Sie permessage-deflate Erweiterung Entfernen Sie die Abhängigkeit von ltregexgt Header, die schlechte Unterstützung in GCC hat Neue Funktionen für die 0.3.x (experimentelle) Zweig im April: Subprotokoll Verhandlung Hixie 76 / Hybi 00 Unterstützung Ausgehende explizite Proxy-Unterstützung für WS und WSS-Verbindungen Proxy-Authentifizierung: Basisauthentifizierung Fähigkeit, sich auf einem beliebigen Stream zu protokollieren (einschließlich Dateien) Verbessert Detail, Konsistenz und Leistung von Fehler - und Zugriffsprotokollierung Mehrere neue Beispiele (Telemetrie-Client, Printserver, testeeserver, iostreamserver) Anpassungen zur Verbesserung der Unterstützung für Visual Studio Library erstellt und übergibt Tests auf 32-Bit - und PowerPC-Architekturen. Roadmap für Mai: Die letzte Sperrfunktion für die Version 0.3.0 ist die Implementierung von Timeouts für mehrere netzbezogene Ereignisse. Die meisten anderen Arbeiten werden im Zusammenhang mit der Prüfung und Behebung von Fehlern in Vorbereitung für eine offizielle 0.3.0 Beta-Version am Ende des Monats. Hinweis für Benutzer der Version 0.2.x. Wenn Ihre Software oder Ihr Build-System auf die Version 0.2.x setzt, die der Master-Zweig auf GitHub ist, müssen Sie einige Änderungen in der nahen Zukunft vornehmen. Ich würde Sie ermutigen, Ihren Code auf die 0.3.x-Schnittstellen zu aktualisieren. Wenn dies nicht möglich ist, gibt es jetzt einen 0.2.x-Zweig in Git, der 0.2.x-Code auf unbestimmte Zeit halten wird. Neues Forum / Mailinglisten Dies ist ein offenes Diskussions - / Supportforum für Nutzungsfragen, Supportanfragen, Featureanfragen und weitere ausführliche entwicklungsbezogene Diskussionen, die für ein GitHub-Problem nicht geeignet sind. Im Allgemeinen, wenn das Antwort - / Diskussionsthema für andere Personen nützlich sein wird, nachdem das Problem behoben ist, sollte es auf dieser Liste statt auf einem GitHub-Problem gehen. Dies ist eine niedrige Volumen moderierte Mailing-Liste, die diese monatlichen Updates Entwicklung sowie Meldungen der neuen offiziellen Bibliothek veröffentlicht werden. Ab heute Abend wurde die WebSocket 0.3.x (experimentelle) Zweig mit einer Reihe von neuen Funktionen, die es ziemlich nahe an Parität mit 0.2.x. Die letzte große fehlende Funktion, die Client-Rolle, wurde abgeschlossen. 0.3.x verfügt nun über eine Client-Rolle, indem es ltwebsocketpp / client. hppgt und drei neue Standardkonfigurationen, coreclient, asioclient und asionotlsclient enthält. Diese spiegeln die jeweils benannten Serverkonfigurationen. Die Client-Rolle wird sowohl netzlos über den iostream-Transport als auch über TCP / IP mit dem Boost-ASIO-basierten Transport funktionieren. Der 0,3.x-Client übergibt alle autobahn-Testsuite-Tests streng. Ein Beispiel-Client ist in dem Beispiel-Ordner verfügbar. Weitere neuere, bemerkenswerte Änderungen: Alle Beispiele und Komponententests kompilieren und laufen auf 32-Bit-Intel-Prozessoren (i686) RNG-Unterstützung Override-fähige Verbindungsbasisklasse Zahlreiche neue Beispiele und Manualseiten Die Readmes für beide Hauptzweige wurden mit detaillierteren Informationen über die Status jedes Zweiges. Diese werden fortlaufend aktualisiert. Remaining features before 0.3.x will be ready to replace version 0.2.x: Subprotocol Negotiation Hybi00/Hixie76 protocol support PowerPC/ARM bug fixes Performance tuning, particularly in the area of message buffer pools Unless you need these features specifically, 0.3.x is the recommended version. I have long been interested in writing and experimenting with web based virtual worlds. Some of my more recent projects in that area ran into communication limitations. In 2010 there was no good way to do low latency bidirectional communication to a browser without resorting to non-standard plugins. While researching my options I came across the IETF hybi working group that was chartered to develop exactly what I was looking for. As this is a capability I felt the web sorely needed a standard solution for I joined the group. WebSocket was born as an early implimentation of the WebSocket protocol to test out ideas proposed by the working group and later on performance and interoperability tests. In the last two years there have been three major versions of WebSocket. Versions tagged 0.1 were very rough experimental versions and not compatible with the final RFC6455 spec. It can be found in the legacy branch on GitHub. Version 0.2 was built for performance and interoperability testing (alongside my work implimenting tests for the Autobahn suite ). It can be found in the Master branch on GitHub. While it is a complete implimentation of RFC6455 a number of early design decisions made it impractical for certain use cases, especially those involving multithreading. In the year or so that version 0.2 has been available I have gathered a great deal of feedback about how developers are using C WebSocket libraries. Ive continued to work with the hybi group on standardizing some extensions to the WebSocket protocol, in particular message compression. The completion of C11 has also brought a number additional options that make sense to use. To address these issues and build a library more suitable for general purpose usage I have been working on a third (and hopefully final) version of the library, 0.3. If no major issues are raised, 0.3 will become the stable 1.0 release. High performance, standards compliant, open source, C WebSocket client and server library.

No comments:

Post a Comment