简体   繁体   English

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

[英]How to design my online Game Server for Unity3d?


Recently, I have been doing multiplayer game development in unity3d. 最近,我一直在unity3d做多人游戏开发。 I have got the pretty good idea of how the Unity's MasterServer works in unity. 我已经很好地了解了Unity的MasterServer如何协同工作。
But now I want to make my own game server from scratch. 但现在我想从头开始制作自己的游戏服务器。 I researched and got to know that we can use the Google cloud compute and the app engine for making our own matchmaking server and the game host server. 我研究并了解我们可以使用Google云计算和应用引擎来制作我们自己的配对服务器和游戏主机服务器。
But I am totally clueless how do we start doing coding my server. 但我完全无能为力,我们如何开始编码我的服务器。 Do we do it using simple http request and json result? 我们使用简单的http请求和json结果吗? Or is there any other technique that can in real time work with FPS type games also. 或者还有其他技术可以实时与FPS类型的游戏一起使用。 I dont think that the sending http requests and waiting for it result can be fast enough to work in a FPS type games where every seconds we send more than 100s of datas. 我不认为发送http请求并等待它的结果可以足够快,可以在FPS类型的游戏中工作,每秒我们发送超过100个数据。
At first I thought of writing php scripts and hosting it to some url, and then sending request to that url and wait for its response. 起初我想过编写php脚本并将其托管到某个url,然后向该url发送请求并等待其响应。 But I found out that if I use this process then for just getting one response from the server it would take me atleast 0.5 seconds or more. 但我发现,如果我使用这个过程然后从服务器获得一个响应,它将花费我至少0.5秒或更多。 In this condition, there would be a lot of lag in game. 在这种情况下,游戏会有很多延迟。
I know that game servers work on some kind of tcp or udp networking. 我知道游戏服务器可以在某种tcp或udp网络上运行。 But my question is this that what kind of application shall I make for the server to receive these datas and send the processed results fast. 但我的问题是,我应该为服务器提供什么样的应用程序来接收这些数据并快速发送处理结果。

First of all I think that you are confusing MasterServer with the connection required to send and receive game data during gameplay. 首先,我认为您将MasterServer与在游戏过程中发送和接收游戏数据所需的连接混淆。

MasterServer is used to retrieve the information of the server that created the game such as IP Address and port number. MasterServer用于检索创建游戏的服务器的信息,如IP地址和端口号。 After you retrieve the IP and port number, the client can directly connect to the server with these information. 检索IP和端口号后,客户端可以使用这些信息直接连接到服务器。

Do we do it using simple http request and json result? 我们使用简单的http请求和json结果吗?

For MasterServer , yes you can. 对于MasterServer ,是的,你可以。 You can also use it in combination with PHP to save game sessions on the database. 您还可以将它与PHP结合使用,以保存数据库上的游戏会话。

For example, when player wants to create a new game, you take you take their game information such as game name, password, max players, player's ip address, port number then serialize it to json and send using RESTful. 例如,当玩家想要创建一个新游戏时,你会带你的游戏信息,如游戏名称,密码,最大玩家,玩家的IP地址,端口号,然后将其序列化为json并使用RESTful发送。

You can use PHP to receive that game information and store it into server so that other players can find it. 您可以使用PHP接收该游戏信息并将其存储到服务器中,以便其他玩家可以找到它。

This shouldn't affect performance since you only using it to create, query and destroy game seasons. 这不应该影响性能,因为您只使用它来创建,查询和破坏游戏季节。 You are not using it to send game data during game play. 在游戏过程中,您没有使用它来发送游戏数据。


As for sending data during gameplay, you do this with raw socket. 至于在游戏过程中发送数据,你可以使用raw socket。 Either TCP or UDP with C# . 使用C#的 TCP或UDP。 Go native with C++ with if you want to get the maximum performance sine Unity's UNet is written in C++ . 入乡随俗用C ++用,如果你想获得正弦统一的UNET用C语言编写的最大性能++。 Most FPS server's are written in C++ and this is to make sure that they get the maximum performance ever. 大多数FPS服务器都是用C ++编写的,这是为了确保它们获得最高性能。

Remember there are many types of servers so I can't cover all of them in this post. 请记住,有许多类型的服务器,所以我不能在这篇文章中涵盖所有这些服务器。 I will just focus on MasterServer which tells client the IP addresses on Games created then Relay which is used when direct connection between players cannot be established. 我将专注于MasterServer ,它告诉客户端创建的游戏上的IP地址,然后在无法建立玩家之间的直接连接时使用的中继。

I suggest you use Google's Protobuf over Json for its performance and lightweight. 我建议你使用谷歌的Protobuf而不是Json的性能和轻量级。 If you find any serialization API that's faster than Protobuf then use it. 如果您发现任何比Protobuf更快的序列化API,那么请使用它。

Direct Connection: 直接连接:

Server : 服务器

1 .Use Nat to perform port forwarding . 1.使用 Nat执行端口转发

2 .Create Game by creating TCP/UDP server . 2.通过创建TCP / UDP服务器创建游戏。

3 .Send the Game Info(game name, ip, port number) to the MasterServer. 3.将游戏信息(游戏名称,IP,端口号)发送到MasterServer。

4 .When client connects with that information, start sending data by serializing the data(FPS player position?) with Protobuf send, to client. 4.当客户端连接该信息时,通过使用Protobuf send将数据(FPS播放器位置?)序列化到客户端来开始发送数据。

5 .When you receive data from the client, deserialize it with Protobuf . 5.当您从客户端接收数据时,使用Protobuf对其进行反序列化。

Client : 客户

1 .Connect to the MasterServer and retrieve running Game Informations. 1.连接到MasterServer并检索正在运行的游戏信息。

2 .Create a TCP/UDP client and connect to one of the IP and port number. 2.创建TCP / UDP客户端并连接到其中一个IP和端口号。

To send and receive data, use steps from Server #4 and #5 . 要发送和接收数据,请使用Server #4#5中的步骤


Sometimes, port forwarding won't work on some devices. 有时,端口转发在某些设备上不起作用。 In that case, two players with different global IP Addresses cannot connect together and this is where a relay and C++ comes into play. 在这种情况下,具有不同全局IP地址的两个玩家无法连接在一起,这就是继电器和C ++发挥作用的地方。 The relay should not be done with http requests, json or php. 应该使用http请求,json或php完成中继。 It should be made with C++ or some similar fast language such as python. 它应该用C ++或类似的快速语言如python制作。

Again, there are many ways to do this. 同样,有很多方法可以做到这一点。 The easiest way is to generate a private key for each game that is created. 最简单的方法是为每个创建的游戏生成私钥。 When server/client send data to one another, they must include this key in that data and this key will be used to determine who the relay server should send the data to. 当服务器/客户端彼此发送数据时,它们必须在该数据中包含此密钥,并且此密钥将用于确定中继服务器应将数据发送给谁。

Connection with Relay: 与继电器连接:

Server : 服务器

1 .Create Game by connecting to sending the Game Info(game name) to the MasterServer . 1.通过连接将游戏信息(游戏名称)发送到MasterServer来创建游戏。

2 . 2 MasterServer responds by generating a private key and returning it to the Server. MasterServer通过生成私钥并将其返回到服务器来响应。

3 .Connect to the relay server with that private key. 3.使用该私钥连接到中继服务器。

4 .To send data to other players, serialize the data(FPS player position?) with Protobuf then send to the Relay server. 4.要向其他玩家发送数据,用Protobuf序列化数据(FPS播放器位置?)然后发送到中继服务器。 That data must also contain the private key. 该数据还必须包含私钥。

5 .Relay server receives data from this server, reads the private key and forward/send the data to any other client with the-same private key. 5.中继服务器从该服务器接收数据,读取私钥并使用相同的私钥将数据转发/发送到任何其他客户端。

6 .When you receive data from the Relay server that the other player sent, deserialize it with Protobuf . 6.当您从其他播放器发送的中继服务器接收数据时,使用Protobuf对其进行反序列化。

Repeat from #4 to #6 as long as the connection is still alive and game is still not over. 只要连接仍然存在并且游戏仍未结束,重复从#4#6

Client : 客户

1 .Connect to the MasterServer and retrieve running Game Informations. 1.连接到MasterServer并检索正在运行的游戏信息。

2 . 2 MasterServer responds by returning a private key of that game to the client. MasterServer通过将该游戏的私钥返回给客户端来响应。

3 .Connect to the relay server with that private key. 3.使用该私钥连接到中继服务器。

4 .To send data to other players, serialize the data(FPS player position?) with Protobuf then send to the Relay server. 4.要向其他玩家发送数据,用Protobuf序列化数据(FPS播放器位置?)然后发送到中继服务器。 That data must also contain the private key. 该数据还必须包含私钥。

5 .Relay server receives data from this server, reads the private key and forward/send the data to any other client with the-same private key. 5.中继服务器从该服务器接收数据,读取私钥并使用相同的私钥将数据转发/发送到任何其他客户端。

6 .When you receive data from the Relay server that the other player sent, deserialize it with Protobuf . 6.当您从其他播放器发送的中继服务器接收数据时,使用Protobuf对其进行反序列化。

Repeat from #4 to #6 as long as the connection is still alive and game is still not over. 只要连接仍然存在并且游戏仍未结束,重复从#4#6

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM