Jump to content
Angus Robertson

Designing a Websocket API

Recommended Posts

I offer clients a REST API service to look-up telecommunication information, using the ICS web application server and MS SQL server. 

 

It works well, for low volumes of queries, but most users start a new SSL/TLS session for each query, which becomes a limiting factor with performance. 

 

So I want to offer a Websocket API as well, so one SSL/TLS session stays open, with just simple request/response packets sent. 

 

But how to adapt the REST HTTP request/response to Websocket?  My queries are simple URL parameters, ie codelookapi.htm?numhistory=118118.

 

Should the Websocket message just be the arguments or include the full or partial URL as well?  Or something else, like a command? 

 

Should the initial Websocket request allow arguments, or just open the connection? 

 

Should be Websocket response message be just a JSON block, or include a wrapper of some sort, like the HTTP response header? 

 

Has anyone done a similar design?  I just want to make it easy for clients using standard Websocket client libraries to integrate the new API.

 

Angus

 

Share this post


Link to post

Hi, 

 

While having the full HTTP request and including the HTTP header for the response is best for switching between the connections type, you can do this by striping all of that and changing the request to pure and simple JSON ,(like a JSON object with a field called apicmd and its value is codelookup with a second field numhistory ), here i want to point an important thing is to put a separator for this simple API request like one CRLF or double CRLF to indicate the end of the request, same can be with the response, also want to point that is very important and will pay in future to put the request parameters in the response for each request, this will prevent the confusion and remove all the tracking for request-response pairs, web socket allows you to send many request from the client and the server can response when it is ready and doesn't require serialization, some queries might/could be executed on the server different threads but the response always known for the client.

2 hours ago, Angus Robertson said:

Should the initial Websocket request allow arguments, or just open the connection? 

Not really important, but i prefer to send one request establishing the timeout and the frequency of the ping to be expected, this way, server have some knowledge on how to handle stale connections, remember that web sockets connection will stale without ping, so the best approach here is make sure the client to ping periodically, and the server will close the connection if this period violated, the ping form the client could be 3 minutes and the server will close the connection on 5-6 minutes if nothing being received in that period(ping or not).

  • Like 1

Share this post


Link to post

Thanks for the comment, yes record ending is important, since this API has simple URL encoded arguments a single CRLF will be fine.  In fact, allowing multiple requests in a single message is probably what is really needed.  This client tends to do 10,000 odd requests in a single block during the night, takes about 25 minutes at the moment, single server thread, with a new session each time, eight per second. Will need to decide how many requests can be queued, in case they decide to try 1 million. 

 

The responses do include the main argument, ie {"success":true,"reccount":16,"records":[{"number":"118118","number_from":"2010-03-10", etc. I should add the API type to the outer wrapper.  Then send them back one message at a time.  

 

Either the server or client can ping/pong to keep the connection open, I was planning on the server doing that to avoid complexity at the client, they simply close the connection when the batch is over.

 

 Angus

 

  • Like 1

Share this post


Link to post
Posted (edited)

If most of all you want to prevent repeated handshakes, that's just a matter of using persistent HTTP connections (keep-alive)...? Another good option could be a RESTful batch API, which in the end helps you optimize more (e.g. database queries).

 

Should you go for the WebSocket idea, the closest thing to a standard is JSON-RPC 2.0, I'd say. There are ready clients available for several languages. Depending on the amount of methods you'll support, consider providing a machine readable spec using OpenRPC.

Edited by Thijs van Dien

Share this post


Link to post
Quote

 persistent HTTP connections

No idea why this client is not using keep-alive, perhaps their REST library does not support it? 

 

The basic Websocket API is working, and the client can access another Websocket interface on the server so seem to know their stuff, now just need to design the pipelining, so that queued queries get returned to the correct client.

 

I'll look at JSON-RPC 2.0 for next time.  

 

Angus

 

Share this post


Link to post

The new Websocket API is live, when using streamlined requests, it handles about 100 SQL queries a minute from a single thread, although slower if the requests are sent sequentially waiting for a reply. 

 

Supporting JSON-RPC 2.0 on the server should not be hard, but does need POST support, I'll look at adding it to the ICS web server database sample.  Client is a little harder since JSON-RPC 2.0 JSON-RPC uses a sequential ID to keep track of requests.

 

Angus

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×