Jump to content
Unity Insider Forum

Client - Server. Wenn man es selber machen will


Recommended Posts

Hallo Liebe Freunde,

 

hier mal ein kleines Beispiel wie ein simple Client - Server Struktur aussehen könnte. Eigenes Handeln ist auch hier immer noch gefragt aber es sollte zu mindestens den einen oder anderen Denkanstoß geben da die meisten schon nicht wissen wo sie anfangen sollen.

 

Generell versuche ich Erklärungen erstmal kurz zu halten, wer Fragen hat stellt sie einfach. Den Code hab ich erstmal auf Pastebin ausgelagert sonst sprengt das einfach den Beitrag!

 

Es ist explizit kein Fertiges Kompilieren und fertig, wenn das gewünscht ist und man einfach nur eine Middleware haben will in der man nur die Packete implementiert dann kann ich da auch gerne jeweils eine Server und Client DLL bauen.

 

Server

Der Server ist entweder eine Consolen oder GUI Anwendung, es hat nichts mit Unity zu tun.

 

Connection.cs

Der Name verrät es schon hier geht um die konkrete Connection -> Versenden und Empfangen von Packeten. Dies findet hauptsächlich über die asynchronen Methoden des des TcpClients statt. Die Packete werden anhand ihres Opcodes erkannt und dementsprechend gelesen/geschrieben, in unseren Fall ist der Opcode die ersten 4 Bytes

 

Packete werden über einen sogenannten Queue versendet der nach dem First-In-First-Out Prinzip arbeitet.

 

BasePacket.cs

Diese Abstrakte Klasse macht an sich nicht viel sie bildet wie der Name sagt einfach nur die Basis die später von den Implementierungen erweitert werden. Im Prinzip ist dies ein MemoryStream der Später in den Implementierungen mit Read/Write Funktionen bestückt wird

 

ClientPacket.cs

Es geht abstrakt weiter. Im Fall des Servers ist der Client natürlich im Prinzip der Spieler der sich auf dem Server verbunden hat. Die Kleingeschriebenen Methoden stammen noch aus einem Java-Projekt da war ich beim übernehmen faul! Die Klasse definiert erstmal nur Methoden die Lesend auf die Daten zugreifen

 

ServerPacket.cs

Das Gegenstück zu ClientPacket, hier schreibt man nur in den Stream

 

SM_FOG_LIGHT.cs

Eine Beispiel-Implementierung eines ServerPackets, schreibt nur 3 Werte in den Stream.

 

PacketHolder.cs

Hier werden die Packete mit ihren Opcode (Code zur Identifikation des Packets) registriert, im Beispiel sind ein paar Beispielpackete drinne.

 

PacketType.cs

Hier mal ohne Pastebin da selbsterklärend ;)

// Copyright (C) Paul Becker, - All Rights Reserved
// Unauthorized copying of this file, via any medium is strictly prohibited
// Proprietary and confidential
// Written by Paul Becker <paul.becker1@gmx.de>, 22:06
namespace SeraphimServer.Network
{
public enum PacketType
{
	CLIENT,
	SERVER
}
}

 

ServerListener.cs

Sehr simpel einfach ein TcpListener (horcht auf sich verbindende TcpClient's), im Beispiel auf localhost:2106

 

NetworkService.cs

Hier findet die eigentliche Server Arbeit statt, horchen auf Clients, TcpClients initalisieren, Start Methoden aufrufen. BeginAccept und EndAccept rufen sich ständig gegenseitig auf und es ist somit eine Endlosschleife.

 

 

Client

Dieser Code wird auf Clientseite ausgeführt, also Unity. Ist im Prinzip der gleiche wie Server nur das die Packete vertauscht sind.

 

Client hat teilweise abgespeckte Klassen, der Sinn dahinter bleibt der Gleiche wie oben beschrieben.

Connection - owner Property was eine Referenz auf euer Unity GameObject hält. Ist aber nur ein Vorschlag, man muss halt nur irgendwo nur eine Verbindung herstellen damit man aus den Packeten heraus auf Unity zugreifen kann

NetworkService - Einpunkt Verbindung

PacketHolder - Gleiche wie oben

& die Packetklassen

 

Wie oben kurz beschrieben sind die Packete hier vertauscht SM_FOG_LIGHT (ServerPacket -> Packet von Server zu Client)

 

Oben nutzten wir SM_FOG_LIGHT welchen zum Client gesendet wird, diese tut dies

		WriteFloat(3); // Light
		WriteFloat(0.02f); // Fog
		WriteInt(500); // Time in ms

 

Auf den Client würden wir jetzt ein eine Erweiterung des ClientPacket dafür erstellen die das als Implementierung machen würde

class PKT_FR_SR_CHANGE_FOG_LIGHT : ClientPacket
{
	public override void ProcessPacket()
	{
		float Light = ReadFloat();
		float Fog = ReadFloat();
		int time = ReadInt();
		//Jetzt haben wir Werte und machen etwas damit, dummy
		Connection.owner.WorldEnvironment.SlightlyChangeFogAndLight(Light, Fog, time);
	}
}

 

WorkFlow

Am Ende implementiert man einfach immer nur Packete die man brauch, ein ServerPacket auf dem Server ist ein ClientPacket auf dem Client, wie direkt darüber beschrieben liest man auf den Client alles was man auf dem Server in das Packet geschrieben hat. Nicht zu vergessen ist immer der PacketHolder ServerPacket mit Opcode 1 auf dem Server muss auf den Client ein ClientPacket mit Opcode 1 sein. Der Opcode ist somit die Verbindung die den Server sagt wie ein Packet gelesen oder geschrieben werden muss und um welches Packet es sich handelt.

 

Das starten des Networkservices wäre in diesem Fall einfach in euer Player Unityklasse in der Startmethode oder so

 

  public Connection Connection { get; set; }
  private void Start()
  {
		/*
		 * Set up Network
		 */
		NetworkService.Start();
		Connection = NetworkService.CnxPreAlloc;
		Connection.owner = this;
	}

 

Dann macht man einfach

player.Connection.SendPacket(new EXAMPLE_SERVERPACKET());

 

Serverseite in der Main Methode oder so.

NetworkService.Start();

 

 

 

Server -> Packet erstellen und schreiben -> Connection.SendPacket -> Client -> Empfängt Packet

-> anhand des Barcodes wird Packet identifiziert und gelesen -> Logik mit Daten aus dem Packet wird ausgeführt

 

 

Disclaimer

Bei dieser Implementierung handelt es sich wirklich um die Basics, ich wollte ungern mein fettes Network um die Ohren hauen wo man gleich mal bei 30-40 Klassen hat.... das ist aber auch auf ganz andere Bedürfnisse angelegt. Ich weiß auch das einige Properties ungenutzt sind, das sind meistens noch Überbleibsel aus der En-/Decryption die ich aus dem Beispiel entfernt habe.

Im Prinzip ist das ganze erstmal nur eine Diskussionsgrundlage.

 

Ein Beispielprojekt würde sich auch anbieten, aber heute ist schon zu spät für mich ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...