Multiplayer: Unterschied zwischen den Versionen

Aus Das Sopra Wiki
Ruzzoli (Diskussion | Beiträge)
Die Seite wurde neu angelegt: „= Multiplayer = Um ein klassisches Client/Server Konzept zu realisieren sind folgende Schritte notwendig: Auf Server Seite: * Socket öffnen & Clientverbindungen…“
 
Ruzzoli (Diskussion | Beiträge)
Keine Bearbeitungszusammenfassung
Zeile 1: Zeile 1:
= Multiplayer =
Um ein klassisches Client/Server Konzept zu realisieren sind folgende Schritte notwendig:
Um ein klassisches Client/Server Konzept zu realisieren sind folgende Schritte notwendig:


Zeile 11: Zeile 10:




== Multiplayer mit der Lidgren Bibliothek ==
== Multiplayer mit der [http://code.google.com/p/lidgren-network/ Lidgren] Bibliothek ==
=== Die NetBuffer Klasse ===
Eine Instanz der ''NetBuffer'' Klasse erhält man stets durch Aufruf der Methode ''CreateBuffer()'' auf einem ''NetServer'' respektive ''NetClient'' Objekt.
 
Die Klasse stellt zum Schreiben von Nutzdaten die Methode ''Write()'' mit unzähligen Overloads für die einzelnen Datentypen zur Verfügung. Wenn die XNA Extension genutzt wird können auch direkt XNA Datentypen wie z.B. ''Vector3'' in einen NetBuffer geschrieben werden.
 
Um die Nutzdaten aus einem ''NetBuffer'' Objekt auszulesen werden die entsprechend benannten Read() Methoden verwendet. So gibt es z.B. ''ReadString()'', ''ReadBoolean()'', ''ReadFloat()'' und falls die XNA Extension eingebunden ist auch Methoden wie ''ReadVector3()''.
 
Zu beachten hierbei ist, dass die Daten in einem Buffer in der gleichen Reihenfolge wieder gelesen werden müssen in der sie auch geschrieben wurden.
=== Network Channels ===
Es gibt 4 verschiedene virtuelle Netzwerk Kanäle die beim versenden von Paketen mittels der Lidgren Library angegeben werden können:
* '''UnreliableUnordered''' - Nachrichten kommen entweder beim Empfänger an oder auch nicht
* '''UnreliableInOrder''' - Auslieferung der Nachrichten ebenfalls nicht garantiert, falls eine Nachricht zu spät kommt, d.h. eine neuere Nachricht ist vorher eingetroffen, so wird die ältere gedroppt
* '''ReliableUnordered''' - Garantierte Auslieferung der Nachrichten, allerdings nicht notwendigerweise in der Reihenfolge in der sie gesendet wurden
* '''ReliableInOrder''' - Alle Nachrichten kommen in der Reihenfolge in der sie gesendet wurden beim Empfänger an
=== Server ===
Starten des Servers
<source lang=csharp>
<source lang=csharp>
NetConfiguration config = new NetConfiguration("MYAPP");
NetConfiguration config = new NetConfiguration("MyApp");
config.Port = 4096;
config.Port = 4096;
NetServer myNetServer = new NetServer(config);
NetServer myNetServer = new NetServer(config);
myNetServer.SetMessageTypeEnabled(NetMessageType.ConnectionApproval, true);
myNetServer.Start();
myNetServer.Start();
</source>
</source>


Empfangen von Clientdaten
<source lang=csharp>
NetBuffer buffer = myNetServer.CreateBuffer();
NetMessageType type;
NetConnection sender;
while (myNetServer.ReadMessage(buffer, out type, out sender))
{
switch (type)
{
case NetMessageType.DebugMessage:
Console.WriteLine(buffer.ReadString());
break;
case NetMessageType.ConnectionApproval:
sender.Approve();
break;
case NetMessageType.StatusChanged:
string statusMessage = buffer.ReadString();
NetConnectionStatus newStatus = (NetConnectionStatus)buffer.ReadByte();
Console.WriteLine("New status for " + sender + ": " + newStatus + " (" + statusMessage + ")");
break;
case NetMessageType.Data:
// data sent by client..
// buffer contains the userdata from the client..
// sending client is specified in sender
break;
}
}
</source>
Daten an Clients senden
<source lang=csharp>
myNetServer.SendMessage(buffer, client, NetChannel.UnreliableInOrder1);
</source>
<source lang=csharp>
myNetServer.SendToAll(buffer, NetChannel.UnreliableInOrder1);
</source>
=== Client ===
Client starten
<source lang=csharp>
NetConfiguration config = new NetConfiguration(identifier);
NetClient myNetClient = new NetClient(config);
myNetClient.SetMessageTypeEnabled(NetMessageType.ConnectionRejected, true);
myNetClient.DiscoverLocalServers(4096);
</source>
Daten vom Server empfangen
<source lang=csharp>
NetBuffer buffer = myNetClient.CreateBuffer();
NetMessageType type;
while (myNetClient.ReadMessage(buffer, out type))
{
switch (type)
{
case NetMessageType.ServerDiscovered:
// just connect to any server found!
myNetClient.Connect(buffer.ReadIPEndPoint());
break;
case NetMessageType.ConnectionRejected:
Console.WriteLine("Rejected: " + buffer.ReadString());
break;
case NetMessageType.DebugMessage:
case NetMessageType.VerboseDebugMessage:
Console.WriteLine(buffer.ReadString());
break;
case NetMessageType.StatusChanged:
string statusMessage = buffer.ReadString();
NetConnectionStatus newStatus = (NetConnectionStatus)buffer.ReadByte();
Console.WriteLine("New status: " + newStatus + " (" + statusMessage + ")");
break;
case NetMessageType.Data:
// userdata sent from the server is now in the buffer
break;
}
}
</source>
Daten zum Server senden
<source lang=csharp>
myNetClient.SendMessage(buffer, NetChannel.UnreliableInOrder1);
</source>
== Multiplayer mittels Windows Live ==


== Multiplayer mittels Windows Live == [[Kategorie:Code-Beispiele]]
[[Kategorie:Code-Beispiele]]

Version vom 8. April 2010, 11:29 Uhr

Um ein klassisches Client/Server Konzept zu realisieren sind folgende Schritte notwendig:

Auf Server Seite:

  • Socket öffnen & Clientverbindungen annehmen
  • Daten gemäß Protokoll transportieren

Auf Client Seite:

  • Mit Server Socket verbinden
  • Daten gemäß Protokoll transportieren


Multiplayer mit der Lidgren Bibliothek

Die NetBuffer Klasse

Eine Instanz der NetBuffer Klasse erhält man stets durch Aufruf der Methode CreateBuffer() auf einem NetServer respektive NetClient Objekt.

Die Klasse stellt zum Schreiben von Nutzdaten die Methode Write() mit unzähligen Overloads für die einzelnen Datentypen zur Verfügung. Wenn die XNA Extension genutzt wird können auch direkt XNA Datentypen wie z.B. Vector3 in einen NetBuffer geschrieben werden.

Um die Nutzdaten aus einem NetBuffer Objekt auszulesen werden die entsprechend benannten Read() Methoden verwendet. So gibt es z.B. ReadString(), ReadBoolean(), ReadFloat() und falls die XNA Extension eingebunden ist auch Methoden wie ReadVector3().

Zu beachten hierbei ist, dass die Daten in einem Buffer in der gleichen Reihenfolge wieder gelesen werden müssen in der sie auch geschrieben wurden.

Network Channels

Es gibt 4 verschiedene virtuelle Netzwerk Kanäle die beim versenden von Paketen mittels der Lidgren Library angegeben werden können:

  • UnreliableUnordered - Nachrichten kommen entweder beim Empfänger an oder auch nicht
  • UnreliableInOrder - Auslieferung der Nachrichten ebenfalls nicht garantiert, falls eine Nachricht zu spät kommt, d.h. eine neuere Nachricht ist vorher eingetroffen, so wird die ältere gedroppt
  • ReliableUnordered - Garantierte Auslieferung der Nachrichten, allerdings nicht notwendigerweise in der Reihenfolge in der sie gesendet wurden
  • ReliableInOrder - Alle Nachrichten kommen in der Reihenfolge in der sie gesendet wurden beim Empfänger an

Server

Starten des Servers

NetConfiguration config = new NetConfiguration("MyApp");
config.Port = 4096;
NetServer myNetServer = new NetServer(config);
myNetServer.SetMessageTypeEnabled(NetMessageType.ConnectionApproval, true);
myNetServer.Start();

Empfangen von Clientdaten

NetBuffer buffer = myNetServer.CreateBuffer();
NetMessageType type;
NetConnection sender;
while (myNetServer.ReadMessage(buffer, out type, out sender))
{
	switch (type)
	{
		case NetMessageType.DebugMessage:
			Console.WriteLine(buffer.ReadString());
			break;
		case NetMessageType.ConnectionApproval:
			sender.Approve();
			break;
		case NetMessageType.StatusChanged:
			string statusMessage = buffer.ReadString();
			NetConnectionStatus newStatus = (NetConnectionStatus)buffer.ReadByte();
			Console.WriteLine("New status for " + sender + ": " + newStatus + " (" + statusMessage + ")");
			break;
		case NetMessageType.Data:
			// data sent by client..
			// buffer contains the userdata from the client..
			// sending client is specified in sender
			break;
	}
}

Daten an Clients senden

myNetServer.SendMessage(buffer, client, NetChannel.UnreliableInOrder1);
myNetServer.SendToAll(buffer, NetChannel.UnreliableInOrder1);

Client

Client starten

NetConfiguration config = new NetConfiguration(identifier);
NetClient myNetClient = new NetClient(config);
myNetClient.SetMessageTypeEnabled(NetMessageType.ConnectionRejected, true);
myNetClient.DiscoverLocalServers(4096);

Daten vom Server empfangen

NetBuffer buffer = myNetClient.CreateBuffer();
NetMessageType type;
while (myNetClient.ReadMessage(buffer, out type))
{
	switch (type)
	{
		case NetMessageType.ServerDiscovered:
			// just connect to any server found!
			myNetClient.Connect(buffer.ReadIPEndPoint());
			break;
		case NetMessageType.ConnectionRejected:
			Console.WriteLine("Rejected: " + buffer.ReadString());
			break;
		case NetMessageType.DebugMessage:
		case NetMessageType.VerboseDebugMessage:
			Console.WriteLine(buffer.ReadString());
			break;
		case NetMessageType.StatusChanged:
			string statusMessage = buffer.ReadString();
			NetConnectionStatus newStatus = (NetConnectionStatus)buffer.ReadByte();
			Console.WriteLine("New status: " + newStatus + " (" + statusMessage + ")");
			break;
		case NetMessageType.Data:
			// userdata sent from the server is now in the buffer
			break;
	}
}

Daten zum Server senden

myNetClient.SendMessage(buffer, NetChannel.UnreliableInOrder1);

Multiplayer mittels Windows Live