请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com
 

Network Messages

 
 
In addition to the high level facilities of commands and RPC calls, it is also possible to send raw network messages. 除了使用高层的Commands和RPC calls之外,还可以发送低层的网络消息。
 
There is a class called MessageBase that can be extended to make serializable network message classes. This class has serialization and deserialization functions that take writer and reader objects. Developers can implement these functions themselves, or rely on code-generated implementations that are automatically created by the networking system. The base class looks like this: Unity提供了一个名为MessageBase的基类。该类可供继承扩展一个可序列化的网络消息类。该类有两个序列化/反序列化虚函数,分别可以对object进行读和写操作。开发者可以重载实现它们。或者依赖于Unity网络系统自动生成的代码。这个基类的声明如下:
 
public abstract class MessageBase
{
// De-serialize the contents of the reader into this message
public virtual void Deserialize(NetworkReader reader) {}

// Serialize the contents of this message into the writer
public virtual void Serialize(NetworkWriter writer) {}
}
 
Message classes can contain members that are basic types, structs, arrays, and most of the common Unity Engine types such as Vector3. They cannot contain members that are complex classes or generic containers. Message类中可以定义为数据成员的类型有:基本类型,结构体,数组,还有大部分的Unity3D数学类。不能使用复杂的类对象和泛型容器作为数据成员。
 
EmptyMessage
StringMessage
IntegerMessage
 
There are built-in message classes for common types of network messages: 以下是几个内建的网络消息类
 
To send a message there are Send() functions on the NetworkClient, NetworkServer, and NetworkConnection classes which work the same way. They take a message Id, and a message object that is derived from MessageBase. The code below shows how to send and handle a message using one of the built-in message classes: 可以使用NetworkServer类,NetworkConnection,或者NetworkCleint类的Send成员函数发送一个网络消息。发送网络消息需要一个网络消息ID,一个继承于MessageBase类的网络消息类。下面的代码演示了如何使用一个网络内建消息类去发送消息。
 
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.NetworkSystem;

public class Begin : NetworkBehaviour
{
    const short MyBeginMsg = 1002;

    NetworkClient m_client;

    public void SendReadyToBeginMessage(int myId)
    {
        var msg = new IntegerMessage(myId);
        m_client.Send(MyBeginMsg, msg);
    }

    public void Init(NetworkClient client)
    {
        m_client = client;
        NetworkServer.RegisterHandler(MyBeginMsg, OnServerReadyToBeginMessage);
    }

    void OnServerReadyToBeginMessage(NetworkMessage netMsg)
    {
        var beginMessage = netMsg.ReadMessage<IntegerMessage>();
        Debug.Log("received OnServerReadyToBeginMessage " + beginMessage.value);
    }
}
 
To declare a custom network message class and use it: 声明和使用一个自定义的网络消息类,如下:
 
using UnityEngine;
using UnityEngine.Networking;

public class Scores : MonoBehaviour
{
    NetworkClient myClient;

    public class MyMsgType {
        public static short Score = MsgType.Highest + 1;
    };

    public class ScoreMessage : MessageBase
    {
        public int score;
        public Vector3 scorePos;
        public int lives;
    }

    public void SendScore(int score, Vector3 scorePos, int lives)
    {
        ScoreMessage msg = new ScoreMessage();
        msg.score = score;
        msg.scorePos = scorePos;
        msg.lives = lives;

        NetworkServer.SendToAll(MyMsgType.Score, msg);
    }

    // Create a client and connect to the server port
    public void SetupClient()
    {
        myClient = new NetworkClient();
        myClient.RegisterHandler(MsgType.Connect, OnConnected);
        myClient.RegisterHandler(MyMsgType.Score, OnScore);
        myClient.Connect("127.0.0.1", 4444);
    }

    public void OnScore(NetworkMessage netMsg)
    {
        ScoreMessage msg = netMsg.ReadMessage<ScoreMessage>();
        Debug.Log("OnScoreMessage " + msg.score);
    }

    public void OnConnected(NetworkMessage netMsg)
    {
        Debug.Log("Connected to server");
    }
}
 
Note that there is no serialization code for the ScoreMessage class in this source code for example. The body of the serialization functions is automatically generated for this class. 注意在上述代码中,ScoreMessage类是没有显式地编写序列化数据操作的代码的。序列化数据操作的代码将会由引擎自动生成。
 
Error Message Class
 
Thre is also a ErrorMessage class that is derived from MessageBase. This class is passed to error callbacks on clients and servers. 引擎也有提供了一个继承自MessageBase的ErrorMessage类。这个类的对象实例将作为参数传递给客户端和服务端的错误回调函数。
 
The errorCode in the ErrorMessage class corresponds to the Networking.NetworkError enumeration. ErrorMessage类中的errorCode成员为Networking.NetworkError枚举类型中的枚举值
 
class MyClient
{
    NetworkClient client;
    
    void Start()
    {
        client = new NetworkClient();
        client.RegisterHandler(MsgType.Error, OnError);
    }
    
    void OnError(NetworkMessage netMsg)
    {
        var errorMsg = netMsg.ReadMessage<ErrorMessage>();
        Debug.Log("Error:" + errorMsg.errorCode);
    }
}