如何为Unity3d设计我的在线游戏服务器?

8
最近,我一直在使用Unity3D开发多人游戏。我已经很好地理解了Unity的MasterServer是如何工作的。
但是现在我想从头开始制作自己的游戏服务器。我进行了研究并知道我们可以使用Google云计算和应用引擎来制作我们自己的匹配服务器和游戏主机服务器。
但我完全不知道该如何开始编写我的服务器。我们是使用简单的http请求和json结果吗?还是有其他实时工作于FPS类型游戏的技术?我认为发送http请求并等待其结果可能不足以快速处理每秒发送100个以上的数据的FPS类型游戏。
起初,我考虑编写PHP脚本并将其托管到某个URL上,然后发送请求并等待其响应。但我发现如果我使用此过程,则仅从服务器获取一个响应就需要至少0.5秒或更长时间。在这种情况下,在游戏中会有很多延迟。
我知道游戏服务器使用某种TCP或UDP网络。但我的问题是,为接收这些数据并快速发送处理后的结果,我应制作什么类型的应用程序。

2
有太多可能的答案,或者好的答案会因为这种格式而过于冗长。请添加细节来缩小答案集或隔离可以在几段文字中回答的问题。我建议您找到一个开发论坛(也许是[Quora](http://www.quora.com/Computer-Programming)?),以解决一般性问题。然后,当您有具体的编码问题时,请回到Stack Overflow,我们将很乐意提供帮助。 - Jay Blanchard
我想知道在使用 PHP 的情况下,我是否走上了正确的道路。或者是否有其他通常用于制作游戏服务器的方法? 我是相当新手,因此很高兴接受任何意见。谢谢。 - rsinha
Unity3D拥有一个出色的内置网络/多人游戏库,可以在这里查看。 - itay_421
1
@itay_421 我认为OP想要制作自己的服务器。因此,“但现在我想从头开始制作自己的游戏服务器。” - Programmer
1个回答

12
首先,我认为你混淆了MasterServer和在游戏过程中发送和接收游戏数据所需的连接。MasterServer用于检索创建游戏的服务器的信息,例如IP地址和端口号。获取IP和端口号后,客户端可以使用这些信息直接连接到服务器。

我们是否可以使用简单的http请求和json结果来完成?

对于MasterServer,是的,您可以。您还可以将其与PHP结合使用,在数据库上保存游戏会话。
例如,当玩家想要创建新游戏时,您需要获取他们的游戏信息,例如游戏名称、密码、最大玩家数、玩家的IP地址、端口号,然后将其序列化为JSON并使用RESTful发送。
您可以使用PHP接收游戏信息并将其存储到服务器上,以便其他玩家可以找到它。 这不应该影响性能,因为您只使用它来创建、查询和销毁游戏季节。您在游戏过程中使用它来发送游戏数据。

关于在游戏过程中发送数据,您可以使用原始套接字进行操作。无论是使用C#的TCP还是UDP,或者如果您想获得最大的性能,可以使用本机C++,因为Unity的UNet是用C++编写的。大多数FPS服务器都是用C++编写的,这样可以确保它们获得最大的性能。

请记住,有许多类型的服务器,所以我无法在本文中涵盖所有类型。我将专注于MasterServer,它会告诉客户端创建的游戏的IP地址,然后是Relay,当玩家之间不能建立直接连接时使用。

我建议您使用Google的Protobuf而不是Json,因为它具有良好的性能和轻量级。如果您找到比Protobuf更快的序列化API,则使用它。

直接连接:

服务器:

1.使用Nat执行端口转发

2.通过创建TCP/UDP服务器来创建游戏。

3.向MasterServer发送游戏信息(游戏名称、IP地址、端口号)。

4.当客户端使用该信息连接时,通过使用Protobuf序列化数据(FPS玩家位置?),向客户端发送数据。

5.当您从客户端接收数据时,使用Protobuf反序列化它。

客户端:

1.连接到MasterServer并检索运行中的游戏信息。

2.创建一个TCP/UDP客户端,并连接到其中一个IP和端口号。

要发送和接收数据,请使用服务器的步骤#4#5


有时端口转发在某些设备上无法使用。在这种情况下,具有不同全局IP地址的两个玩家无法连接在一起,这就是中继和C++发挥作用的地方。中继不应该使用http请求、json或php完成,而应该使用C++或类似的快速语言,比如python。
同样,有很多方法可以做到这一点。最简单的方法是为创建的每个游戏生成一个私钥。当服务器/客户端相互发送数据时,它们必须在数据中包含此密钥,此密钥将用于确定中继服务器应将数据发送到哪里。
与中继的连接:
服务器:
1.通过连接将游戏信息(游戏名称)发送到MasterServer来创建游戏。
2.MasterServer通过生成私钥并将其返回给服务器来做出回应。
3.使用该私钥连接到中继服务器。
4.要将数据发送到其他玩家,请使用Protobuf对数据进行序列化(FPS玩家位置?),然后将其发送到中继服务器。该数据还必须包含私钥。

5.转发服务器从此服务器接收数据,读取私钥并将数据转发/发送到具有相同私钥的任何其他客户端。

6.当您从中继服务器接收到另一位玩家发送的数据时,使用Protobuf进行反序列化。

只要连接仍然存在且游戏仍未结束,请重复从#4#6

客户端

1.连接到MasterServer并检索正在运行的游戏信息。

2.MasterServer通过向客户端返回该游戏的私钥来响应。

3.使用该私钥连接到中继服务器。

4.要向其他玩家发送数据,请使用Protobuf序列化数据(FPS玩家位置?),然后将其发送到中继服务器。该数据还必须包含私钥。

5.转发服务器从此服务器接收数据,读取私钥并将数据转发/发送到具有相同私钥的任何其他客户端。

6. 当您从Relay服务器接收到其他玩家发送的数据时,请使用Protobuf进行反序列化。
请在连接仍然活动且游戏尚未结束时,重复执行#4#6

很好的答案,但是你为什么认为Python是一种快速语言呢? - Bloodday
1
@Bloodday 我指的是Stackless Python。虽然我不是Python的粉丝,但我们在大学里使用它来处理大量数据,由于其更平滑的多线程特性,速度非常快。假设这是一个大型多人在线游戏,它可以很好地处理它。我提到Python作为一种替代方案,但出于性能和安全原因,我会推荐C ++。这可以用任何语言完成,但如果你想处理许多用户,必须使用C ++。 - Programmer
Python被用于机器学习和数据处理,因为与此目的一起使用的软件包是用C++编译的。但是,从头开始用Python编写多人游戏将导致服务器极慢,因为它是最慢的解释性语言之一。 - Bloodday
1
是的,我知道它是解释性的。我曾看到过《无栈Python》被用于编写MMO游戏服务器。它表现得非常好而且不慢。如果你有Python的经验,那么没有什么能阻止你使用它,甚至比C++更好。这比使用PHP要好,因为大多数Unity程序员似乎现在都在使用它。 - Programmer
你知道有趣的事吗?这篇帖子没有标记为Python。这是一个非常彻底、深思熟虑和写得很好的答案,太漂亮了 @程序员 - Technivorous
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接