Photon——Product Overview 产品概述
Product Overview 产品概述
On the client-side, Photon supports various platforms. Even though programming in C, C# and Flash is very different, the basic workflow stays similar. In this online documentation we try to explain the concepts and background, while language specifics are left to the reference documentation per platform.
在客户端,Photon支持多样的平台,使用C,C#,Flash进行编程的方式是不同的,但是基本的工作流是相似的。在这文档中我们尝试去解释它的概念和背景,而语言的细节部分需要查阅每个语言平台的参考文档。
Each Photon Client SDK comes with a fitting reference documentation for its platform and language.
每一个客户端SDk都带有相关平台的参考文档。
Project Setup 项目设置
You need to include a single library to communicate with Photon on the client-side. This is a different setup per platform.
在客户端你需要包含一个独立的library ,每个平台的设置是不同的。
- DotNet
Add a reference to the PhotonDotNet.dll in your DotNet project to make its classes known. Import the lib’s namespace with: using ExitGames.Client.Photon;
在项目中引用PhotonDotNet.dll,引用命名空间using ExitGames.Client.Photon
- Unity3d
You need to import the PhotonUnity3D.dll into your project in Unity. Simply open a Unity project/scene, open an explorer and drag and drop the .dll from <sdk>\libs\debug\ into the editor. Again, import the lib’s namespace with: using ExitGames.Client.Photon;
你需要导入PhotonUnity3D.dll到项目中,打开Unity 的project/scene,打开资源管理器从<sdk>\libs\debug\ 拖放PhotonUnity3D.dll到editor,导入命名空间using ExitGames.Client.Photon;
Workflow 工作流
The simplified lifecycle for any multiplayer game looks like this:
多人游戏的简化生命周期如下:
- Connect to server
连接服务器
- Make RPC calls
RPC调用
- Receive something
接收数据
- Disconnect
断开连接
很简单,让我们来看看每一个步骤,以Lite为例。
- Connect to server 连接服务器
Actually, you do a little more than just connect in this step. In short:
事实上,你做的不只是连接而已:
- Implement the interface IPhotonPeerListener in one of your classes
在你的类中实现接口IPhotonPeerListener
- Create a LitePeer instance with your server’s address
创建LitePeer 实例和你服务器的地址
- In your game loop, call Service about 10 times a second
在你的游戏循环中大约10秒调用一次服务
- Now call Connect to establish the connection. The application name should match one in the PhotonServer.config
现在建立连接,这应用程序的名字要与PhotonServer.config中的匹配
- Your implementation if PeerStatusCallback is called when the connection is ready or failed
你要实现的是当连接是未连接的时候调用PeerStatusCallback
- The returned status be StatusCode.Connect
返回的状态是StatusCode.Connect
The peer instance provides you with some methods to talk to Photon. It does not have its own thread. It updates when you call Service instead. This will keep the connection alive
peer 实例提供了一些方法去访问Photon,它没有自己的线程,当你调用服务时它进行更新,并保持着连接
We assume that Photon is running the “Lite” Application, which it does by default.
我们假设Photon运行着Lite,以下是默认情况。
- Make RPC calls RPC调用
After connecting, the client can call methods in the Lite Application just about anytime it needs to. The methods available as “remote procedure call” are called operations.
连接后,客户端可以再任何时候去调用Lite应用的方法,这样的远程过程调用被称为操作
Operation calls are asynchronous and won’t block your game. They are queued internally until you intently send something by calling SendOutgoingCommands. There will be a short delay until the result is received. These results are defined per operation and are not used at all sometimes.
操作调用是异步的,并且不会阻碍你的游戏。他们是在内部排队的直到你需要发送他们的时候通过SendOutgoingCommands发送。收到结果只需要很短暂的延迟时间,这些结果是被定义为操作并且不是所有的时间都被使用的。
- Call OpJoin with any room name to get into a game
调用OpJoin 可以加入游戏
- Wait for the callback: OperationResult with opCode: LiteOpCode.Join
等待回调带有 opCode: LiteOpCode.Join 的 OperationResult
- Send any hashtable with content by calling OpRaiseEvent. Other players in the room will receive events.
通过调用OpRaiseEvent发送带有内容的hashtable ,其他这个房间的玩家也将收到相关的事件信息。
Joining a room and raising events in it is provided (server side) by the Lite Application logic we use in this sample. You can use other applications and implement your own operations.
这是一个按照Lite应用的逻辑加入房间并触发事件的例子,你可以使用其他的应用并且实现你自己的操作
- Receive something 接收数据
In the previous step you already received an operation result. We differentiate those from other incoming messages, so called events. Lite will forward the event you raised to others in a room.
在前面的步骤,你已经接收到了操作的结果,我区别于来自其他地方的信息,所以称之为事件,Lite将发送这事件触发到房间中的其他人。
调用IPhotonPeerListener.EventAction接收事件,evCode 将与你使用的OpRaiseEvent进行匹配
The client library will internally queue received packages, so your game decides when to use them. EventAction is called by your calls to PhotonPeer.Service.
这客户端将接收到的数据包进行内部排队,由你的游戏决定何时使用它们,通过调用PhotonPeer.Service来调用EventAction
- Disconnect 断开连接
When a client is closed, the best is to disconnect. That’s nice, but not a must-have as a timeout will disconnect clients that don’t answer anymore.
当客户端是关闭的时候,最好是断开连接,但不是作为超时断开。
- To close the connection: call Disconnect
关闭连接:调用Disconnect
- Check “disconnect” return in PeerStatusCallback with statusCode: StatusCode.Disconnect
检查 “disconnect” ,PeerStatusCallback 的返回值为statusCode: StatusCode.Disconnect
- Now the client can stop calling service
现在客户端可以停止调用服务了
LitePeer versus PhotonPeer LitePeer与PhotonPeer
Aside from the LitePeer, the client libraries also include a PhotonPeer which could be used. The PhotonPeer has the bare minimum of API needed for Photon. It is the base for LitePeer, which adds operations like “Join”, “Leave” and “RaiseEvent”, which are available with the Lite Application.
除了LitePeer,客户端还包含了一个PhotonPeer 可以使用,PhotonPeer 对于Photon只有有限的API,它是LitePeer的基础,Lite中LitePeer增加了“Join”、“Leave” 、“RaiseEvent”等。
Reliable UDP 可靠的UDP
Under the hood, Photon clients and servers send operations and events via UDP. This guarantees low overhead, flexibility and performance but is unreliable by definition.
在底层,Photon客户端和服务器通过UDP发送操作和事件的,这保证了低开销、灵活性和性能但是被定义为不可靠的。
Within the UDP packages, Photon uses a thin binary protocol to enable aggregation, ordering, detection of packet loss and more. It is based on eNet and used in similar form on client and server.
在UDP包中,Photon 使用了一个精简的二进制协议来进行聚合、排序、检测数据包丢失,它是基于eNet的被用于服务器和客户端
So called “commands” are used to transfer the payload, such as operations. On the client side, Photon gives you full control of when commands are put into a UDP package and send.
所谓的“commands”是用于传递这负载的,例如操作。在客户端,由Photon控制命令以UDP包的形式进行发送
As a result, the API also includes methods that manage the connection to the server. Basically, there are two “layers”: the “command layer” and the “operation layer”:
因此,API还包括管理连接服务器的方法,基本上,他们是由两个层组成:“command layer” 和 “operation layer”
- Command layer: manages the communication protocol to establish and maintain communication.
命令层:管理通信协议建立连接并保持通信
- Operation layer: gives access to rooms, events and custom Operations. Client side, methods of this layer are prefixed with “Op”.
操作层:用于访问房间、事件、自定义操作。在客户端,这层的方法被加上了前缀 “Op”
Reliable vs. Unreliable 可靠对不可靠
With Photon’s underlying protocol, everything that’s sent across can be made flagged as reliable or unreliable. The operation request is not changed by this though, only the command that’s used.
Photon的底层协议,可以被标记为可靠或不可靠,仅仅在命令被使用的时候操作请求是不可更改的。
Photon keeps track of the ordering. Even unreliable commands are synchronized/sequenced within the order of reliable commands. So an unreliable command, which was sent after a certain reliable command, will also be dispatched after the reliable command was dispatched (even if that command was delayed).
Photon 保持跟踪,不可靠的命令是随着可靠的命令进行同步测序,所以一个不可靠的命令,被发送在一个可靠的命令之后,也将在可靠命令被分派之后再进行分派。
Operations and events that are sent as unreliable might get lost. As example, this is no problem for position updates, which are quickly replaced. On the server side, Operations that are received unreliable, should not create a result: The client can not expect that the operation even reached the server.
操作和事件发送是不可能丢失的,举例,对于位置的更新这不是问题,更新很快就被替换了,在服务端,接收到的不可靠的操作不会创建这样一个结果:客户端不会期望这操作到达服务器。
Connection and Timeout 连接与超时
The client has two rules to define a timeout:
这客户端有两种规则去定义超时:
- Retries: A reliable command is sent multiple times to be acknowledged, each time the interval between retries gets longer, depending on general rountrip times. If the number of retries reaches a limit (in DotNet: SentCountAllowance), this causes a disconnect.
重试:一个可靠的命令将会被发送多次以用作确认,每次重试的时间间隔变长,根据统一的区域时间定义,如果重试次数达到一个极限,将会断开连接。
- DisconnectTimeout: This defines a maximum number of milliseconds, before a reliable command must be answered. This is independent of the retry counting. In DotNet, the setting is: DisconnectTimeout.
断开超时:这定义了一个可靠命令必须答复的时间间隔的最大毫秒值,这是独立于重试计数的,在DotNet中设置为DisconnectTimeout
The settings are described in more detail in the client API documentation.
这详细的信息请阅览客户端文档。