# 传输示例

在使用匹配器或大厅管理玩家并通过 Edgegap API 为他们创建中继会话后，当中继准备好时，需要将玩家连接到该中继。Edgegap 提供了一个专用传输来实现此目的，本指南将向你展示如何在项目中实现它。该传输可在 [我们的 GitHub 上获得](https://github.com/edgegap/distributed-relay-examples/tree/main).

对于 Unity，目前该传输有以下 netcode 的版本：

* Mirror；
* Fishnet；
* Unity Netcode for GameObjects (NGO)。

### 添加传输

在下载适合你所用 netcode 的传输后，需要将其包含到项目中。首先，将其添加到项目文件的以下位置：

* **Mirror** ：在 `Edgegap` 文件夹下添加 `Assets/Mirror/Transports`;
* **Fishnet** ：在 `Edgegap KcpTransport` 文件夹下添加 `Assets/Fishnet/Plugins`;
* **NGO** ：在 `EdgegapRelay` 与 `kcp2k` 文件夹下 `Assets/Edgegap`.

然后，添加 `EdgegapKcpTransport` 脚本到你的 `NetworkManager` gameObject，确保将该新组件拖拽到该 `Transport` 属性上。

{% hint style="info" %}
如果有该选项，请确保禁用 `Relay GUI` 在 `EdgegapKcpTransport` 组件的 `NetworkManager`。否则，在尝试连接到中继时它会产生干扰。

该选项主要存在于 Mirror 和 NGO 版本的传输中。
{% endhint %}

### 连接到中继

在完成匹配并创建中继会话后，使用 Edgegap API 来确定中继何时准备好接受连接。一旦准备就绪，使用 API 响应中提供的数据来设置传输的各项数值。你需要在相应字段中填写以下值：

* 中继的 `IP` 地址用作 `传输的中继地址`;
* 由 `会话授权令牌` 用作 `传输的会话 ID`;
* 由 `用户的授权令牌` 用作 `传输的用户 ID`.

#### 服务器/主机 连接

* 中继的 `服务器端口` 值用作 `传输的中继端口` .

#### 客户端 连接

* 中继的 `客户端端口` 值用作 `传输的中继端口` .

{% hint style="info" %}
每个玩家都会有自己唯一的授权令牌，但会话令牌在会话中的每个玩家之间保持相同。
{% endhint %}

### 使用 Mirror

```cs
// `data` 是反序列化为 JSON 的 API 响应
// `_EdgegapTransport` 是 EdgegapKcpTransport

// 将 uint? 转换为 uint
uint sessionAuthorizationToken = data.authorization_token ?? 0;

//TODO 找到哪个会话用户对应该玩家，`i` 表示其在列表中的位置
uint userAuthorizationToken = data.session_users?[i].authorization_token ?? 0;

_EdgegapTransport.ChangeValue(
    data.relay.ip,
    data.relay.ports.client.port,
    data.relay.ports.server.port,
    data.session_id,
    sessionAuthorizationToken,
    userAuthorizationToken
);

// 如果是主机玩家，则调用 `NetworkManager.Singleton.StartHost();`
// 或者如果是客户端，则调用 `NetworkManager.Singleton.StartClient();` 
```

### 使用 Fishnet

```cs
// `data` 是反序列化为 JSON 的 API 响应
// `_transport` 是 EdgegapKcpTransport

// 将 uint? 转换为 uint
uint sessionAuthorizationToken = data.authorization_token ?? 0;

//TODO 找到哪个会话用户对应该玩家，`i` 表示其在列表中的位置
uint userAuthorizationToken = data.session_users?[i].authorization_token ?? 0;

Relay relay = data.relay;
string address = relay.ip;
ushort serverPort = relay.ports.server.port;
ushort clientPort = relay.ports.client.port;

var relayData = new EdgegapRelayData(
    address,
    serverPort,
    clientPort,
    userAuthorizationToken,
    sessionAuthorizationToken
);
_transport.SetEdgegapRelayData(relayData);

// 然后如果是主机调用 `_transport.StartConnection(true);`
// 或者如果是客户端调用 `_transport.StartConnection(false);`
```

### 使用 NGO

```cs
// `data` 是反序列化为 JSON 的 API 响应
// `_EdgegapTransport` 是 EdgegapKcpTransport

// 将 uint? 转换为 uint
uint sessionAuthorizationToken = data.authorization_token ?? 0;

//TODO 找到哪个会话用户对应该玩家，`i` 表示其在列表中的位置
uint userAuthorizationToken = data.session_users?[i].authorization_token ?? 0;

_EdgegapTransport.relayAddress = data.relay.ip;
_EdgegapTransport.relayGameClientPort = data.relay.ports.client.port;
_EdgegapTransport.relayGameServerPort = data.relay.ports.server.port;
_EdgegapTransport.sessionId = sessionAuthorizationToken;
_EdgegapTransport.userId = userAuthorizationToken;

// 如果是主机玩家，则调用 `NetworkManager.Singleton.StartHost();`
// 或者如果是客户端，则调用 `NetworkManager.Singleton.StartClient();` 
```

### 使用 ApiResponse

```cs
public class ApiResponse
{
    public string session_id { get; set; }
    public uint? authorization_token { get; set; }
    public string status { get; set; }
    public bool ready { get; set; }
    public bool linked { get; set; }
    public object? error { get; set; }
    public List<SessionUser>? session_users { get; set; }
    public Relay relay { get; set; }
    public object? webhook_url { get; set; }
}
```

一旦这些数值正确设置，使用传输将每个玩家连接到中继。过一会儿，你就可以开始玩游戏了！

### 示例项目

以下项目是使用 Edgegap 中继传输的简单示例。

要使它们正常工作，请打开命令提示符终端并通过 `git clone [URL]` 命令下载项目。在 Unity Hub 中打开项目文件夹，然后更改 `RelayProfileToken` 值在 `HelloWorldManager` 组件的 `NetworkManager` gameObject 中为你自己的中继配置文件令牌。

* [Mirror 示例](https://github.com/edgegap/unity-mirror-relay-sample)
* [Fishnet 示例](https://github.com/edgegap/unity-fishnet-relay-sample)
* [NGO 示例](https://github.com/edgegap/unity-ngo-relay-sample)

{% hint style="info" %}
使用你自定义的 [中继配置文件令牌](https://app.edgegap.com/relay-management/dashboard) 置于 `HelloWorldManager.cs` 或 `EdgegapRelayService.cs`.
{% endhint %}
