views:

109

answers:

4

First off, I intend no hostility nor neglegence, just want to know people's thoughts. I am looking into bi-directional communication between client and server; client being a web application. At this point I have a few options: MS-proprietary duplex binding, from what I hear unreliable and unnatural: comet, and web sockets (for supported browsers).

I know this question has been asked in other ways here, but I have a more specific question to the approach. Considering web sockets are client-side, the client code sits in JavaScript. Is it really the intention to build a large chunk of an application directly in JavaScript? Why didn't W3C do this in web services? Wouldn't it be easier if we were to be able to use SOAP to provide a contract and define events along with the existing messaging involved? Just feels like the short end of the stick so far.

Why not make it simple and take advantage of JS dynamic nature and leave the bulk of code where it belongs....on the server?

Instead of

mysocket.send("AFunction|withparameters|segmented");

we could say

myServerObject.AFunction("that", "makessense");

and instead of

...
mysocket.onmessage = function() { alert("yay! an ambiguous message"); }
...

we could say

...
myServerObject.MeaningfulEvent = function(realData) { alert("Since I have realistic data....");  alert("Hello " + realData.FullName); }
...

HTML 5 took forever to take hold....did we waste a large amount of effort in the wrong direction? Thoughts?

+1  A: 

WebSocket makes Comet and all other HTTP push type techniques legible by allowing requests to originate from the server. It is kind of a sandboxed socket and gives us limited functionality.

However, the API is general enough for framework and library authors to improve on the interface in whichever way they desire. For example, you could write some RPC or RMI styled service on top of WebSockets that allows sending objects over the wire. Now internally they are being serialized in some unknown format, but the service user doesn't need to know and doesn't care.

So thinking from a spec authors POV, going from

mysocket.send("AFunction|withparameters|segmented");

to

myServerObject.AFunction("that", "makessense");

is comparatively easy and requires writing a small wrapper around WebSockets so that serialization and deserialization happens opaquely to the application. But going in the reverse direction means the spec authors need to make a much more complex API which makes for a weaker foundation for writing code on top of it.

Anurag
+3  A: 

JavaScript allows clients to communicate via HTTP with XMLHttpRequest. WebSockets extends this functionality to allow JavaScript to make arbitrary network I/O (not just HTTP), which is a logical extension and allows all sorts of applications that need to use TCP traffic (but might not be using the HTTP protocol) to be ported to JavaScript. I think it is rather logical that, as applications continue to move to the cloud, that HTML and JavaScript support everything that is available on the desktop.

While a server can do non-HTTP network I/O on behalf of a JavaScript client and make that communication available over HTTP, this is not always the most appropriate or efficient thing to do. For example, it would not make sense to add an additional round-trip cost when attempting to make an online SSH terminal. WebSockets makes it possible for JavaScript to talk directly to the SSH server.

As for the syntax, part of it is based on XMLHttpRequest. As has been pointed out in the other posting, WebSockets is a fairly low-level API that can be wrapped in a more understandable one. It is more important that WebSockets support all the necessary applications than that it have the most elegant syntax (sometimes focusing on the syntax can lead to more restrictive functionality). Library authors can always make this very general API more manageable to other application developers.

Michael Aaron Safyan
You can't quite connect directly to a raw socket using WebSockets (there is a handshake and two bytes of framing). My noVNC project includes `wsproxy` (http://github.com/kanaka/noVNC/tree/master/utils/) that proxies between WebSockets and raw TCP sockets.
kanaka
+2  A: 

As you noted WebSockets has low overhead. The overhead is similar to normal TCP sockets: just two bytes more per frame compared to hundreds for AJAX/Comet.

Why low-level instead of some sort of built-in RPC functionality? Some thoughts:

  • It's not that hard to take an existing RPC protocol and layer it on a low-level socket protocol. You can't go the opposite direction and build a low-level connection if the RPC overhead is assumed.

  • WebSockets support is fairly trivial to add to multiple languages on the server side. The payload is just a UTF-8 string and pretty much every language has built-in efficient support for that. An RPC mechanism not so much. How do you handle data type conversions between Javascript and the target language? Do you need to add type hinting on the Javascript side? What about variable length arguments and/or argument lists? Do you build these mechanisms if the language doesn't have a good answer? Etc.

  • Which RPC mechanism would it be modeled after? Would you choose an existing one (SOAP, XML-RPC, JSON-RPC, Java RMI, AMF, RPyC, CORBA) or an entirely new one?

  • Once client support is fairly universal, then many services that have normal TCP socket will add WebSockets support (because it's fairly trivial to add). The same is not true if WebSockets was RPC based. Some existing services might add an RPC layer, but for the most part WebSockets services would be created from scratch.

For my noVNC project (VNC client using just Javascript, Canvas, WebSockets) the low-overhead nature of WebSockets is critical for achieving reasonable performance. Until VNC servers include WebSockets support, noVNC includes wsproxy which is a generic WebSockets to TCP socket proxy.

If you are thinking about implementing an interactive web application and you haven't decided on server-side language, then I suggest looking at Socket.IO which is a library for node (server-side Javascript using Google's V8 engine).

In addition to all the advantages of node (same language on both sides, very efficient, power libraries, etc), Socket.IO gives you several things:

  • Provides both client and server framework library for handling connections.

  • Detects the best transport supported by both client and server. Transports include (from best to worst): native WebSockets, WebSockets using flash emulation, various AJAX models.

  • Consistent interface no matter what transport is used.

  • Automatic encode/decode of Javascript datatypes.

It wouldn't be that hard to create a RPC mechanism on top of Socket.IO since both side are the same language with the same native types.

kanaka
+4  A: 

Sounds to me like you've not yet fully grasped the concepts around Websockets. For example you say:

Considering web sockets are client-side

This is not the case, sockets have 2 sides, you could think of these as a Server and a Client, however once the connection is established the distinction blurs - you could then also think of the client and the server as "peers" - each can write or read in to the pipe that connects them (the socket connection) at any time. I suspect you'd benefit from learning a little more about HTTP works on top of TCP - WebSockets is similar / analogous to HTTP in this way.

Regarding SOAP / WSDL, from the point of view of a conversation surrounding TCP / WebSocket / HTTP you can think of all SOAP / WSDL conversations as being identical to HTTP (i.e. normal web page traffic).

Finally, remember the stacked nature of network programming, for instance SOAP/WSDL looks like this:

SOAP/WSDL
--------- (sits atop)
HTTP
--------- (sits atop)
TCP

And WebSockets look like this

WebSocket
--------- (sits atop)
TCP

HTH.

Robin
why was this downvoted?
Anurag