使用 XNA 建立遊戲/網路/網路引擎
其他看起來有用的引擎
- WCF - Windows 通訊基礎
- XNA 整合
- RakNet
其他有趣的事實和示例可以在這裡找到:http://create.msdn.com/en-US/education/catalog/?devarea=19,特別是名為網路預測的那個。
Lidgren 網路引擎是一個由 Michael Lidgren 建立的基於 .NET 的庫。它基本上可以與所有型別的 .NET 應用程式一起使用。它使用單個 UDP 套接字進行傳輸,並提供用於點對點和伺服器-客戶端連線的類。該引擎在 MIT 許可下執行,這意味著可以免費使用它。當前版本“gen3”需要 .NET 3.5 或更高版本。Lidgren 附帶一個額外的庫,其中包含一些類擴充套件方法,以便更好地支援 XNA。但是,您不能將 Lidgren 用於 Xbox 遊戲。[1]
NetPeer
NetPeer 代表本地連線點。它儲存並建立到其他對等點的連線。重要的派生類是NetServer 和NetClient,它們包含針對伺服器-客戶端系統的適當修改。
NetOutgoingMessage
此類的物件是您資訊的載體。要建立一個,您必須使用 NetPeer 物件的 CreateMessage() 方法。使用 Write(),您可以將所有資料放入訊息中。Write() 接受所有基本型別和物件。
NetIncomingMessage
這用於儲存有關接收訊息的資訊。除了內容,它還說明了 MessageType,它可能是與庫相關的,也可能是您傳送的資料。*MessageType 列表*
NetConnection
表示與遠端主機的連線。
如何開始
- 從專案的網站下載最新版本。
- 開啟“Lidgren XNA Extensions/Lidgren XNA Extensions.sln”檔案並編譯解決方案。
- 將建立的 .dll 檔案複製到您的專案資料夾中,並在您的專案中引用它們。
- 現在,您應該能夠使用 Lidgren.Network 名稱空間。
如何建立對等點
class Program
{
//hold the NetPeer Object as a member
//In this example I use a server, because it is more common to work with server and clients
private NetServer server;
public Program()
{
//When initialising, create a configuration object.
NetPeerConfiguration config = new NetPeerConfiguration("Server");
//Setting the port, where the NetPeer shall listen.
//This is optional, but for a server its good to know, where it is reachable
config.Port = 50001;
//Create the NetPeer object with the configurations.
server = new NetServer(config);
//Start
server.Start();
}
}
如何傳送訊息
//get a message from the servers message pool
NetOutgoingMessage msgOut = server.CreateMessage();
//write your data
msgOut.Write("Some Text");
msgOut.Write((short)54);
//send the message to a client
server.SendMessage(msgOut, client, NetDeliveryMethod.ReliableOrdered);
不同的 NetDeliveryMethods 在這裡解釋。
如何接收訊息
//use local message variable
NetIncomingMessage msgIn;
//standard receive loop - loops through all received messages, until none is left
while ((msgIn = server.ReadMessage()) != null)
{
//create message type handling with a switch
switch (msgIn.MessageType)
{
case NetIncomingMessageType.Data:
//This type handles all data that have been send by you.
break;
//All other types are for library related events (some examples)
case NetIncomingMessageType.DiscoveryRequest:
//...
break;
case NetIncomingMessageType.ConnectionApproval:
//...
break;
}
//Recycle the message to create less garbage
server.Recycle(msgIn);
}
可以在這裡找到所有 MessageTypes 的描述。
如何連線到伺服器
[2]第一步是啟用三個特定的訊息型別。
//for the server
serverConfig.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
serverConfig.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
//for the client
clientConfig.EnableMessageType(NetIncomingMessageType.DiscoveryResponse);
初始化客戶端後,您可以搜尋伺服器。因此,您可以向 IP 地址傳送請求,或搜尋本地網路中的所有系統。
//search in local network at port 50001
client.DiscoverLocalPeers(50001);
伺服器現在已收到 DiscoveryRequest,必須由“接收訊息迴圈”處理。
case NetIncomingMessageType.DiscoveryRequest:
NetOutgoingMessage msg = server.CreateMessage();
//add a string as welcome text
msg.Write("Hellooooo Client");
//send a response
server.SendDiscoveryResponse(msg, msgIn.SenderEndpoint);
break;
客戶端現在已收到伺服器的 DiscoveryRequest。假設本地網路中只有一個伺服器,您可以直接連線到它。
case NetIncomingMessageType.DiscoveryResponse:
Console.WriteLine("Server answered with: {0}", msgIn.ReadString());
client.Connect(msgIn.SenderEndpoint);
break;
最後一步是在伺服器端接收 ConnectionApproval 訊息並批准連線。
case NetIncomingMessageType.ConnectionApproval:
msgIn.SenderConnection.Approve();
break;
RakNet 是一個包含多個類以執行網路解決方案的庫,由 Jenkins Software LL 開發。它是一個跨平臺庫,適用於 C++ 和 C#。因此,它可以在所有主要平臺上使用,包括 Android 和 iOS。主要功能包括物件複製、大廳系統、安全連線、語音通訊和自動修補程式。[3]
Swig 可用於為本機 DLL 生成包裝程式碼,從而允許在 C# 中使用 RakNet。[4] Swing 生成 CXX 和 .h 檔案,這些檔案表示介面,以及 C# 專案連線到 DLL 所需的包含檔案。有關如何使用 Swig,請參閱詳細說明。
儘管 RakPeerInterface 不是一個實際的類,但它是網路通訊的主要介面,負責啟動。透過呼叫.GetInstance() 方法返回對等點例項。[5]
一個例項描述了本地套接字,可用於啟動。[5]可以使用引數定義埠,或使用 0 自動選擇一個空閒埠。此外,如果需要,可以建立套接字描述符陣列。[6]
它代表來自另一個系統/計算機的訊息,幷包含有關訊息的資訊,例如長度、位元大小或傳送者的 ID。
===== 作為客戶端的連線 ===== [7]
using UnityEngine;
using System;
using System.Collections;
using RakNet;
public class ConnectClient {
public static string remoteIP = “127.0.0.1″;
RakPeerInterface myClient;
SocketDescriptor scktDist;
//…
void Awake() {
myClient = RakPeerInterface.GetInstance();
scktDist = new SocketDescriptor();
// Prameters: 1) max. number of connection 2) SocketDescriptor to specifie ports/addresses
myClient.Startup(1,scktDist,1);
}
void OnGUI(){
//…
// if not yet connected
myClient.Connect(remoteIP, 25000, “”,0);
//…
}
}
===== 作為伺服器的連線 ===== [8]啟動伺服器與上述說明非常類似。
public class ConnectServer {
public static string remoteIP = “127.0.0.1″;
public static int maxConnectionsAllowed = 4:
public static int maxPlayersPerServer = 10;
RakPeerInterface server;
SocketDescriptor scktDist;
//…
void Awake() {
server = RakPeerInterface.GetInstance();
scktDist = new SocketDescriptor();
server.Startup(maxConnectionsAllowed, 30, scktDist, 1);
server.SetMaximumIncomingConnections(maxPlayersPerServer);
}
}
===== 資料包的讀取 ===== [8]說明,如果資料包為 0,則沒有要讀取的內容。
public class PackageReading {
RakPeerInterface server;
Packet p;
//…
void Reading() {
while (true) {
if (p = server.Receive()) {
// do something terribly interesting with p...
}
}
}
}
===== 資料包的傳送 ===== [9]說明,它使用 BitStreams 建立“資料包”。
public class PackageReading {
RakPeerInterface peer;
Packet p;
//…
void Sending() {
MessageID useTimeStamp; // Assign this to ID_TIMESTAMP
Time timeStamp; // Put the system time in here returned by GetTime()
MessageID typeId; // This will be assigned to a type I've added after ID_USER_PACKET_ENUM, lets say ID_SET_TIMED_MINE
useTimeStamp = ID_TIMESTAMP;
timeStamp = GetTime();
typeId=ID_SET_TIMED_MINE;
BitStream message = new BitStream();
message.Write(useTimeStamp);
message.Write(timeStamp);
message.Write(typeId);
message.Write("Hallo",5);
peer = Send(BitStream * bitStream,HIGH_PRIORITY,RELIABLE,0,UNASSIGNED_SYSTEM_ADDRESS,true);
}
}
微軟的 Windows Communication Foundation (WCF) 是一個平臺或應用程式程式設計介面,它捆綁了多種技術,用於構建連線的服務或程式。微軟將其功能定義為:面向物件、互操作性、多種訊息模式、服務元資料、安全性和 AJAZ 和 REST 支援。 [10] 它支援透過 HTTP、TCP、訊息佇列等傳輸 SOAP。 WCF 需要 Windows XP SP2 或更高版本。 [11]
- ↑ http://code.google.com/p/lidgren-network-gen3/ - 在 Google 程式碼上的專案頁面
- ↑ http://www.xnamag.de/article.php?aid=19#chapter3 - 關於伺服器和客戶端之間連線的文章
- ↑ http://www.jenkinssoftware.com/
- ↑ http://www.jenkinssoftware.com/raknet/manual/swigtutorial.html
- ↑ a b http://www.jenkinssoftware.com/raknet/manual/Doxygen/
- ↑ http://www.jenkinssoftware.com/raknet/manual/startup.html
- ↑ http://txcom2003.wordpress.com/2011/05/29/unity-3d-and-raknet-4/
- ↑ a b http://www.jenkinssoftware.com/raknet/manual/detailedimplementation.html
- ↑ http://www.jenkinssoftware.com/raknet/manual/creatingpackets.html
- ↑ http://msdn.microsoft.com/en-en/library/ms731082.aspx
- ↑ http://msdn.microsoft.com/de-de/library/ms733890.aspx
mglaeser 和 juliusse