Connecting to FIMK websockets

In this post I’d like to explain how to connect to the FIMK Websocket server from client side javascript. We’ll be creating a small widget consisting of HTML and Javascript only that could be shown on a website. The widget will be displaying the current blockheight of the FIMK network and will update in real time when a new block arrives.

We’ll be introducing a helper library for working with the websocket server, this library is kept simple intentionally and should show you how to create a similar helper library for your own language.

sockets

No! Not those sockets

First things first

Before we do anything lets have a look at Javascript Websockets. As can be seen here websocket support is available in practically every browser out there. As always Firefox and Chrome are the frontrunners when it comes to supporting new standards, practically all versions of these browsers support websockets.

When we get to that other widely used browser, Internet Explorer, you’ll find websockets are supported from Internet Explorer 10 upwards. IE 8 (2.9% global usage) and IE 9 (1.82% global usage) unfortunately don’t have websocket support.

Because Websockets are a W3C standard you can expect the same API to work across all supporting browsers and you’ll see that using Websockets from Javascript is actually pretty easy.

About the live samples

Throughout my posts you will find several runnable code examples (jsfiddles). Each jsfiddle has a tab bar at the top with a Javascript, HTML and Result tab. The Javascript in the Javascript tab and the HTML in the HTML tab can be edited by you. Clicking the Result tab will actually let you run the code straight in your browser.

Getting started

Before you can use your websocket from Javascript you need to declare a WebSocket instance. Unlike the XMLHttpRequest object (thats the part you use to do Ajax requests) the WebSocket will connect to the server immediately on creation. The sample below shows you three key concepts of WebSockets.

  1. Creating the WebSocket
  2. Registering WebSocket listeners
  3. Closing the WebSocket

To run the sample in your browser click the Result tab.

Although it doesn’t look like much what you see in the jsfiddle above is a new WebSocket instance being created and connecting to the FIMK Websocket server at wss://fim1.mofowallet.org:7986/ws/. Normally websockets connect over the ws:// protocol, but since Krypto Fin ri association servers are all equipped with SSL certificates we must use the secure version (in case you did not figure it out, as http has it’s secure brother https so has the ws protocol it’s secure sister wss).

Introducing FIMKSocket.js

To make working with the WebSocket server easier we advise to use a wrapper that wraps the low-level raw websocket specifics and exposes a clean set of access points. The FIMKSocket.js reference wrapper is written in Javascript but the same principles will apply to all other languages. Contact me if you need help creating a wrapper for your language, we’ll be happy to co-create and host the source code for that wrapper on our github page.

I made the FIMKSocket.js library for this blog post and will use it to show how easy it is to create a WebSocket wrapper. In MofoWallet we also have a WebSocket wrapper which is called MofoSocket but since that was made to work especially in an Angular environment I figured an Angular-less version would work better for most people.

So what does the FIMKSocket.js library has to offer?

  1. Create new socket and be notified when it’s open
  2. Call RPC methods on the server and receive the result in a callback
  3. Register and unregister for server side events

The following jsfiddle shows how to declare an instance of FIMKSocket and connect it to a FIMK WebSocket server. When the socket is open a callback is called.

Calling RPC methods

The WebSocket server not only allows you to listen to server side events, it also supports a rich (and growing) set of RPC calls. RPC calls (aka Remote Procedure Call) are similar to the standard HTTP API but specialized for use in MofoWallet.

The FIMKSocket.js library was made aware of all available RPC end points which allows you to call RPC calls as if they are methods on the FIMKSocket object.

If you for instance want to get the current block height you could call the getBlockchainState RPC call. As with every RPC the call will look something like this.

socket.getBlockchainState(null, function (data) {
  window.alert("Height is "+data.height);
});

As you can see the name of the RPC call is actually the name of the method you call on the WebSocket server, behind the scenes the FIMKSocket library will forward this call for you.

Run the following jsfiddle to try it for yourself (click the result tab to run the code).

The getBlockchainState call does not expect any parameters thats why we pass null as the first argument, if you need to pass arguments to an RPC call you can do that by passing an object as the first parameter.

For example if we want to know the balance of account FIM-5PGB-BFNZ-KCSF-9XJWB we would use the GetAccount RPC call. The GetAccount call expects an account argument which means on the server side it expects the following raw JSON string.

{ "account": "FIM-5PGB-BFNZ-KCSF-9XJWB" }

Since Javascript has built in JSON support we can get away with passing an object which will automatically be transformed to JSON, if you use another language this kind of transformation is something that your wrapper should be taking care of.

Try running that yourself by selecting the Result tab.

Access HTTP API over Websockets

The old API server has been turned off in the newest FIMK server and mofowallet releases. This however does not mean you don’t have access to those API functions. Because of the HTTP API to WebSocket bridge available in the FIMK WebSocket server users of the WebSocket server still have access to all the older API calls.

As mentioned earlier one thing NXT is truly in a league of it’s own is the number of available API calls. To get a good view of the API calls available please have a look at the NXT API documentation, FIMK supports all of those NXT API calls.

To show how to call the old API over WebSockets we’ll create a rather pointless example of calling the getState HTTP API function.

Key to accessing the HTTP API over Websockets is the callAPIFunction RPC call. Since code speaks louder than words lets look an example.

Lets call the getState HTTP API function:

The GetState function does not require any parameters apart from the requestType but most other functions do require additional parameters. Luckily adding other parameters is pretty easy, all that is required is to add the named parameters to the object that already contains the requestType parameter.

Lets  look at another sample, lets see who forged the last 10 blocks:

Easy right? Just add the remaining parameters as properties to the object containing the requestType property.

Listening for server events

Calling RPC methods over a websocket connection is nice of course but it’s not what sets websockets apart. It’s the two way communication that makes WebSockets unique, it’s the ability to one time register a listener for some event and then be notified the moment that event occurs on the server side.

Lets begin with an example. We’ll be registering a listener that’s notified of each new block that is forged, what we then do is update a piece of UI so it displays the block height.

Cool right? Well there are a lot more events you can listen for lets go over them in short.

  • blockPushed
    Forwards event BLOCK_PUSHED, has limited data available. Response  consists of height and timestamp only.
  • blockPushedNew
    Forwards event BLOCK_PUSHED for blocks less than 1 day old. You would prefer to use this topic since the blockPushed event is also sent for each block while downloading a complete blockchain and while scanning the blockchain.
  • blockPushed-FIM-5PGB-BFNZ-KCSF-9XJWB
    Forwards event BLOCK_PUSHED for blocks generated by the appended account.
  • blockPopped
    Forwards event BLOCK_POPPED, has limited data available. Response  consists of height and timestamp only.
  • blockPoppedNew
    Forwards event BLOCK_POPPED for blocks less than 1 day old.
  • blockPopped-FIM-5PGB-BFNZ-KCSF-9XJWB
    Forwards event BLOCK_POPPED for blocks generated by the appended account.
  • addedUnconfirmedTransactions
    Forwards event ADDED_UNCONFIRMED_TRANSACTIONS. This allows you to listen to transactions as they arrive on the network in real time.
  • addedUnconfirmedTransactions-FIM-5PGB-BFNZ-KCSF-9XJWB
    Forwards event ADDED_UNCONFIRMED_TRANSACTIONS but only for transactions that have the added account as recipient or sender.
  • removedUnconfirmedTransactions
    Forwards event REMOVED_UNCONFIRMED_TRANSACTIONS. Internally transactions always go through the two states UNCONFIRMED and CONFIRMED. Before a transaction is moved from status UNCONFIRMED to CONFIRMED expect it first be removed from the UNCONFIRMED pool. In normal daily usage it is to be expected that transactions can go in and out of UNCONFIRMED status several times.
  • removedUnconfirmedTransactions-FIM-5PGB-BFNZ-KCSF-9XJWB
    Same as removedUnconfirmedTransactions but only for transactions where FIM-5PGB-BFNZ-KCSF-9XJWB is either the sender or recipient.
  • addedTrades
    Collects all trades in between two blocks and which are pushed less than 1 day ago. Since trades happen only when the block is created we can only notify you each block. To get around this limitation Mofowallet listens for unconfirmed buy/sell order transactions and cancellations of buy/sell orders. With this information we are still able to display instant feedback in the Asset Exchange.
  • addedTrades-FIM-5PGB-BFNZ-KCSF-9XJWB
    Same as addedTrades but without the rate limiter and only reporting trades where the seller or buyer is the appended account. The rate limiter is what causes to only report trades that are less than a day old.
  • addedTrades*13664938383416975974
    Same as addedTrades-FIM-5PGB-BFNZ-KCSF-9XJWB but instead of limited to buyer or seller these trades are limited to an asset id.
  • removedUnconfirmedTransactions-FIM-5PGB-BFNZ-KCSF-9XJWB
    Same as removedUnconfirmedTransactions but only for transactions where FIM-5PGB-BFNZ-KCSF-9XJWB is either the sender or recipient.
  • addedTrades
    Collects all trades in between two blocks and which are pushed less than 1 day ago. Since trades happen only when the block is created we can only notify you each block. To get around this limitation Mofowallet listens for unconfirmed buy/sell order transactions and cancellations of buy/sell orders. With this information we are still able to display instant feedback in the Asset Exchange.
  • addedTrades-FIM-5PGB-BFNZ-KCSF-9XJWB
    Same as addedTrades but without the rate limiter and only reporting trades where the seller or buyer is the appended account. The rate limiter is what causes to only report trades that are less than a day old.
  • addedTrades*13664938383416975974
    Same as addedTrades-FIM-5PGB-BFNZ-KCSF-9XJWB but instead of limited to buyer or seller these trades are limited to an asset id.

 

And now for our widget

As stated at the start of this article I was going to show you how with the help of FIMK WebSockets we could make a widget that could be displayed on a website and that showed the current block height and automatically updates on the next block.

To achieve this we will be using one RPC function and will subscribe to receive a single event. Since we need to initialize the widget with the initial height (and lets throw in the date while we are at it) we will be using the GetBlockchainState call to obtain the height and timestamp.

Then to be informed when a new block arrives we’ll register as a listener for the blockPushed event. Finally to notify you about a new block a sound is played.

And there you go, real time blockchain data right in your browser, thank you for reading.

Share Your Thoughts

Leave a Reply