WebSocket connections and Tritium - websocket

Can a site use Tritium while also establishing open socket connections with whatever host you are 'filtering' requests from? Let's say I wanted to clone a site which is using WebSockets to keep open connections for a browser chat client. Would these requests be made directly between the browser and the remote host, or would they be passed through my Moovweb instance (which I'm presuming would allow me access to data in the stream)?

AFAIK, Moovweb 4.3 is not WebSocket aware. An upcoming release may support it though.
WebSockets works cross-domain by default so it's easy to go direct to the origin WebSockets server.
For example, say you specify the Websocket server with the line: var socket = new WebSocket("ws://echo.websocket.org");. You would not map the domain "echo.websocket.org" in Moovweb's config.json file. Instead you use the same line: var socket = new WebSocket("ws://echo.websocket.org"); on your Moovweb-powered site as well.

Related

How to handle multiple websockets from same browser's different tabs

I'm trying to implement a plugin for a game, which will communicate via websockets with my server. I want to prevent double connections from the same IP address from different browsers/tabs. I can't use cookies, because the connection is opened from plugin, which runs under a different domain, and cookies can be spoofed anyways, I also don't want to implement any authentication mechanism.
Now I went through myriad of implementations of websocket servers, but I still can't understand if I can communicate with multiples web sockets opened from same IP separately, or rather I want to communicate only with the very first websocket opened from a specific IP and ignore the requests that come from others. Is there any way to "store" a websocket connection on server side during handshake? Because as far as I can see I'm only getting a request and the only thing I can do is pass a parameter or token from client side, which again can be spoofed, so it's really not very different from a regular HTTP request, only with push option.
Thanks in advance.

How does WebSockets server architecture work?

I'm trying to get a better understanding of how the server-side architecture works for WebSockets with the goal of implementing it in an embedded application. It seems that there are 3 different server-side software components in play here: 1) the web server to serve static HTTP pages and handle upgrade request, 2) a WebSockets library such as libwebsockets to handle the "nuts and bolts" of WebSockets communications, and 3) my custom application to actually figure out what to do with incoming data. How do all these fit together? Is it common to have a separate web server and WebSocket handling piece, aka a WebSocket server/daemon?
How does my application communicate with the web server and/or WebSockets library to send/receive data? For example, with CGI, the web server uses environmental variables to send info to the custom application, and stdout to receive responses. What is the equivalent communication system here? Or do you typically link in a WebSocket library into the customer application? But then how would communication with the web server to the WebSocket library + custom application work? Or all 3 combined into a single component?
Here's why I am asking. I'm using the boa web server on a uClinux/no MMU platform on a Blackfin processor with limited memory. There is no native WebSocket support in boa, only CGI. I'm trying to figure out how I can add WebSockets support to that. I would prefer to use a compiled solution as opposed to something interpreted such as JavaScript, Python or PHP. My current application using long polling over CGI, which does not provide adequate performance for planned enhancements.
First off, it's important to understand how a webSocket connection is established because that plays into an important relationship between webSocket connections and your web server.
Every webSocket connection starts with an HTTP request. The browser sends an HTTP request to the host/port that the webSocket connection is requested on. That request might look something like this:
GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
What distinguishes this request from any other HTTP request to that server is the Upgrade: websocket header in the request. This tells the HTTP server that this particular request is actually a request to initiate a webSocket connection. This header also allows the web server to tell the difference between a regular HTTP request and a request to open a webSocket connection. This allows something very important in the architecture and it was done this way entirely on purpose. This allows the exact same server and port to be used for both serving your web requests and for webSocket connections. All that is needed is a component on your web server that looks for this Upgrade header on all incoming HTTP connections and, if found, it takes over the connection and turns it into a webSocket connection.
Once the server recognizes this upgrade header, it responds with a legal HTTP response, but one that signals the client that the upgrade to the webSocket protocol has been accepted that looks like this:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
At that point, both client and server keep that socket from the original HTTP request open and both switch to the webSocket protocol.
Now, to your specific questions:
How does my application communicate with the web server and/or
WebSockets library to send/receive data?
Your application may use the built-in webSocket support in modern browsers and can initiate a webSocket connection like this:
var socket = new WebSocket("ws://www.example.com");
This will instruct the browser to initiate a webSocket connection to www.example.com use the same port that the current web page was connected with. Because of the built-in webSocket support in the browser, the above HTTP request and upgrade protocol is handled for you automatically from the client.
On the server-side of things, you need to make sure you are using a web server that has incoming webSocket support and that the support is enabled and configured. Because a webSocket connection is a continuous connection once established, it does not really follow the CGI model at all. There must be at least one long-running process handling live webSocket connections. In server models (like CGI), you would need some sort of webServer add-on that supports this long-running process for your webSocket connections. In a server environment like node.js which is already a long running process, the addition of webSockets is no change at all architecturally - but rather just an additional library to support the webSocket protocol.
I'd suggest you may find this article interesting as it discussions this transition from CGI-style single request handling to the continuous socket connections of webSocket:
Web Evolution: from CGI to Websockets (and how it will help you better monitor your cloud infrastructure)
If you really want to stick with the stdin/stdout model, there are libraries that model that for your for webSockets. Here's one such library. Their tagline is "It's like CGI, twenty years later, for WebSockets".
I'm trying to figure out how I can add WebSockets support to that. I
would prefer to use a compiled solution as opposed to something
interpreted such as JavaScript, Python or PHP.
Sorry, but I'm not familiar with that particular server environment. It will likely take some in-depth searching to find out what your options are. Since a webSocket connection is a continuous connection, then you will need a process that is running continuously that can be the server-side part of the webSocket connection. This can either be something built into your webServer or it can be an additional process that the webServer starts up and forwards incoming connections to.
FYI, I have a custom application at home here built on a Raspberry Pi that uses webSockets for real-time communication with browser web pages and it works just fine. I happen to be using node.js for the server environment and the socket.io library that runs on top of webSockets to give me a higher level interface on top of webSockets. My server code checks several hardware sensors on a regular interval and then whenever there is new/changed data to report, it sends messages down any open webSockets so the connected browsers get real-time updates on the sensor readings.
You would likely need some long-running application that incoming webSocket connections were passed from the web server to your long running process or you'd need to make the webSocket connections on a different port than your web server (so they could be fielded by a completely different server process) in which case you'd have a whole separate server to handle your webSocket requests and sockets (this server would also have to support CORS to enable browsers to connect to it since it would be a different port than your web pages).

SocketIO tries to connect using same port as the browser used to get web page

I am serving content locally, accessible through http://0.0.0.0:4000. That works ok, I get a correct webpage, which contains the following line inside a script:
var socket = io('http://example.com');
i.e. I am referencing an external server. Now my browser shows the followoing error:
GET http://example.com:4000/socket.io/?EIO=3&transport=polling&t=1417447089410-1 net::ERR_CONNECTION_REFUSED
That is, the browser is trying to connect using the same port that it used to get the original page.
Everything works fine when both the SocketIO server and the web server listen on the same port.
Am I missing something? Is this a bug? Is there a workaround? Thank you.
You can read here about how a plain webSocket is initially set up. It all starts with a somewhat standard HTTP GET request, but one that has some special headers set:
GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
The interchange may also allow the host to enforce requests only from web pages on certain origins. While this header can be spoofed from non-web-browser agents (so the server has to be prepared for that), it will likely be correct when the OP is using a real browser (assuming no proxy is modifying it).
If the server accepts the incoming request, it will then return an HTTP response that looks something like this:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
At this point, the socket which used to be an HTTP socket is now a webSocket and both endpoints have agreed that they're going to use the webSocket data format from now on. This initial connection may be followed by some form of authentication or new or existing cookies can also be used in the authentication during the initial HTTP portion of the connection.
socket.io adds some enhancements on top of this by initially requesting a particular path of /socket.io and adding some parameters to the URL. This allows socket.io to negotiate whether it's going to use long polling or a webSocket so there are some exchanges between client/server with socket.io before the above webSocket is initialized.
So, back to your question. The socket.io server simply spies at all incoming web requests on the normal web port (and looks for both it's special path and for special headers to indicate a webSocket initiation rather than a classic HTTP request). So, it runs over the same port as the web server. This is done for a bunch of reasons, all of which provide convenience to the server and server infrastructure since they don't have to configure their network to accept anything other than the usual port 80 they were already accepting (or whatever port they were already using for web requests).
By default in socket.io, the domain and port will default to the same domain and port as the web page you are on. So, if you don't specify one or the other in your connect call, it will use the domain or port from the web page you are on. If you want to use both a different domain and port, then you must specify both of them.

Can I open a websocket connection to a local server running on an arbitrary port?

I have a local server outputting my real-time home sensor data, and I want to visualize it in my browser.
My question is, can I use a websocket to open the connection from my browser to the local server? How would I go about doing that?
The local server runs on a non-http designated port number, and I can't change that.
Yes and no.
No:
WebSockets are not raw TCP connections. They have an HTTP compatible handshake (for both security and compatibility with existing servers) and have some minimal framing for each packet to make WebSockets a message based protocol. Also, the current WebSocket API and protocol that exists in browsers as of today do not directly support binary data messages. They only UTF-8 encoded payloads.
Yes:
You can use websockify to proxy a WebSockets connection to a raw binary TCP server. websockify is a python proxy/bridge that has binary support and also includes a javascript library to make interacting with it easier. In addition, websockify includes the web-socket-js fallback/polyfill (implemented in Flash) for browser that do not have native WebSockets support. The downside is that you have to run websockify somewhere (either on the client system, the server system, or some other system). Also, websockify is Linux/UNIX only for now. On the plus side, websockify has a special mode that you can use to launch and wrap an existing service.
Disclaimer: I made websockify.

Unsolicited notifications from server to client over http

I am working on a dropbox like system and I am wondering how the client gets notified when the files change on the server side. It is my impression that both dropbox and ubuntu one operate over HTTP ports and work as follows:
1. if files change on client machine, inotify detects it and preforms a push from the client to the server. (I get this part)
2. if files change on the server a simple unsolicited notification (just a message saying "time to sync") is sent from the server to the client. Then the client initiates a sync to the server.
I dont really care which language I do this in. I am just wondering how the client gets contacted. Specifically, what if a client is behind a firewall with its own local IP addresses. How does the server locate it?
Also, what kind of messaging protocols would be used to do something like this? I was planning on doing this over HTTP or SSH, but I have no attachment do that.
I'm not sure what Dropbox is using, but it could be websockets (unlikely, it's a pretty new and not widely deployed thing) or more likely a pending Ajax request from the client to the server -- to which the server only responds when it has new stuff for the client. The latter is the common way to implement (well, OK -- "hack";-) some form of "server push" with HTTP.
It took a little research into networking to see how this would work, but it is far more trivial then I expected. I am now using standard Java sockets for this. Start up the server process which listens for a socket connection. Then start up the client which connects to the server.
Once the connection is made, messages can be sent back and fourth. This works through NAT (network address translation) which is standard method for routing packets on private networks behind a firewall.

Resources