Message Function

The majority of logic of simulation is written inside message function. This function must return the payload to be sent to the server.

Message function is where the majority of your logic will be written. It is passed the initialized state object from the setup function. The message function must return the payload which is supposed to be sent to the backend. Let's have a look at some of the use cases you will encounter in writing message function.

Getting current iteration

When the template is running, it might be required to do some actions based on a specific iteration, e.g. for every 10th call, you would like to send a special message. Simply call index() function to find out which iteration you are into. The iteration starts from 0 and continues upto the number of iterations you have specified in simulate tab.

{
if (index() == 0 ) {
return "This is the first iteration"
}
if (index() % 10 == 0 ) {
return "Special Message at every 10th iteration"
}
if (index() % 2 == 0 ) {
return "Special Message at every even iteration"
}
var randomIteration = Math.floor(Math.random()*100);
if (index() == random ) {
return "This is a random message triggered one time in 100 iteration"
}
return "Normal message";
}

Knowing your client ID

If you are simulating more than 1 clients, you could find the current client ID in the template by accessing the function client(). This returns an integer starting from 0 and going upto the maximum number of clients specified. If you have passed a client offset while running simulation, that offset will be added to the client.

{
if (client() === 0 ) {
return "I am the leader with ID 0"
}
return "I am the follower with id "+ client();
}

A combination of client() and index() function could be very powerful to create some complex scenarios. Let's see an example

{
if ( (client() % 3 == 0) and (index() %5 == 0) ) {
return "I am a rogue client"
}
else {
return "I am a good client"
}
}

In the above case, every third client on every 5th iteration will send a rogue message while others will send a good message. The behavior could also be changed dynamically by using glob keys.

Logging

Anywhere in the function you could call console.log() which will be saved in the results and preview. Note that other console functions such as console.error or console.warn are not captured and will not be displayed to the user.

{
console.log("This is a log", state.myvariable);
}

Generating Payload

The device model will eventually generate a payload to be sent to the cloud platform. This could be a string or the message function could also return a binary payload. This is really helpful when dealing with TCP/UDP payload types. E.g. lets create a raw payload and send it as a Buffer.

{
state.content = [0x62, 0x75, 0x66, 0x66, 0x65, 0x72];
state.content.push(0);
return Buffer.from(state.content);
}

This will result in the following hex content being sent to the server

62 75 66 66 65 72 00

Skipping message sending

It is important that at the end of processing, function body must return a value to be sent to the cloud platform. The return value could either be a string or a Node.js binary Buffer object, depending upon what values are accepted by your cloud platform provider. If you would like to skip sending anything for that particular iteration, simply call skip() helper function. This will cause the current payload to be skipped being sent to the cloud platform.

{
if (index() == 2){
skip(); // This will cause payload sending to be skipped
}
return JSON.stringify(state, null, 2);
}

When a skip call is encountered by our back-end simulation engine, the message sending part will be skipped for the client for that iteration, even though payload has been successfully generated. This help in simplifying the code structure for the end user. Note that skip() effect will be automatically cleared for the next iteration for the client. However, the iteration result will not counted as a failure if the payload is skipped. If you want to explicitly mark the current client iteration as a failure, you could use assert(false) function.