DarkRift 2 Tutorial for Unity 3D – Part 8 – DarkRift 2 Messages – Concepts

Reminder : You can find all the DarkRift2 related articles here 
You can find the entire project on my official GitHub

What is a DarkRift2 message ?

Each communication between a client and a server is message-based. That’s the only way to send and receive information from a client or the server. Messages are used for example to :

  • Spawn objects into the client scene, when another players connects for exemple
  • Send network objects positions
  • Send profil information (player rank, connected friends, …)

All message are send by TCP or UDP. Depending of the type, messages is built like that :

  • A : Header Message : This part is uncompressible. The size taken by this one cannot be reduced. In DarkRift2, the size has been incredibly optimized
    • DarkRift1 : 13 bytes
    • DarkRift2 : 3 bytes with UDP, 7 bytes with TCP composed by :
      • TCP additional header : 4 bytes wich are necessary for TCP communication only.
      • Flag : 1 byte : for additional information like bit numbering or future features like server-server communication or ping I think (Thx @Allmaron)
      • Tag : ushort (2 bytes) :
        What the message is about (Spawn, Position, login info, …)
  • B : Message content data : Here is the information you want to send :
    size depends on sended data

Send DarkRift2 messages

There is 2 classes (in DarkRift namespace) that we need to create and send the message :

  • DarkRift.Writer : This class will build the content message.
  • DarkRift.Message : This is the complete message with the 3 parts described above.

Here is its usage :

using (DarkRiftWriter messageDataWriter = DarkRiftWriter.Create())
{
	//Build the message data
	messageDataWriter.Write("MyDataToSend");
	messageDataWriter.Write("AnotherDataToSend");
	messageDataWriter.Write(154);

	using (Message myMessage = Message.Create(MESSAGE_TAG, playerWriter))
	{
		//Send a message to a client
		ClientToSendMessage.SendMessage(myMessage, SendMode.Reliable);
	}
		
}

If you need more information about Using(), you can find what you need here. To sum up, using this will destroy automatically the object instantiated into the Using(), wich free the memory of this object

You can see the MESSAGE_TAG parameter. It describes what the message is about. It will be useful when you need to read the message, in order to know what this message concerns

Receive DarkRift2 messages

When a client receive a message, it throws an event MessageReceived that must be used in order to read it. It’s the only way to read the message.

For this, you will need 2 classes (in DarkRift namespace) wich are :

  • Reader : This class will get data inside the message. You can read data one by one or can use serializable classes (wich are described below)
  • Message : This is the same classe used for the sending.

So, when you instantiate your client, you need to listen to this message :

client.MessageReceived += MyFunctionToCall;

Once it’s done, you need to create the function MyFunctionToCall with these parameters wich are mandatory to be compliant with the suscribtion of the event

void MyFunctionToCall(object sender, MessageReceivedEventArgs e)
{
    //Get the received message
    using (Message message = e.GetMessage())
    //Use the DarkRift2 reader
    using (DarkRiftReader reader = message.GetReader())
    {
        //Get the tag
        int tag = message.Tag;

        //read message content
        string firstLine = reader.ReadString();
        string secondLine = reader.ReadString();
        int firstInt = reader.ReadInt32();

        if(tag == 1)
            //Do something with your data
        else if (tag == 2)
            //Do another thing with your data
    }
}

The code is pretty simple to understand but there is something that perturbs me. the way of getting back data from the message. As you can see, you have to know exactly how the data are organized in the message. Of course, you know that because it’s probably you that have written the message. but it’s very inappropriate in a big network game with a lot of messages.

There is another way to send and read data from DarkRift2 messages. that’s serializable classes. DarkRift2 provides an interface that allows you to build message structure independantly from the message. Like that you can modify easly a message content whitout rewritting everywhere it’s used.

How to use IDarkRiftSerializable 

In order to use classe to send message, you need to create a classe that implements this interface : IDarkRiftSerializable .
Here is an example :

public class MyMessageContent : IDarkRiftSerializable
{
    //Data to send within the message
    public string myName;
    public int myAge;

    //Constructor (can be empty)
    public MyMessageContent()
    {    }

    #region Interface implementation IDarkRiftSerializable
    //Used by the DarkRift reader
    public void Deserialize(DeserializeEvent e)
    {
        myName = e.Reader.ReadString();
        myAge = e.Reader.ReadInt32();
    }

    //Used by the DarkRift writer
    public void Serialize(SerializeEvent e)
    {
        e.Writer.Write(myName);
        e.Writer.Write(myAge);
    }
    #endregion
}

Sending message with serializable

using (DarkRiftWriter messageDataWriter = DarkRiftWriter.Create())
{
    //Build the message data
    MyMessageContent content = new MyMessageContent
    {
        myName = "TheUncas",
        myAge = 30
    };

    using (Message myMessage = Message.Create(MESSAGE_TAG, content))
    {
        //Send a message to a client
        ClientToSendMessage.SendMessage(myMessage, SendMode.Reliable);
    }
}

We just need to create the object, fill properties with some data and then pass the object to the message.

Receiving message with serializable

using (DarkRiftReader messageReader = message.GetReader())
{
    //...
    MyMessageContent content = reader.ReadSerializable<MyMessageContent>();
    //...
}

No way, reading message like that is more elegant and maintenable. You can fin more information about DarkRift2 messages here

What’s next ?

In the next article, we will write the spawn message to all connected clients and read it in the client.

Stay informed by all my article by following me on twitter here