For instance, it would be possible to create (or just port them from node.js) client libraries for things like: Memcache, Redis, MySQL, Riak, RabbitMQ or any other server.
While in many situations such usage would be questionable and insecure, there are cases when it could be quite useful:
- using server-side cache from JS
- using pub/sub servers to deliver notifications to browsers. (Redis, RabbitMQ, Apache Kafka, etc)
- making HTTP request to any server bypassing same-origin policies :|
As an experiment I implemented this small library: WebTCP. Here is how it works.
It is impossible to make browser to initiate raw TCP connections to a server, but it is possible to use some proxy (or a “bridge” would be a better name) that will receive connection requests from the browser, create real sockets and then redirect responses back to the browser. So on a client side we will have fake socket objects that will be mapped to real socket connections on a proxy side.
How client connects to the bridge
This is when Websockets or something like Socket.IO or SockJS comes in handy. Client can use Websockets (or fall back to xhr/jsonp-polling or whatever is supported) to talk to the bridge and bridge will talk to TCP servers using real socket connections. I decided to use SockJS although Socket.IO is fine too. Here is how the entire thing looks like:
How is it different than having a backend app
The difference is in where to put logic to handle different servers’ protocols. The normal way would be to handle it on a server side. So, for instance, if browser wants to get something out of Memcache – it will make a request to some backend app that knows how to get data out of Memcache. If suddenly you want to do something with Redis then you will need to modify backend code and restart server to add support for that.
On the other hand, if browser can operate on a socket level such protocol logic could be implemented on a client side. There can be just a bridge (or easily a cluster of bridges behind HAproxy) that knows nothing about servers’ protocols and just pass data to sockets back and forth. Whatever you want to connect to from the browser just include a JS client library in the page, no need to touch bridge at all.
Here are some examples for sockets, http, memcache client and redis client. I ported memcache client easily from node.js version just by using node-browserify and by replacing net library with WebTCP connection. Redis client for node.js relies on C library, so I had to implement client from scratch, but luckily Redis protocol is pretty simple.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
It’s also possible to specify advanced options when creating a socket connection
1 2 3 4 5 6 7
And then pass those options when creating socket
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
That’s about it. Although this project still need more thought to figure out good use cases, I had really fun time playing with it.