JSON Formats

Information is exchanged between a Manager, a Client and a Service using JSON as the data format. The information is serialized to bytes and terminated with "\r\n" (a carriage return and a line feed).

A Client or a Service can be written in any programming language, but the JSON data format must adhere to the specific requirements specified below. The Client and Service must also check for the "\r\n" (or just the "\n") byte sequence in each network packet that it receives in order to ensure that all bytes have been received or to check if multiple requests/responses are contained within the same network packet.

Client Format

A Client must send a request with the following JSON representation:

{
  "args": array of objects (arguments to be passed to the method of the Manager or Service)
  "attribute": string (the name of a method or variable to access from the Manager or Service)
  "error": false
  "kwargs": name-value pairs (keyword arguments to be passed to the method of the Manager or Service)
  "service": string (the name of the Service, or "Manager" if the request is for the Manager)
  "uid": string (a unique identifier of the request)
}

The unique identifier (uid) is only used by the Client. The Manager simply forwards the unique identifier to the Service which just includes the unique identifier in its reply. Therefore, the value can be anything that you want it to be (provided that it does not contain the "\r\n" sequence and it cannot be equal to "notification" since this is a reserved identifier). The unique identifier is useful when keeping track of which reply corresponds with which request when executing asynchronous requests.

A Client will also have to send a reply to a Manager during the connection procedure (i.e., when sending the identity of the Client and possibly providing a username and/or password if requested by the Manager).

To send a reply to the Manager use the following JSON representation

{
  "error": false (can be omitted)
  "requester": string (can be omitted)
  "result": object (the reply from the Client)
  "uid": string (can be omitted)
}

You only need to include the “result” name-value pair in the reply. The “error”, “requester” and “uid” name-value pairs can be omitted, or anything you want, since they are not used by the Manager to process the reply from a Client. However, including these additional name-value pairs provides symmetry with the way a Service sends a reply to a Manager when there is no error.

A Client will receive a reply that is in 1 of 3 JSON representations.

Before a Client successfully connects to the Manager the Manager will request information about the connecting device (such as the identity of the device and it may check the authorization details of the connecting device).

If the bytes received represent a request from the Network Manager then the JSON object will be:

{
  "args": array of objects (arguments to be passed to the method of the Client)
  "attribute": string (the name of a method to call from the Client)
  "error": false
  "kwargs": name-value pairs (keyword arguments to be passed to the method of the Client)
  "requester": string (the address of the Network Manager)
  "uid": string (an empty string)
}

If the bytes received represent a reply from a Service then the JSON object will be:

{
  "error": false
  "requester": string (the address of the Client that made the request)
  "result": object (the reply from the Service)
  "uid": string (the unique identifier of the request)
}

If the bytes received represent an error then the JSON object will be:

{
  "error": true
  "message": string (a short description of the error)
  "requester": string (the address of the device that made the request)
  "result": null
  "traceback": array of strings (a detailed stack trace of the error)
  "uid": string
}

A Service can also emit a notification to all Client's that are Linked with the Service. Each Client will receive a notification that has the following JSON representation

{
  "error": false
  "result": array (a 2-element list of [args, kwargs], e.g., [[1, 2, 3], {"x": 4, "y": 5}])
  "service": string (the name of the Service that emitted the notification)
  "uid": "notification"
}

Service Format

A Service will receive data in 1 of 2 JSON representations.

If the bytes received represent an error from the Network Manager then the JSON object will be:

{
  "error": true
  "message": string (a short description of the error)
  "requester": string (the address of the Manager)
  "result": null
  "traceback": array of strings (a detailed stack trace of the error)
  "uid": string (an empty string)
}

If the bytes received represent a request from the Manager or a Client then the JSON object will be:

{
  "args": array of objects (arguments to be passed to the method of the Service )
  "attribute": string (the name of a method or variable to access from the Service)
  "error": false
  "kwargs": name-value pairs (keyword arguments to be passed to the method of the Service)
  "requester": string (the address of the device that made the request)
  "uid": string (the unique identifier of the request)
}

A Service will send a response in 1 of 2 JSON representations.

If the Service raised an exception then the JSON object will be:

{
  "error": true
  "message": string (a short description of the error)
  "requester": string (the address of the device that made the request)
  "result": null
  "traceback": array of strings (a detailed stack trace of the error)
  "uid": string (the unique identifier of the request)
}

If the Service successfully executed the request then the JSON object will be:

{
  "error": false
  "requester": string (the address of the device that made the request)
  "result": object (the reply from the Service)
  "uid": string (the unique identifier of the request)
}

A Service can also emit a notification to all Client's that are Linked with the Service. A Service must emit a notification that has the following JSON representation

{
  "error": false
  "result": array (a 2-element list of [args, kwargs], e.g., [[1, 2, 3], {"x": 4, "y": 5}])
  "service": string (the name of the Service that emitted the notification)
  "uid": "notification"
}