独自构建 Unity 网络服务器

所有单独的网络服务器的源代码都可以从 Unity 网站上下载。包括连接测试器、服务商、主服务器和代理服务器。

所有源代码包都包含 RakNet 3.732 网络库,该库能处理基本的网络函数并可提供 网络服务器使用的插件。

源代码包包含三种不同类型的工程文件,可直接用于编译:

Xcode 和 Visual Studio 工程可被打开、编译和构建。要使用生成文件 (Makefile) 进行构建,只需运行“make”。它应与 Linux 和 Mac OS X 上的标准编译设置配合使用,如果您有 gcc,它就会运行。在 Linux 上您可能需要安装 ncurses 库。

结构

主服务器

主服务器 (Master Server) 使用内部数据库结构来追踪主机信息。

主机发送带有 RUM_UPDATE_OR_ADD_ROW 消息标识符并嵌入了所有主机信息的消息。此过程由 LightweightDatabaseServer.cpp 文件中的 OnReceive() 函数处理。这里是所有消息最初出现的地方,因此也是您开始追踪消息处理过程的好位置。数据库结构中为每个游戏类型创建了一个表,在使用MasterServer.RegisterHost 函数时会对该表进行设置。所有游戏类型都被聚集在一个表中,如果该表不存在,则会在 CreateDefaultTable() 函数中动态地创建该表。

主机信息数据由主服务器修改。正在注册的游戏 IP 和端口在被主服务器发现时会被加入到主机数据中。这样,在主机有私有地址(NAT 地址)的情况下我们一定能检测到正确的外部 IP 和端口。主机数据中游戏服务器发送的 IP 和端口是私有地址和端口,将被保存以供后续使用。如果主服务器检测到客户端正在请求游戏服务器的主机数据,并且游戏服务器有相同的 IP 地址,那么它将用服务器的私有地址来代替外部地址。这用于处理客户端和服务器在相同的本地网络上并使用带 NAT 地址的相同路由器时的情况。因此它们会有相同的外部地址但无法通过它互相连接,它们需要使用私有地址,这些地址在该情况下将会有用。

客户端发送带有 ID_DATABASE_QUERY_REQUEST 消息标识符以及其正在寻找的游戏类型的消息。从数据库结构中取得表或主机列表并将其发送到客户端。如果没有找到,则会发送空的主机列表。

发送给主服务器的所有消息都必须包含在 CheckVersion() 函数中被检查的版本信息。此时 Unity 的每个版本都会在内部设置一个新的主服务器版本并在此进行检查。因此如果主服务器通信程序会在任何点发生更改,它将会在此处检测更旧的版本,并可能参考主服务器的其他版本(如果必要的话),或者修改该消息的处理以说明该差别。

服务商

服务商在不修改的前提下直接使用 RakNet 的 NAT 穿透 (punchthrough) 插件。这在本质上只是在加载了 NAT 穿透 (punchthrough) 插件的端口上的同级监听 (peer listening)。当有 NAT 地址的服务器和客户端都连接到这一级时,它们将能执行 NAT 穿透 (punchthrough) 来相互连接。当 Network.InitializeServer 使用 NAT 时,会自动为您建立连接。

Page last updated: 2013-06-27