vrijdag 1 juni 2012

Remobjects via Websockets and in Node.js

After playing with Smart Mobile Studio (SMS) and RemObjects for Javascript, I thought it would be cool to have a HTML5 websocket communication channel (instead of only http). Note: websockets are some kind of "TCP over HTTP", so very efficient and fast for e.g. binary data.
At my current customer we use TROIndyTCPChannel and TROBinMessage internally, because this is the fastest option.

Websockets in Delphi

Because RO does not have websocket support (yet), I tried to make a Proof of Concept (PoC) to see if it is possible. I searched and tried some Delphi implementations, but one was old (Indy9, old websocket spec), otherone had no sourcecode yet (Indy10, no  response on my mail so far), etc. I found one which is based on "synapse", which is also included in RO, namely "bauglir-websocket".
I looked at how RO made their TRO***Server and TRO***Channel and made a simple implementation for websockets: uROWebsocketChannel.pas and uROWebsocketServer.pas. This was almost too easy :).
I tested this with a Delphi RO demo server and client (using the RO wizard) and: tada, it works! :).

RO websocket channel

Next I had to make a websocket channel in "RemObjects for Javascript", and after some copy and paste I added this to the end of the RemObjectsSDK.js file. I made a simple html test file and this one works too!


Okay, what can we do next? Make a websocket server in html? Hmm, websockets (in html) can only make client connections and cannot act as a server...
Maybe I can use it in Node.js? Note: Node.js is a server side javascript implementation, based on the Google V8 Javascript engine.
I found a websocket chat demo in Node.js, so it should be possible... Because it is not easy to debug in Node.js, I tried to make it work in Google Chrome first, by using the "websocket.onmessage" event and by sending a fetched JSON string (using the network debug tab in Chrome) when the html page connects to my  Delphi server. After some hacking I could read the RO message, do the "sum" and send the data back to the client. Sweet!
After some little more hacking I also had it working in Node.js! So both my html page and my Delphi client can connect to the Node.js server. Ain't that cool! :)

Download and test

If you want to test it yourself, you can download the zip file, and do the following:
- start "ROWebSocketsServer.exe"
- start "ROWebSocketsClient.exe" and open "\client\client.html"
- push the sum buttons, both should work

- stop "ROWebSocketsServer.exe"
- start the node.js server via "\node\start RO.node.bat"
- push the sum buttons in the clients (maybe restart them?), both should work too :)

6 opmerkingen:

Jim zei

Very cool! Thanks!

Unknown zei

Delphi on Rails have builtin (opensource) WebSocket support.

laura zei

I have tried Delphi on Rails without luck... now I am using sgcWebSockets works very well for me.

laura zei
Deze reactie is verwijderd door de auteur.
Lenin zei

Hi André,

You said you use TROIndyTCPChannel and TROBinMessage, because this is the fastest option.

We are also using this approach with RemObjects. But, recently, while trying to solve some performance issues we found that WinInetHTTPChannel performs faster than IndyTCP, even when using binary data as TMemDataTable.

Have you ever benchmarked TROIndyTCPChannel against other Channels?

(FYI, we are using Delphi 7 + Indy 9 + RO SDK

Thank you in advance.

André Mussche zei

Hi Lenin,
I only did some profiling with other channels (mail, http, winmessage, pipes, etc) a couple of years ago. But not between the several RO tcp channel (indy, synapse, wininit, etc).

Thanks for the idea, I will take a look at it soon too. But for now, our tcp+bin is performing good enough (D2010, Indy 10, Win7), I only had to force disable the nagle to remove the auto 200ms delay by Windows on small tcp messages :(