Hallo, alle miteinander! Ich möchte der Öffentlichkeit das Framework mitteilen, auf dessen Grundlage derzeit viele Server Tausende von Clients in verschiedenen Serversystemen bedienen. exsc (EXtensible Server Core) ist ein in C geschriebenes Framework, mit dem Sie einen oder mehrere Server-Threads in einer Anwendung haben können. Jeder Server-Thread kann eine große Anzahl von Clients bedienen. Obwohl das Framework in einem Request-Response-Modell verwendet werden kann, wurde es in erster Linie entwickelt, um eine konstante Verbindung mit einer großen Anzahl von Clients aufrechtzuerhalten und Nachrichten in Echtzeit auszutauschen. Da ich selbst gerne ein fertiges HelloWorld-Projekt nehme, es kompiliere und sehe, wie alles funktioniert, werde ich am Ende des Artikels einen Link zu einem solchen Projekt veröffentlichen.
Viele Operationen werden für eine bestimmte Verbindung ausgeführt. Im Rahmen dieses Frameworks ist die Struktur exsc_excon für die Verbindung verantwortlich. Diese Struktur enthält die folgenden Felder:
ix - Verbindungsindex. Dies ist die Seriennummer der Verbindung, die zum Zeitpunkt der Verbindung des Clients frei war.
id - Verbindungskennung. Dies ist eine eindeutige Verbindungsnummer. Im Gegensatz zu einem Index wiederholt er sich nicht.
addr -
Name der Client-IP-Adresse - Verbindungsname. Es können mehrere Verbindungen mit demselben Namen benannt und anschließend eine Nachricht an alle Verbindungen mit demselben Namen gesendet werden (siehe Funktion exsc_sendbyname).
Kernel-Initialisierung
Um mit dem Kernel arbeiten zu können, müssen wir ihn mit der Funktion initialisieren
void exsc_init(int maxsrvcnt);
Der Parameter maxsrvcnt teilt dem Kernel mit, wie viele Server-Threads wir in unserer Anwendung verwenden werden.
Starten des Server-Streams
Als Nächstes müssen wir den Server-Stream mithilfe der Funktion starten
int exsc_start(uint16_t port, int timeout, int timeframe, int recvbufsize, int concnt, void newcon(struct exsc_excon excon), void closecon(struct exsc_excon excon), void recv(struct exsc_excon excon, char *buf, int bufsize), void ext());
Port - Der Port, der den Server-Stream abhört.
Zeitüberschreitung - Gibt an, wie lange der Server-Thread auf Aktivitäten des Clients wartet. Wenn der Client während dieser Zeit keine Nachrichten gesendet hat, schließt der Server-Thread eine solche Verbindung. Wenn wir also eine konstante Verbindung aufrechterhalten und diesen Parameter beispielsweise 30 Sekunden lang einstellen möchten, müssen alle 10-15 Sekunden Ping-Nachrichten gesendet werden.
Zeitrahmen- Der Zeitrahmen, für den wir die Ausführung der Anforderung zulassen. Wenn dieser Wert beispielsweise auf 100 Millisekunden festgelegt ist und der Server-Thread alle aktuellen Anforderungen von Benutzern in 10 Sekunden verarbeitet hat, bleiben die verbleibenden 90 Millisekunden dem Prozessor, um andere Aufgaben auszuführen. Je kleiner dieser Wert ist, desto schneller verarbeitet der Server-Thread Anforderungen, aber desto mehr lädt er den Prozessor.
recvbufsize - Die Größe des Puffers, den der Server-Thread gleichzeitig liest.
concnt - Die maximale Anzahl von Verbindungen, mit denen der Server-Thread gleichzeitig arbeitet.
newcon- Rückruffunktion, die jedes Mal funktioniert, wenn ein neuer Client eine Verbindung herstellt. Die Parameter dieser Funktion werden an die Verbindung des Clients übergeben, der die Verbindung hergestellt hat.
closecon ist eine Rückruffunktion, die jedes Mal ausgeführt wird, wenn eine inaktive Verbindung geschlossen wird. Die Parameter dieser Funktion werden an die Verbindung des Clients übergeben, der die Verbindung getrennt hat.
recv ist eine Rückruffunktion, die aufgerufen wird, wenn der Client Pakete sendet. Den Parametern dieser Funktion wird die Verbindung des Clients übergeben, von dem die Daten stammen, ein Zeiger auf die Daten und die Größe des Puffers mit Daten.
ext- Rückruffunktion, die bei jedem Durchlauf der Server-Thread-Schleife aufgerufen wird. Diese Funktion dient dazu, die Funktionalität des Kernels zu erweitern. Hier können Sie beispielsweise die Verarbeitung von Timern verknüpfen.
Die Funktion exsc_start gibt ein Handle an den Server-Thread zurück, der zum Aufrufen einiger Funktionen des Frameworks benötigt wird.
Senden von Nachrichten
Die Funktion ist für das Senden von Nachrichten verantwortlich.
void exsc_send(int des, struct exsc_excon *excon, char *buf, int bufsize);
Diese Funktion ist threadsicher (Sie können sie von jedem Thread aus aufrufen). Als Parameter müssen Sie das Handle des Server-Streams (den wir als Rückgabewert der Funktion exsc_start erhalten haben ), die Verbindung, an die wir eine Nachricht senden möchten, einen Zeiger auf den Puffer mit der Nachricht und die Größe übergeben des Puffers.
Wir haben auch die Möglichkeit, eine Nachricht an eine Gruppe von Kunden zu senden. Hierfür gibt es eine Funktion
void exsc_sendbyname(int des, char *conname, char *buf, int bufsize);
Es ähnelt der Funktion exsc_send, mit Ausnahme des zweiten Parameters, bei dem es sich um den Namen der Verbindungen handelt, an die die Nachricht gesendet wird.
Festlegen des Verbindungsnamens
Verwenden Sie die Funktion, um die Verbindung in Zukunft weiter zu identifizieren, Informationen über die Verbindung zu speichern oder Nachrichten an eine Gruppe von Clients zu senden
void exsc_setconname(int des, struct exsc_excon *excon, char *name);
Diese Funktion ist threadsicher. Der erste Parameter ist das Handle des Server-Streams, der zweite Parameter ist die Verbindung selbst und der dritte Parameter ist der Name dieser Verbindung.
Verbinden eines Server-Streams mit einem anderen Server
Manchmal erfordert die serverseitige Logik, dass Sie eine Verbindung zu einem anderen Server herstellen, um Daten anzufordern oder zu übertragen. Für solche Aufgaben wurde eine Funktion eingeführt, die eine solche Verbindung herstellt.
void exsc_connect(int des, const char *addr, uint16_t port, struct exsc_excon *excon);
Diese Funktion ist threadsicher. Als Parameter müssen wir das Handle des Server-Streams, die Adresse des Servers, zu dem wir eine Verbindung herstellen müssen, den Serververbrauch, zu dem wir eine Verbindung herstellen müssen, und als letzten Parameter den Verbindungszeiger übergeben, mit dem wir eine Verbindung herstellen können Rufen Sie später andere Funktionen des Frameworks auf. Es ist erwähnenswert, dass wir nicht warten müssen, bis die Verbindung hergestellt ist. Wir können die Funktionen exsc_connect und exsc_send nacheinander aufrufen, und das System stellt sicher, dass die Nachricht gesendet wird, sobald eine Verbindung zum Remote-Server hergestellt werden kann.
Beispielserver mit Kommentaren
#include <stdio.h>
#include <string.h>
#include "../exnetwork/exsc.h"
int g_des; //
//
void exsc_newcon(struct exsc_excon con)
{
printf("the connection was open %s\n", con.addr);
}
//
void exsc_closecon(struct exsc_excon con)
{
printf("the connection was closed %s\n", con.addr);
}
//
void exsc_recv(struct exsc_excon con, char *buf, int bufsize)
{
char msg[512] = { 0 };
memcpy(msg, buf, bufsize);
printf("receive data from %s\n%s\n", con.addr, msg);
if (strcmp(msg, "say hello") == 0)
{
strcpy(msg, "hello");
exsc_send(g_des, &con, msg, strlen(msg));
}
}
//
void exsc_ext()
{
}
int main()
{
printf("server_test_0 is started\n");
exsc_init(2); //
// 7777
// 30
// 10
// 1024
// 10000
g_des = exsc_start(7777, 30, 10, 1024, 10000, exsc_newcon, exsc_closecon, exsc_recv, exsc_ext);
// ,
// exit ENTER
while (1)
{
const int cmdmaxlen = 256;
char cmd[cmdmaxlen];
fgets(cmd, cmdmaxlen, stdin);
if (strcmp(cmd, "exit\n") == 0)
{
break;
}
}
return 0;
}
Fazit
Der exsc-Kernel interagiert nur wenig mit Clients. Obwohl dies das wichtigste Element des Serversystems ist, auf dessen Grundlage alles aufgebaut ist, müssen Sie darüber hinaus höhere Ebenen erstellen, die für die Verwaltung von Verbindungen, das Generieren von Nachrichten und das Zusammenstellen von Nachrichten (die wahrscheinlich eingehen werden) verantwortlich sind mehrere Stufen). Wenn dieser Artikel eine positive Antwort erhält, wird ein zweiter Teil geschrieben, in dem das Thema der Entwicklung eines Serverprogramms der obersten Ebene auf der Grundlage dieses Kernels behandelt wird.
PS
Wenn jemand beschließt, die interne Logik dieses Frameworks zu verstehen oder sie in seinen Projekten anzuwenden und Fehler oder Engpässe darin findet, lassen Sie es uns bitte wissen. Die Community ist dafür, damit jeder, der zu Open Source-Projekten beitragen kann.
Link zur Bibliothek Das
Beispiel befindet sich im Archiv exsc_test_0.zip