【发布时间】:2023-04-04 22:35:01
【问题描述】:
我正在尝试使用覆盖虚拟功能 NetworkConnection.TransportSend 和 NetworkConnection.TransportRecieve (btw this is a typo in the API, it's spelled receive!) 的能力创建自己的网络接口,这是我的代码:
void CreateNetworkClient(ConnectionId _connectionId) {
Debug.Log("creating new network client with connectionId " + _connectionId);
DummyConnection newDummyConnection = new DummyConnection ();
newDummyConnection.Initialize ( _connectionId.ToString (), 0, _connectionId.id, new HostTopology(connectionConfig, 100)); //create a new dummy connection, which we'll assign to the high level API networkClient from its constructor
networkClient = new NetworkClient(newDummyConnection);
networkClient.SetNetworkConnectionClass<DummyConnection> (); //not sure how to use this, because it's supposed to apply this class to /new/ connections
networkClient.connection.logNetworkMessages = true;
Debug.Log ("networkClient class: " + networkClient.networkConnectionClass.Name); //shows DummyConnection
Debug.Log ("networkClient connection Id: " + networkClient.connection.connectionId);
networkManager.client = networkClient;
ClientScene.Ready (networkClient.connection); //tell server we're ready to spawn
if (!networkClient.connection.isConnected)
Debug.LogError ("network client failed to connect");
}
public class DummyConnection : NetworkConnection {
//override the sending function called every time a networkClient or networkServer wants to send data.
public override bool TransportSend(byte[] bytes, int numBytes, int channelId, out byte error) {
Debug.Log ("using dummy connection to send data to " + connectionId);
error = 0;
if (channelId == Channels.DefaultReliable)
SendData (bytes, (short)connectionId, true);
else if (channelId == Channels.DefaultUnreliable)
SendData (bytes, (short)connectionId, false);
else
Debug.LogError ("error in DummyConnection: unknown channel! Try using default reliable or unreliable or adding support");
return true; //probably not good. This might trick it into thinking there's no errors, ToDo: fix
}
//just a debug function
public override void TransportRecieve(byte[] bytes, int numBytes, int channelId)
{
StringBuilder msg = new StringBuilder();
for (int i = 0; i < numBytes; i++)
{
var s = String.Format("{0:X2}", bytes[i]);
msg.Append(s);
if (i > 50) break;
}
Debug.Log("TransportRecieve h:" + hostId + " con:" + connectionId + " bytes:" + numBytes + " " + msg);
HandleBytes(bytes, numBytes, channelId);
}
}
基本上,我试图让 networkClient 和 Server 的 NetworkConnection 使用这个 DummyConnection 类,它通过我自己的网络解决方案强制发送数据。这是一种实验。我“滥用”了 NetworkConnection.Initialize 中的参数,只是简单地放置了我的网络解决方案生成的我自己的自定义 connectionId,因为我没有将 NetworkConnection 用于其他任何事情,而是假装一个实际的连接。然后当它需要发送数据时,它应该在 DummyConnection 中调用我的覆盖函数 TransportSend。我这样做是因为我希望仍然能够将高级 API 与 [SyncVar] 和 [Command] 等功能一起使用。
所以我连接了我自己的网络解决方案,然后添加了一个虚拟连接,我试图让 networkClient 和 networkServer 使用这个 DummyConnection,但是双方都没有显示通过 DummyConnection 发送时应该出现的调试日志。
调试显示networkClient、其关联的networkConnection和networkManager都处于活动状态并已连接。
到目前为止,我的自定义网络解决方案无关紧要,但可以正常连接。
将连接设置为使用 NetworkConnection.logNetworkMessages 确实表明客户端正在发送数据,在控制台中记录第一条消息(ClientScene.Ready())。
所以我的问题是,我设置正确吗?因为当我强制数据通过它时,我什至无法通过 DummyConnection 记录错误。 以下信息会有所帮助:
- 确切的 unity3d 网络堆栈是什么?例如:
- NetworkServer 和 NetworkClient 是否必须使用
TransportSend()和TransportRecieve()? - NetworkClient 是否必须使用
networkClient.Connect()才能尝试向其连接发送数据?
【问题讨论】:
标签: c# networking unity3d network-programming multiplayer