>> The goal was to add support for Web in a Box for browsers that didn't have native
WebSockets and I had a couple of options and I chose Socket.IO because it had the--is basically
designed to add a API that's very similar to WebSockets. Web support over transports
that weren't WebSockets. So, the API is very similar. It has the same semantics; a little
bit different functioning though. The data transport is very similar but there's some
additional support in that right now with WebSockets, if you login, you have no activity,
it'll just disconnect you after, say, five minutes or less. With Socket.IO there's some
heartbeats going back and forth so that the connection will not drop due to inactivity.
Right now, there's three server implementations; the Node.JS implementation which is officially
associated with Socket.IO JavaScript. And then someone wrote it in a server in Go and
another one wrote a server in Ruby. None of those, of course, would work for us. So, I
created the Socket.IO-java project. It's a J2E Servlet based implementation using the
jetty on a WebSocket component and the jetty continuations which was needed to do an efficient
non-multithreaded method of communication because if you've got, like, 10,000 clients,
you don't want 10,00 threads. You want 10,000 socket connections in the number of those
needed to support whatever it is that you're actually doing, otherwise, it's not scalable.
So, I did make some diff--I did fork the original Socket.IO project because I need to make some
changes to really make it work well with Wave in a Box. I changed the message encoding slightly
to support some other semantics. I should also mention that I created this as a separate
project because it has applicability outside of the Wave in a Box. I want to make sure
it would work with Web in a Box but I also wanted it to be an external project so other
people can use it for other purposes. I added a clean close semantic because with the original
Socket.IO implementation, you'd call disconnect and you had no way of knowing if the last
message you sent actually arrived at the server without implementing your own acknowledgement
step on top. With this, even when you'd call a close, you'll get a disconnect message indicating
exactly what kind of close was achieved, whether that was a clean close or whether not your
connection dropped somewhere along the way. It's not as good as true acknowledgments but
at least you'll know whether or not your close was successful or not. I also added more detailed
information to your disconnect, so you know what kind of disconnect occurred, whether
or not the server an--issued a disconnect or if you just lost your connection entirely
or if there was some unknown error. And I did some minor bug fixes and changes as well.
And unfortunately right now, it is not compatible with the official Socket.IO implementation
so you can't use this JavaScript with my server. You have to use this JavaScript that's served
from my server. Socket.IO supports six transports. There's the raw WebSockets, there's a Flash-based
WebSocket implementation, htmlfile, XHR which stands for XML HttpRequest multipart, long
polling, and jsonp long polling. For the WebSocket, obviously, you've got Chrome 6+ support, Safari
5, I think, outside of the iPhone universe because they went with the version just prior
to the addition of WebSockets, and I don't know if Firefox 4 works with raw WebSockets.
I think some people managed to make that work. Now, the Flash-based WebSocket will not work
behind a proxy. There is--in the Flash implementation, there is a way to tell it what proxy to use
and what username and password to use but it's not really usable in a generic environment
because the browser needs to know about the proxy information and that basically requires
prompting the user for the information and most users don't know what that is--most non-techno
users, anyway. See on the server side, the WebSocket implementation on the server side
is basically the same, although it does go though a different URL and the server serves
up those, the Flash component. Htmlfile is really for--there's two classes of non WebSocket
transports. There is a persistent connection and a non-persistent connection. Unfortunately,
non of them have persistent send, but they all have persistent GET, so with htmlfile,
you're basically implementing the client calls "get" and then the server just strings messages
over them as required and the connection doesn't close until the end--session ends. So, this--with
this reason, the chunked transfer encoding which is basically the amount of bytes and
then the bytes being sent, you know, repeatedly, is a little bit overhead in the messages in
that what's being sent is actually a script tag on the client's side, though it cleans
them up so you only have one script tag at a time in the html documents that doesn't
max out your memory over time. Going from client to server, it's a simple POST message
where you can have one or more messages encoded in the block and then pushed. And because
it's a plain text, there's not a lot of extra rigmarole you have to go through to translate
from a client side to server side. XML H--the multipart on Firefox, the XML HttpRequest
supports multipart transport, so the server is basically expressing a content type of
"multipart/x-mixed-replace" which I'm not completely familiar with, but basically means
that each multipart replaces the previous multipart, so you don't end up growing your
document over time. So, the different coding, the boundary that's specified is, right now,
is a random 20-character string. So, there is a small chance that random--that that random
20-character string plus previous two dashes is going to appear in actual content. If that
happens, that message won't make it through, but because it's a random 20-character string,
the chances of that happening are fairly small. We would need--in order for absolute bulletproofness,
we'd have to add some sort of a encode-decode for that one rare case. Right now, that's
not deal with. And again, the server--the client to server is POST and in the JavaScript,
if an existing--if a POST is active, then the messages are queued up until the next--until
the POST completes then it pushes an entire block of messages. So if you're just cramming
messages down the pipe, each POST will contain multiple messages. Long polling, this is the
most common transport we're familiar with before. The GET will time out eventually;
right now, the time out is 20 seconds because most browsers have a request timeout of 30
seconds. We want to make sure that we get an empty reply versus a connection timed out.
And there's no need for any sort of special encoding, so it just sends the message box
plain and again, the server side is POST messages. And then jsonp-polling, I'm told is really
only needed for doing cross domain in IE. I'm not sure what other browsers might require
it. The client is basically pushing JavaScript method calls and posting apparently requires
using a form in an--in a iFrame and the data has to go through those "form-urlencoded"
stuff so some decoding has to happen on the server side. The messages are encoded in a
block. We use a little [INDISTINCT] between the pieces. You got the message type, message
size and then the data. Message types--the very first message the client gets when he
connects the session ID and it uses that for further connections. So, the--a spe--for WebSockets,
it won't matter, but for all the others, the server needs to know which session the connection
is associated with as a close message. Ping-Pong is for your--keeping your session liveness
so that the server will pair out. It will send a Ping and then a client has to reply
with a Pong within a certain time. Otherwise, their connections drop. And then you've got
your data blocks. The API does support the idea of a message base on interlinking message
types so that you can--makes it easier for you to have multiple message types going back
from clients sever that the software itself doesn't need to know about but your client's
software can switch on. For the future, playing on standardizing the client/server protocol,
because right now it's all you have to look at the code to figure out what they're doing
but I'd like to at least have a document, so that anybody can implement a server or
a client based on that standard. And we want to--I want to separate the handshake for a
session from the actual connection to make it a little bit easier to implement some alternative
authentication forms. And right now, the server has intimate knowledge of how the client's
JavaScript is implemented, and I want to separate it out. There's a document written by a Michael
Carter describing something he called a Comet Session Protocol and one of the ideas he had
in there was this ability for the client to specify what the preamble and pre and post
block stuff was. So, for example, that script tag stuff for htmlfile, the client would say,
"Here is what I expect before and after the actual message data," and then the server
just passes that. It doesn't even know what it's dealing with. So, that the client has--the
server becomes independent from the client in terms of implementation, so if the client
decides to change the name of the method that's in the script tag, the server doesn't even
know that. The client just tells it during the session establishment and then the server
just feeds those pieces around a block of data. And then there's also plans to converge
the existing Socket.IO project, the core project and the stuff that I've done, so that you
can pick up the improvements, but we're still on discussion on that. Those who like to--there's
no test cases right now. I've got some simple test applications to make. Example applications
I can use for testing like a chat at a echo and broadcast but I'd like to--I need to add
some formal test cases so that you can do a lot of unit testing without having to start
something up and type in it. Same--browser test should be a lot more difficult but I
do want to have something so you can just basically point your browser to a URL and
have it run the tests and tell you which ones passed and which ones failed. Make it a lot
easier to go through all of your browser tests. And I believe it's also going to be possible
to add support for extra--other [INDISTINCT] containers. For right now, I do know that
this code should work in Tomcat 6, the latest version without--but the WebSocket won't all
work, but the other stuff will. I think that's--and here is the projects that are involved. Got
the original Socket.IO project. He's got his own Socket.IO webpage and the github source
code project. And you could add a "–node" here to get to the Node.JS project and he
has links to it in there, so it's easy to find. WebSocket.JS is the Flash-based WebSocket
project. I should point out that right now, he doesn't--he only supports version 76 of
the WebSocket protocol. The new IETF draft 3 isn't supported. Jetty added support for
that in their 7.2 version but I don't support that yet either because they changed the APIs.
I've--here--the next one, the Socket.IO-fork, that's the forked version of the Socket.IO
code to post the changes I've made and then Socket.IO-java is the Google code project
to host the java site. And the Flash and the Socket.IO-JavaScript, that search in the server
is contained in this project as well, so you don't have to get the project to make them
work together. Any questions? Yes. >> On the proxy, you had said you forgot to
do that so [INDISTINCT]... >> The Flash base doesn't work through a proxy
but everything else does. >> All except Flash?
>> Yeah. Just Flash because the difficulty is that there's no way programmatically for
JavaScript or a Flash component to query the browser for proxy information. The bro--no
browser provides that information to you. You can't ask what proxy are you talking to,
you know, what's the user name and password do I need to use. None of that's available,
so in order for the Flash to get though a proxy, you have to explicitly tell it in code,
"Here is the proxy, here is the user name, and here is the password you have to use."
In order to dot hat though, you have to query the user to get that information. So, the
Flash-based WebSocket won't work through a proxy without a lot of rigmarole that it's
not really not appropriate in a--on a generic user environment. Now, in a speci--in a fixed
enterprise environment where that information is--can be hard coded into your--into the
code, then you can prompt the user for their username and password again and then that
would work but that won't work for most cases. Everything else, though, does work through
a proxy. I've tested it. >> Sorry if you had mentioned this. Does it
automatically--so if you got--if it's not working, you kind of establish a connection
through your Flash, will it just automatically basically be created?
>> Yeah, it will fall through. Usually, if things are poorly configured, it will fall
through to the XHR-Polling. >> Okay. Does it take a while to do that?
Perhaps a... >> It--in Chrome, things connect right away.
In Firefox, it does take--it seems to take, you know, three to ten seconds to establish
a connection. I don't know if there's any way to speed that up. If you know for a fact
that you're never going to use the Flash type, you can modify the project to just tell it
not to even consider Flash, just skip right on through and then the connection should
happen a little bit quicker. But it does--it does work through. It checks--it checks to
see which transports it can--should work based on whether or not you each--even have the
WebSocket API and it'll try those first. But it doesn't find them or--I think in the case
of WebSocket, WebSocket fails, it won't--it won't fall trough but in the case of Flash,
it will fall through. Any other questions? Okay.
just tell it not to even consider Flash, just skip right on through and then the connection
should happen a little bit quicker. But it does--it does work through. It checks--it
checks to see which tran