Skip to content
Thijs Elenbaas edited this page Jan 6, 2019 · 5 revisions

SimplMessage is a library that facilitates sending on any type of objects. It uses MessagePack for high performance serialization to binary format and uses SimplSockets to send the binary data. It also adds a descriptor to each package so that the receiving side knows how to deserialize the data to the correct class.

Serialization

SimplMessage uses the msgpack-cli implementation of MessagePack, so you can use, e.g. the msgpack-cli attributes:

https://github.com/msgpack/msgpack-cli/wiki/Serialization-attributes

var objectToSend  = new ClassA() {
	// If the target type has any members which are marked with
        // MessagePackMemberAttribute, then only those members will 
        // be serialized in opt-in manner.
        [MessagePackMember(0)]
        VarInt = 2,
        [MessagePackIgnore]
    	VarDouble = 2.5
    };

Sending an object with a descriptor

Sending objects is done by passing an object and a descriptor to the send function:

// Create an object to send
var objectToSend  = new ClassA() { VarInt = 2, VarDouble = 2.5 };

// Send it
client.Send("ObjectOfTypeClassA",objectToSend);

Sending an object without a descriptor

You may ask, why we need to use a descriptor? Can we not just use the class name? Indeed we can, and this precisely what happens if you use the send command without descriptor:

client.Send(objectToSend);

or, if you want to make the type explicit:

client.Send<ClassA>(objectToSend);

SimplMessage now uses the class name as descriptor. Note that this is not the fully qualified type name, partly because of overhead. This means that it is possible to have name collisions, if you the same class name in different namespaces or encapsulating classes.

Sending from server

Like SimpleSockets, Sending an object from the server works similar to sending from the client but again with the difference that you need add the client you would like to send to:

// Wait until a new client has connected
var connectedClient = server.WaitForNewClient();

// Create an object to send
var objectToSend  = new ClassA() { VarInt = 2, VarDouble = 2.5 };
// Send it to the new client
server.Send(objectToSend, connectedClient);

Sending to all clients can be done using broadcast.

server.Broadcast(objectToSend);

Or, if you want you can do this manually

foreach (var connectedClient in server.ConnectedClients)
{
    server.Send(objectToSend, connectedClient);
}

Replying to a message

It is also possible for a client to send a command and wait for a reply.

var receivedObject = client.SendReceive<ClassA, ClassA>(objectToSend);

in conjunction the server has a reply function to answer

server.AddCallBack<ClassA>((receivedMessage) =>
{
    var receivedObject = receivedMessage.GetContent<ClassA>();
    
    // Reply to the message with the same content (echo)
    server.Reply(receivedObject, receivedMessage);
    Console.WriteLine($"Server replied to message");
});

Example

These features are shown in more detail in this example and this example