-
Notifications
You must be signed in to change notification settings - Fork 6
WebSocket communication
The Nano WebSocket API provides real-time access to network events and node functions, allowing your application to receive new information as soon as the node sees or processes the data.
For further information and guidance, visit the Nano documentation website at docs.nano.org.
In order to utilise the WebSockets functionality, you will need to configure and enable them in the settings. These can be found in the config-node.toml
configuration file:
-
node.websocket/enable
must be set totrue
-
node.websocket/address
should be set to::1
in most instances, unless you need to bind the socket to a different interface -
node.websocket/port
is the port the websocket should listen on — by default, this value is 7078
The NanoWebSocketClient
class is the primary class used to configure and connect to the node's WebSocket interface. The constructor argument takes the address and port of the websocket endpoint, or will default to localhost:7078
if using the parameter-less variant.
In order to use the WebSocket library, it is recommended that you first specify a WsObserver
object to monitor the status of the WebSocket. This can be accomplished through the setObserver(WsObserver)
method within the NanoWebSocketClient
class, and will allow you to be notified of when the websocket is opened and closed, as well as dealing with uncaught exceptions which may occur.
You can now initiate the Websocket connection through the use of the connect()
method. This will attempt to connect to the node's WebSocket, or return false if the connection could not be established.
Once the above is done, a listener should be registered for each topic you want to listen to. To do this, call any of the relevant topicXXX()
methods returned by the call to .getTopics()
, then call the .registerListener(TopicListener)
method to register your listener. For example: ws.getTopics().topicConfirmedBlocks().registerListener(myListener);
.
Finally, you will need to subscribe to any of the topics through the subscribe()
method. Some topics may support additional arguments and filters which you can pass through this method (check the table below), and others may also provide an update function for modifying existing filters. Calling the subscribe()
methods will process them asynchronously, while the subscribeBlocking()
variants will block and wait for an acknowledgement response from the server before continuing. The same concept applies to the update
and unsubscribe
methods.
Topic | Method | Message class | Sub args | Update args |
---|---|---|---|---|
confirmation |
topicConfirmedBlocks() | TopicMessageConfirmation | ✔ | ✔ |
active_difficulty |
topicActiveDifficulty() | TopicMessageActiveDifficulty | ❌ | ❌ |
bootstrap |
topicBootstrap() | TopicMessageBootstrap | ❌ | ❌ |
stopped_election |
topicStoppedElection() | TopicMessageStoppedElection | ❌ | ❌ |
telemetry |
topicTelemetry() | TopicMessageTelemetry | ❌ | ❌ |
new_unconfirmed_block |
topicUnconfirmedBlocks() | Block | ❌ | ❌ |
vote |
topicVote() | TopicMessageVote | ✔ | ❌ |
work |
topicWork() | TopicMessageWork | ❌ | ❌ |
In the example below, we will listen for newly confirmed blocks which belong to a specific set of accounts (using a filter), and print the block and election information to the console.
Main application code:
// Create a WebSocket client, with an endpoint address of localhost:7078 (the default address)
NanoWebSocketClient ws = new NanoWebSocketClient();
// Register a WebSocket observer (not necessary, but recommended)
ws.setObserver(new SampleWsObserver());
// Attempt to connect to the WebSocket
if (!ws.connect()) {
// Connection failed
System.err.println("Could not connect to WebSocket!");
return;
}
// Register a topic listener (in this case, using a lambda function)
ws.getTopics().topicConfirmedBlocks().registerListener((message, context) -> {
System.out.println(message.getHash()); // Print the block hash
System.out.println(" Amount: " + message.getAmount()); // Print the transaction amount
System.out.println(" Conf: " + message.getConfirmationType()); // Print the confirmation type
System.out.println(" Voted by: " + message.getElectionInfo().getVoters()); // Print vote count
});
// Subscribe to the confirmed blocks topic, and specify filters and configuration
boolean subscribed = ws.getTopics().topicConfirmedBlocks().subscribeBlocking(
new TopicConfirmation.SubArgs()
.includeElectionInfo() // Include election info in the messages
.filterAccounts( // Account filter (only include blocks belonging to these accounts)
"nano_34qjpc8t1u6wnb584pc4iwsukwa8jhrobpx4oea5gbaitnqafm6qsgoacpiz",
"nano_1b9rcj4o7r37acf8hdm5iq9qn5tx8nfwqr51d6yxtknona1ybir5kgjpyoh9")
);
// Print subscription status
System.out.println(subscribed ? "Subscribed to topic!" : "Could not subscribe to topic!");
And the WebSocket observer we are using:
static class SampleWsObserver implements WsObserver {
@Override
public void onOpen(int httpStatus) {
System.out.println("WebSocket connected!");
}
@Override
public void onClose(int code, String reason, boolean remote) {
System.out.println("WebSocket disconnected!");
}
@Override
public void onSocketError(Exception ex) {
ex.printStackTrace();
}
}
Example console output:
WebSocket connected!
Subscribed to topic!
478DC8ECA3F0D3B4CEE42A5971F1D963F36FEE8E5DBF326E7A181864041F66D4
Amount: 0.000547 Nano
Conf: ACTIVE_QUORUM
Voted by: 74
C2BA24A043EAE962FD750F784FF5D8703FC09B703E531777F269EF7F99B04D29
Amount: 0.000547 Nano
Conf: ACTIVE_QUORUM
Voted by: 65