Java OOCSI Client

OOCSI is a in essence a client-server message-bus infrastructure. With the server running, a client can connect an exchange messages with other clients via the server. While there is a dedicated Processing plug-in for OOCSI, a client interface for direct use in a Java or JVM application is provided as well (see below).

Embedding the client

The Java OOCSI client can be embedded in any kind of Java program (or anything running on a JVM). The only dependency is the oocsi.jar (20kB) library. Put this library into the classpath and follow the steps below.

Connecting to the OOCSI network

As the first step, create an OOCSI client by providing a unique name to the OOCSIClient constructor:

// Tip: include '####' in the client name to let the server assign random digits and avoid collisions
OOCSIClient sender = new OOCSIClient("sender_####");

Connect to a running OOCSI server on the same machine and the default port 4444.

sender.connect("localhost", 4444);

Connect to a running OOCSI server on a different machine at 123.123.123.123 and a custom port 4545.

sender.connect("123.123.123.123", 4545);

Sending messages

Use the OOCSIMessage class to create and send messages on the OOCSI network:

new OOCSIMessage(sender, "mychannel").data("mykey", "myvalue").send();

In this example a message is created to be sent with the OOCSIClient sender and destined for the channel mychannel. A key-value pair of data "mykey": "myvalue" is added to the message by calling the data() method and finally, the message is sent to the OOCSI network with send().

Receiving messages and handling events

For receiving messages, another OOCSI client is initialized and started:

OOCSIClient recipient = new OOCSIClient("myrecipient");
recipient.connect("localhost", 4444);

Again, take care that the handle is unique and that the client connects to the right server.

This new client, recipient, subscribes for the channel mychannel and provides an EventHandler instance. This newly instantiated object asynchronously receives all events sent on the respective channel and will call the internal method receive. In this example, the event’s timestamp will be printed in the console output.

recipient.subscribe("mychannel", new EventHandler() {
	public void receive(OOCSIEvent event) {
		System.out.println(event.getTimestamp());
	}
});

Getting data from events

An OOCSIEvent has built-in infrastructure-level data fields such as sender, timestamp, and channel. In addition, the recipient field is provided for some client implementations. Each of these fields can be accessed with a dedicated getter method:

OOCSIEvent event = ...

// sender and receiver
String sender = event.getSender();
String channel = event.getChannel();
String recipient = event.getRecipient();

// time
Date timestamp = event.getTimestamp();
long unixTime = event.getTime();
```

Apart from that, OOCSIEvents have a data payload that is freely definable and realized as a key-value store (`Map<String, Object>`). Such key-value pairs can be accessed with helper methods that convert the data type of the value accordingly: 

```java	 
OOCSIEvent event = ...
String stringValue = event.getString("mykey");
Object objectValue = event.getObject("mykey");
```

Events do not guarantee that specific keys and values are contained. For these cases, default values can be used in the retrieval of event data. These default values (with the correct data type) are added to the retrieval call as a second parameter, and they will be assigned if (1) the key could not be found, or (2) if the value could not be converted to the specified data type.

```java
// retrieval with an additional default value
OOCSIEvent event = ...
String stringValue = event.getString("mykey", "default");
long longValue = event.getLong("mykey", 0L);
int intValue = event.getInt("mykey", 0);
boolean booleanValue = event.getBoolean("mykey", false);
```

As an alternative to using default values, one can also check whether the key is contained in the event:

````java
OOCSIEvent event = ...
if(event.has("mykey")) {
	// retrieve value
}

Finally, events can provide a list of contained keys, which can be used to dump all contained data or to systematically retrieve all data.

OOCSIEvent event = ...
String[] keys = event.keys();

OOCSI Variables (State Synchronization)

The Java client supports typed OOCSI variables (OOCSIInt, OOCSIFloat, OOCSIBoolean, OOCSIString, OOCSIDouble) that automatically synchronize across the network whenever their values change:

// Synchronize an integer variable on channel "dashboard"
OOCSIInt counter = new OOCSIInt(client, "dashboard", "counter", 0);

// Get current value
int count = counter.get();

// Set new value (automatically broadcasts update to the channel)
counter.set(count + 1);

Call-Response (RPC Services)

You can register synchronous responders or execute calls to remote services:

// Register a responder for 'weather_service'
new Responder(client, "weather_service") {
    @Override
    public void respond(OOCSIEvent event, Map<String, Object> response) {
        response.put("temp", 22.0);
        response.put("condition", "Sunny");
    }
};

// Call the service and wait up to 2000ms for a response
OOCSICall call = new OOCSICall(client, "weather_service", 2000);
if (call.hasResponse()) {
    System.out.println("Temp: " + call.getFirstResponse().get("temp"));
}

Full example

The full example given below registers two clients, of which one subscribes for message on the channel mychannel and the other will send a single message on this channel. The subscribing client receives the message and prints out the value associated with the key mykey and the timestamp of the event on the console.

OOCSIClient recipient = new OOCSIClient("myrecipient");
recipient.connect("localhost", 4444);
recipient.subscribe("mychannel", new EventHandler() {
	public void receive(OOCSIEvent event) {
		System.out.println(event.getString("mykey") + " >> " + event.getTimestamp());
	}
});

OOCSIClient sender = new OOCSIClient("sender");
sender.connect("localhost", 4444);
new OOCSIMessage(sender, "mychannel").data("mykey", "myvalue").send();

Copyright © 2013-2026 Mathias Funk.

This site uses Just the Docs, a documentation theme for Jekyll.