openstatic.org

openstatic.org

Routeput Websocket and JSON Message Server

Introduction

I found myself constantly needing a Websocket server that handles JSON packets and distributes them to other clients, or specific clients. Solutions like pusher and pubnub just seemed like overkill, and i'm not a fan of relying on too many outside services. This project is my attempt at making a simple, lightweight and fast Websocket Server for my many-to-one, and many-to-many messaging needs.

Every message contains its an object field called "__routeput" which provides all the routing information. This makes it easy for objects to traverse other protocols and services without losing the message's source, destination, and channel.

Another way to think of the message is like a piece of mail, "__routeput" is the envelope with the return address and destination.

What about the name?

Routeput got it's name from the idea of PUTting the ROUTE information directly into the JSON object.

Under the hood

  1. This server was written in java using GraalVM and native-image.
  2. Jetty is used for all websocket management and api interfaces
  3. org.json is used for JSON object management

How to use

After installing Routeput the server will launch by default on port 6144. by default all websockets should be formed to http://127.0.0.1:6144/channel/channelName/ (replacing channelName with your custom channel)

Once you connect you will receive a packet from the server that looks like this:

{
  "__routeput": {
      "srcId": "VWbFlzwFVagMUldXGhZFABlH",
      "channel": "channelName",
      "type": "connectionId",
      "channelProperties": {},
      "connectionId": "VWbFlzwFVagMUldXGhZFABlH",
      "properties": {}
    }
}

this is a "connectionId" packet (denoted by the "type" field inside "__routeput") and will be received by any client connecting to the Websocket. Whenever the "type" field is present in a message chances are this is a special message. In all client libraries these packets are usually absorbed and managed internally.

The important thing to note is your connectionId which is "VWbFlzwFVagMUldXGhZFABlH" in the provided example.

Multiple Connections

OK! So now lets form a second connection as well to the same endpoint. As soon as this happens, the second connection receives the same welcome packet, and another packet.

{
  "__routeput": {
      "srcId":"VWbFlzwFVagMUldXGhZFABlH",
      "channel":"channelName",
      "type":"ConnectionStatus",
      "connected":true,
      "properties":{}
    }
}

"ConnectionStatus" messages are another type of message generated by the server. This packet lets you know whenever someone joins or exits the channel. When a member joins they will receive a packet for each other member already joined, and the other members will receive a packet for the user that just joined. If you go back to connection 1 you will see they received a message that connection 2 joined. This eliminates the need to implement any of your own connection tracking logic. "srcId" will always represent the "connectionId" of the client joining or leaving.

Now that we have two connections lets try sending some of our own messages....

From the first connection lets sent the message:

{
  "hello": "world"
}

The Second Connection Receives:

{
  "hello": "world",
  "__routeput": {
    "srcId": "VWbFlzwFVagMUldXGhZFABlH",
    "channel": "ANYTHING"
  }
}

As you can see an additional field called "__routeput" was added to the object. The server always knows your connectionId and channel, so there is no need to add this information to packets sent directly to the server. Also note the lack of a "type" field, one of the main ways to tell your messages from ones auto-generated by the server is the presence of the "type" field.

Targeted Messages

In order to send a message directly to another client (instead of the entire channel) you must know it's connectionId which can be obtained from "ConnectionStatus" messages

Example Targeted Message:

{
  "__routeput": {
    "dstId": "PXpoTFSfxnAqzjoEyyMrLWuD"
  }
  "hello": "world"
}

Implementation with javascript

Routeput is designed to work with a javascript powered front-end, below is a simple implementation example. Please note that all transmitted messages must be serialized json. routeput.js is provided in the root of your routput server. (ex: http://127.0.0.1:6144/routeput.js) this library provides the RouteputConnection class

var routeput = new RouteputConnection("myChannel");

routeput.onblob = function(name, blob) {
    console.log("Recieved File: " + name);
};

routeput.onmessage = function (jsonObject) {
    var routeputMeta = jsonObject.__routeput;
    var channel = routeputMeta.channel;
	console.log("Received Message on " + channel);
};

routeput.onconnect = function () {
	routeput.transmit({"hello": "world"});
};

Projects using Routeput

  • Midi Chat
    • Webchat service with MIDI message sharing, think of it as a chatroom with MIDI
  • Midi Tools
    • Midi swiss army knife

Github Project


Download

Latest Build: July 28 2020 03:42:56 PM EDT


routeput-1.0-SNAPSHOT-native.deb
(Ubuntu/Debian x64)

routeput-1.0-SNAPSHOT.deb
(Ubuntu/Debian/Raspbian)