NetworkServer中注册事件RegisterHandler
主要是注册服务端使用的事件
// message handlers
/// <summary>Register a handler for message type T. Most should require authentication.</summary>
// TODO obsolete this some day to always use the channelId version.
// all handlers in this version are wrapped with 1 extra action.
public static void RegisterHandler<T>(Action<NetworkConnectionToClient, T> handler, bool requireAuthentication = true)
where T : struct, NetworkMessage
{
ushort msgType = MessagePacking.GetId<T>();
if (handlers.ContainsKey(msgType))
{
Debug.LogWarning($"NetworkServer.RegisterHandler replacing handler for {
typeof(T).FullName}, id={
msgType}. If replacement is intentional, use ReplaceHandler instead to avoid this warning.");
}
handlers[msgType] = MessagePacking.WrapHandler(handler, requireAuthentication);
}
使用方法如下:
先设计传输的数据
public struct TestServerMessage: NetworkMessage
{
public string message;
}
在服务端注册事件,注意一定要在服务端,事件格式如下所示
NetworkServer.RegisterHandler<TestServerMessage>(OnTestServerMessage);
public void OnTestServerMessage(NetworkConnectionToClient conn, TestServerMessage msg)
{
Debug.Log(msg.message);
}
然后发送事件,客户端使用Send发送事件,发送给服务端执行,而不是发送给其他客户端
NetworkClient.Send(new TestServerMessage {
message="我来了"});
NetworkClient.Send() 函数
主要是发送数据给服务端,调用注册的服务端函数
// send
/// <summary>Send a NetworkMessage to the server over the given channel.</summary>
public static void Send<T>(T message, int channelId = Channels.Reliable)
where T : struct, NetworkMessage
{
if (connection != null)
{
if (connectState == ConnectState.Connected)
{
connection.Send(message, channelId);
}
else Debug.LogError("NetworkClient Send when not connected to a server");
}
else Debug.LogError("NetworkClient Send with no connection");
}
NetworkConnectionToClient中的Send函数
主要是向该连接的客户端发送消息,例如我在服务端保存了所有客户端NetworkConnectionToClient,可以通过该客户端的Send函数执行对应的事件
// Send stage one: NetworkMessage<T>
/// <summary>Send a NetworkMessage to this connection over the given channel.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Send<T>(T message, int channelId = Channels.Reliable)
where T : struct, NetworkMessage
{
using (NetworkWriterPooled writer = NetworkWriterPool.Get())
{
// pack message and send allocation free
MessagePacking.Pack(message, writer);
NetworkDiagnostics.OnSend(message, channelId, writer.Position, 1);
Send(writer.ToArraySegment(), channelId);
}
}
例如在服务器端运行的OnServerConnect函数中,检测到一旦有客户端加入,就会执行该函数,conn为加入函数的客户端NetworkConnectionToClient 。
public override void OnServerConnect(NetworkConnectionToClient conn){
}
创建一个客户端使用的传输数据
public struct TestClientMessage : NetworkMessage
{
public string message;
}
注册该事件,每个客户端都要注册,如果出现客户端没有注册该事件,但是仍然发送数据过去,就会出现下面这个错误,因为NetworkClient没有注册该事件,所以会出现该问题
一般注册在OnStartClient函数中
public override void OnStartClient(){
NetworkClient.RegisterHandler<TestClientMessage>(OnTestClientMessage);
}
public void OnTestClientMessage(TestClientMessage msg)
{
Debug.Log(msg.message);
}
注册完成之后,进行发送调用
public override void OnServerConnect(NetworkConnectionToClient conn){
conn.Send(new TestClientMessage {
message=conn.connectionId+"发来消息"});
}