使用 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