unity 线程 网络传输_关于Unity网络传输层的所有信息

unity 线程 网络传输

This blog is the third in a series about our upcoming networking technology known internally as UNET. We want UNET to be a system that all game developers can use to build multiplayer games for any type of game with any number of players as easily as possible. We’ll be launching UNET in the 5.x cycle.

该博客是有关我们即将推出的内部称为UNET的联网技术的系列文章中的第三篇。 我们希望UNET成为一个系统,所有游戏开发人员都可以使用它来尽可能轻松地为具有任意数量的玩家的任何类型的游戏构建多人游戏。 我们将在5.x周期中启动UNET。

Get a general overview of the UNET system here, or read on to learn about the UNET transport layer foundation!

在此处获得有关UNET系统的一般概述,或者继续阅读以了解有关UNET传输层基础的知识!

When we started to design the new network library for Unity, we want to understand what an ideal library would look like. We realized that we have (roughly) two different types of users:

当我们开始为Unity设计新的网络库时,我们想了解理想的库的外观。 我们意识到,我们拥有(大约)两种不同类型的用户:

1.   Users who want networking tools that will give them an out of the box result with minimal effort (ideally without any effort at all).

1.想要联网工具的用户可以以最小的努力获得开箱即用的结果(理想情况下完全不需要任何努力)。

2.   Users who develop network-centric games and want very flexible and powerful tools.

2.开发以网络为中心的游戏并需要非常灵活和强大的工具的用户。

Based on these two user types, we divided our network library into two different parts: a HLAPI (high-level API) and a LLAPI (low-level API).

基于这两种用户类型,我们将网络库分为两个不同的部分:HLAPI(高级API)和LLAPI(低级API)。

If you’re interested in learning more about the Syncvars we use in the high level API you can read more here. The following discussion relates to the low level API and our library design which was based on the following principles:

如果您想了解更多有关我们在高级API中使用的Syncvars的信息,请在此处阅读更多内容。 以下讨论与基于以下原则的低级API和我们的库设计有关:

Performance, performance, performance…

性能,性能,性能…

The LLAPI is a thin layer on top of the UDP socket, most of the work is performed in a separate thread (hence LLAPI can be configured to use the main thread only). There’s no dynamic memory allocation and no heavy synchronization (actually most of the library uses memory barrier synchronization with some atomic increment/decrement operation).

LLAPI是UDP套接字顶部的薄层,大部分工作在单独的线程中执行(因此LLAPI可以配置为仅使用主线程)。 没有动态内存分配,也没有繁重的同步(实际上,大多数库使用带有一些原子增量/减量操作的内存屏障同步)。

If something can be done using C# it should be

如果可以使用C#进行某些操作

We decided to only expose what we felt our users would need to use. Like BSD sockets, the LLAPI supports just one abstraction – exchanging raw binary messages. There are no tpc-like streams, serializers or RPC calls in the LLAPI; only low level messages.

我们决定只公开我们认为用户需要使用的内容。 像BSD套接字一样,LLAPI仅支持一种抽象-交换原始二进制消息。 LLAPI中没有类似tpc的流,序列化程序或RPC调用; 仅低级消息。

Flexibility and configurability? Yes please…

灵活性和可配置性? 是的,请…

If you take a look at TCP socket implementation you can find tons of parameters (timeouts, buffer length etc.) which you can change. We chose to to take a similar approach and to allow users to change almost all of our library parameters so they can tune it to their specific needs. Where we faced a choice between simplicity and flexibility we sacrificed simplicity to flexibility.

如果看一下TCP套接字的实现,您会发现可以更改的大量参数(超时,缓冲区长度等)。 我们选择采取类似的方法,并允许用户更改几乎所有库参数,以便他们可以根据自己的特定需求进行调整。 在简单性和灵活性之间进行选择的地方,我们牺牲了简单性而不是灵活性。

Nice and easy

好,易于

We tried to design the LLAPI to resemble the BSD socket API wherever possible.

我们试图将LLAPI设计为尽可能类似于BSD套接字API。

Network and transport layers

网络和传输层

Logically, the UNET low level library is a network protocol stack built on top of the UDP, containing a “network” layer and a “transport” layer. The network layer is used for creating connections between peers, delivering packets and controlling possible flow and congestion. The transport layer works with “messages” belonging to different communication channels:

从逻辑上讲,UNET低级库是建立在UDP之上的网络协议栈,包含“网络”层和“传输”层。 网络层用于在对等方之间建立连接,传递数据包并控制可能的流量和拥塞。 传输层使用属于不同通信渠道的“消息”:

communication channels

Channels serve two different purposes, they can separate messages logically and they provide different delivery grants or quality of service.

渠道有两个不同的用途,它们可以在逻辑上分离消息,并提供不同的交付授权或服务质量。

Channels configuration is a part of configuration procedure, something we’ll discuss in more detail in an upcoming post. For now, lets just consider the configuration part as “My system will contain up to 10 connections, each connection will have 5 channels, where channel 0 will have this type, and channel 1 will have other type and so on”. The last part of this sentence is defined by:

通道配置是配置过程的一部分,我们将在后续文章中对其进行详细讨论。 现在,让我们考虑一下配置部分:“我的系统最多包含10个连接,每个连接将具有5个通道,其中通道0将具有这种类型,通道1将具有其他类型,依此类推”。 这句话的最后一部分定义为:

The second parameter is channel number and last is channel type, or channel qos (delivery grant).

第二个参数是通道号,最后一个是通道类型或通道qos(交付许可)。

UNET (so far) supports the following QOS:

UNET(到目前为止)支持以下QOS:

  • Unreliable: An unreliable message which can be dropped due to network conditions, or internal buffers overflow, similar to UDP packet.  Example: Short Log Messages

    不可靠 :不可靠的消息,可能会由于网络状况或内部缓冲区溢出而被丢弃,类似于UDP数据包。 示例:短日志消息

  • UnreliableFragmented: Maximum packet length is fixed, but sometimes you will probably want to send “big” messages. This channel type will disassemble your message to fragments before sending, and assemble it back before receiving. As this qos is unreliable, delivery is not granted.  Example: Long  Logs

    UnreliableFragmented :最大数据包长度是固定的,但有时您可能希望发送“大”消息。 此通道类型将在发送之前将您的消息分解为片段,然后在接收之前将其重新组合。 由于此Qos不可靠,因此不准予交付。 示例:长日志

  • UnreliableSequenced: Channel grants delivery order, as this qos is unreliable, the message can be missed. Example: voice, video

    UnreliableSequenced :信道授予传递顺序,因为此qos不可靠,因此可能会丢失消息。 示例:语音,视频

  • Reliable: Channel grants delivery (or disconnect) but not grant order.  Example: Sending Damage

    可靠 :渠道授予投放(或断开连接),但不授予订单。 示例:发送损坏

  • ReliableFragmented: Same as UnreliableFragmented, but additionally it will grant delivery.  Example: Group Damage

    ReliableFragmented :与UnreliableFragmented相同,但另外它会授予交付。 示例:团体伤害

  • ReliableSequenced: Same as UnreliableSequenced, but additionally it will grant delivery. This QOS is analogous to TCP stream.  Example: File Delivery/Patching

    ReliableSequenced :与UnreliableSequenceded相同,但另外它会授予交付。 此QOS类似于TCP流。 示例:文件传递/修补

  • StateUpdate: An unreliable channel type plus channel with this qos will force drop messages which are older than sending/receiving. If when sent, send buffer contains more than one message, only the youngest will send. If the receiving buffer, when reading, contains more than one message only the youngest will be delivered.  Example: Sending Position

    StateUpdate :不可靠的通道类型加上带有此Qos的通道将强制丢弃比发送/接收更早的消息。 如果发送时,发送缓冲区包含多个消息,则只有最小的消息会发送。 如果接收缓冲区在读取时包含多个消息,则只会传送最小的消息。 示例:发送职位

  • AllCostDelivery: Fairly similar to Reliable qos, but there is a difference. The reliable channel will resend undelivered messages based on round trip time value (RTT) which is a dynamic parameter while AllCostDelivery will automatically resend messages after a period of time (configured value). This can be useful for small important messages: “I shot player A in the head” or “Mini-game starts”.  Example: Game events such as firing bullets

    AllCostDelivery :完全类似于Reliable qos,但是有所不同。 可靠通道将根据往返时间值(RTT)重新发送未传递的消息,该时间是一个动态参数,而AllCostDelivery将在一段时间(配置值)后自动重新发送消息。 这对于一些重要的小消息可能很有用:“我在头部射中了玩家A”或“迷你游戏开始”。 示例:游戏事件,例如发射子弹

If you have a use case you feel doesn’t fit conveniently in these categories, we’d love it if you could bring it up in the comments!

如果您有用例,感觉不适用于这些类别,那么如果您能在评论中提出它,我们将不胜感激!

Let’s review typical LLAPI function calls:

让我们回顾一下典型的LLAPI函数调用:

1.       Initialize library

1.初始化库

2.       Configure network: topology, channels amount, their types, different timeouts and buffer sizes (we discuss this in a later post)

2.配置网络:拓扑,通道数量,其类型,不同的超时时间和缓冲区大小(我们将在以后的文章中讨论)

3.       Create socket:

3.创建套接字:

This function will open the socket on port 5000 on all network interfaces, and will return an integer value as a descriptor of this socket

此函数将打开所有网络接口上端口5000上的套接字,并将返回一个整数值作为此套接字的描述符。

4.       Make connection to other peer:

4.建立与其他对等方的连接:

This function will send a connection request to “other peer” at address 127.0.0.1/6000. It will return an integer value as a descriptor of this connection for this host. You will receive the connection event when the connection is established or the disconnect event if the connection cannot be established

此功能将向地址为127.0.0.1/6000的“其他对等方”发送连接请求。 它将返回一个整数值作为此主机的此连接的描述符。 建立连接后,您将收到连接事件;如果无法建立连接,则将收到断开连接事件

5.       Send message:

5.发送消息:

This last function will send binary data contained in the buffer via socket described by hostId for peer-described connectionId using channel #1 (in our case this is “reliable channel”, so for this message delivery will be granted.

最后一个功能将通过主机ID所描述的套接字,使用通道#1通过对等连接描述的连接ID,发送包含在缓冲区中的二进制数据(在我们的情况下,这是“可靠的通道”,因此将允许此消息传递。

6.       Receiving network events:

6.接收网络事件:

For receiving network events, we chose a poll model. User should poll UTransport.Receive() function to be acknowledged about network events. Note that this model is very similar to ordinary select() call with zero timeout. This function receives 4 different events:

为了接收网络事件,我们选择了轮询模型。 用户应轮询UTransport 。 确认有关网络事件的Receive()函数。 请注意,此模型与零超时的普通select()调用非常相似。 此函数接收4个不同的事件:

  • UNETEventType.kConnectEvent – somebody connects to you, or connection requested by  UTransport.Connect() call has been successfully established

    UNETEventType 。 kConnectEvent –有人连接到您,或UTransport请求的连接 。 Connect()调用已成功建立

  • UNETEventType.kDisconnectEvent – somebody disconnects with you, or connection requested by UTransport.Connect() call cannot be established for some reason (error code will report what this reason was)

    UNETEventType 。 kDisconnectEvent –有人与您断开连接,或者由于某些原因无法建立UTransport.Connect()调用请求的连接(错误代码将报告该原因)

  • UNETEventType.kDatatEvent  – New data has been received

    UNETEventType 。 kDatatEvent –已接收到新数据

  • UNETEventType.kNothing – Nothing interesting happened

    UNETEventType 。 没事 –没事发生

7.       Send disconnect request:

7.发送断开连接请求:

This function call will send a disconnect request to a connection defined by connectionId on host defined by hostId. The connection will close immediately and can be re-used in the future.

该函数调用将向hostId定义的主机上的connectionId定义的连接发送断开连接请求。 该连接将立即关闭,以后可以重新使用。

That’s it for now! Thanks for reading, and don’t forget to check back (or subscribe to our blog) to catch the next post in the UNET series in which we’ll be discussing network topology configuration.

现在就这样! 感谢您的阅读,不要忘了返回(或订阅我们的博客 )以获取UNET系列的下一篇文章,在该文章中我们将讨论网络拓扑配置。

翻译自: https://blogs.unity3d.com/2014/06/11/all-about-the-unity-networking-transport-layer/

unity 线程 网络传输

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值