Client - Language Support

Swim developer logo developer.

Overview


As mentioned in the previous section the most straight-forward way of ingesting data and subscribing to data from the Lanes is by using the SWIM-Client. If this is not an option then raw web-socket messages can be used to ingest data into lanes. However, this option is only available for data ingestion. Data subscription from lanes is only supported using the SWIM-Client.

Given a Service defined with a CommandLane, data ingestion to that lane is accomplished using the following steps:

  1. Open a websocket to the URL of the Swim Server.
  2. Send a websocket message to the aforementioned Service and Lane. The websocket payload should conform to the following format: @command(node:"$serviceURI",lane:"$laneURI")$data where $serviceURI is the Service URI, $laneURI is the Lane URI of the CommandLane and $data is the message to be sent.
Since all popular programming languages support websockets natively or via standard libraries, you may use the programming language of your choice.

Consider a Swim application running on localhost:5620 with the following Plane and Service definition. The sections below describe how the different languages can be used to send data to the command lane in a specific PlanetService instance.

Plane

import swim.api.*; class SolarSystem extends AbstractPlane { // e.g. /planet/saturn, /planet/earth @SwimRoute("/planet/:name") final ServiceType<?> planet = serviceClass(PlanetService.class); }
  • HTML
  • recon

Service and Lanes

import recon.*; import swim.api.*; class PlanetService extends AbstractService { @SwimLane("co2") ValueLane<Double> co2 = valueLane() .valueForm(Form.DOUBLE); @SwimLane("co2History") MapLane<Long, Double> history = mapLane() .keyForm(Form.LONG).valueForm(Form.DOUBLE); @SwimLane("addCo2") CommandLane<Double> addCo2 = commandLane().valueForm(Form.DOUBLE) .onCommand(newCo2 -> co2.set(newCo2)); }
  • HTML
  • recon

Websocket Payload


The websocket payload should conform to the following format: @command(node:"$serviceURI",lane:"$laneURI"){$data} where $serviceURI is the Service URI, $laneURI is the Lane URI of the CommandLane and $data is the message to be sent. The $data should be valid Recon.

C#


The code below uses the standard C# websocket library. Here a value of 0.4 is sent to the CommandLane named addCo2 of the "Earth" Service whose URI is /planet/earth.

static ClientWebSocket cws = new ClientWebSocket(); const String SwimHost = "wss://localhost:5620"; await cws.ConnectAsync(new Uri(SwimHost), CancellationToken.None); String command = "@command(node:\"/planet/earth\",lane:\"addCo2\"){0.4}"; await sendCommand(command); static async Task sendCommand(String command) { byte[] commandBytes = System.Text.UTF8Encoding.Default.GetBytes(command); Console.WriteLine("Connected"); await cws.SendAsync(new ArraySegment(commandBytes), WebSocketMessageType.Text, true, CancellationToken.None); Console.WriteLine("Sent command {0}", command); }
  • HTML
  • recon

Golang


The code below uses the standard Golang websocket library. Here a value of 0.4 is sent to the CommandLane named addCo2 of the "Earth" Service whose URI is /planet/earth.

package main import ( "log" "golang.org/x/net/websocket" ) func main() { const swimHost = "wss://localhost:5620" swimSocket, initErr := websocket.Dial(swimHost, "", "http://localhost/") if initErr != nil { log.Fatal(initErr) } const message = "@command(node:\"/planet/earth\",lane:\"addCo2\"){0.4}" sendErr := websocket.Message.Send(swimSocket, message) if sendErr != nil { log.Fatal(sendErr) } }
  • HTML
  • recon

Python


The code below uses the websocket-client library found here, so please run the "pip install websocket-client" before using this code. Here a value of 0.4 is sent to the CommandLane named addCo2 of the "Earth" Service whose URI is /planet/earth.

from websocket import create_connection host = 'wss://localhost:5620' ws = create_connection(host) message = "@command(node:\"/planet/earth\",lane:\"addCo2\"){0.4}" ws.send(message)
  • HTML
  • recon