1. Objectives. 1.1 UDP and TCP networking. The goal is to make available in a JavaScript API all the functionalities of UDP and TCP networking. UDP must include support for multicast. Notably, multicast is used for receiving video streams and for service discovery. TCP must support SSL and it is also necessary to accept connections. SSL is widely used, for instance to retrieve emails (SMTP or IMAP). Also, "STARTTLS" (starting as a non encrypted TCP session and then upgrading to SSL) must be supported, as some mail servers (Microsoft Exchange) use that feature. Acting as a server can be useful (for gaming?) even for "small devices". There will probably be a future use for that. 1.2 Compatibility with current standard / Ease of porting code. Currently, there seems to be three "main" socket specifications for browsers: WebSocket, Mozilla, and Chrome. WebSocket being the W3C proposal (and the longest around). Chrome's socket API is basically JavaScript bindings of C Berkeley sockets. This is way to much low-level, JavaScript is a "higher" level language. Plus it is absolutely not compatible with WebSocket. Mozilla's proposal for TCP socket is based on WebSocket, it uses almost the same interface, but with add-ons and some ideas probably from NodeJS (suspend() and resume(), ondrain event). As for "server side" JavaScript programming, NodeJS is the "de facto" standard, with a large existing community and code base. It has lots of libraries (https://npmjs.org/) and demonstrated capabilities used by "production" servers. NodeJS's networking APIs (net.Socket, net.Server, and dgram.Socket) aren't compatible at all with W3C's WebSocket. For events, they use the EventEmitter interface instead of EventTarget, and use Buffer object instead of ArrayBuffer for handling binary data. However, NodeJS, just like WebSocket, uses non-blocking calls for sending, and asynchronous events for receiving. Hence it is easy to write a small abstraction layer for porting code from NodeJS to W3C's WebSocket like. So the idea here is to be compatible with WebSocket, to be a superset. That way, developers have less API to learn. 2. Architecture. 2.1 Asynchronous event based. Sending data is through non blocking buffered send() calls. Most systems buffer data sending anyway. Receiving data is through events. The event file implicitely buffers the receiving. Socket connections (TCP server) are accepted through events. 2.2 Socket Hierarchy. Both UDPSocket and TCPSocket implement the Socket interface. 2.2.1 Socket interface. Socket is the "parent" interface. It captures the basic functionnality of a socket. Both UDPSocket and TCPSocket derive from it. Also it would be possible to make WebSocket derive from Socket (it is possible to transmit any data encapsulated in the Web Socket Protocol). interface Socket : EventTarget { readonly attribute unsigned short ipVersion; // 4 or 6 for IPv4 or IPv6. readonly attribute SocketOptions options; // Socket options, note that it is read only. // Options can be changed using setOption() method, which does checking. // Peer information, not necessarly set for UDPSocket. readonly attribute DOMString address; // "123.123.123.123" for IPv4 or "4065:4456:2112::45" for IPv6. // (Mozilla calls this attribute host) of peer. readonly attribute unsigned short port; // Port number of peer. readonly attribute DOMString url; // "Unresolved" form of the address, example "peerhost.abc.net:8081". // Local information. readonly attribute DOMString localAddress; // Same format as adress attribute. readonly attribute unsigned short localPort; // Same format as port attribute. readonly attribute DOMString localURL; // Same format as url attribute, example "localhost:1234". const unsigned short CONNECTING = 0; // UDP will go directly to OPEN state upon creation. const unsigned short OPEN = 1; // A "half-closed" TCP socket will remain in OPEN state, see halfClosed flag. const unsigned short CLOSING = 2; // UDP will go directly to CLOSED state when closed. const unsigned short CLOSED = 3; // For a TCP that means both side closed. readonly attribute unsigned short readyState; // See readyState codes above. readonly attribute unsigned long bufferedAmount; // Amount of send() data buffered. attribute EventHandler onopen; // This event is fired when the socket is ready to receive/send. // For TCP, when the socket is effectively opened (both side handshaked). // For UDP, when the socket is successfully binded to a local interface. attribute EventHandler onerror; // on error, whatever. attribute EventHandler onclose; // This event is fired when the socket is properly closed: // When both sides have exchanged FIN for TCP. // For UDP, when unbinded from interface. // Set an option in SocketOptions. name is the option to change and value the new value (any valid JavaScript type). // Error handling: Return a boolean ? Or an error code ? Or return nothing but throw an exception on error ? // Would have same kind of function as setsockopt(). boolean setOption (DOMString name, jsVal value); // Close the socket. For TCP sockets this will close both sides. For UDP socket this will just unbind it. void close(); // Receiving and sending. attribute EventHandler ondrain; // When bufferedAmount becomes zero. attribute EventHandler onmessage; // When a packet of data is received. The actual event received depends upon type of socket. attribute BinaryType binaryType; // Control the format of the data of onmessage event. // Suspend or resume incoming data. void suspend (); // Or pause(). void resume (); // As a hint, send() returns true if user can continue to send immediately, or false if it is preferable to wait. // This idea is taken from Mozilla's proposal. boolean send(DOMString data); boolean send(Blob data); boolean send(ArrayBuffer data); boolean send(ArrayBufferView data); }; SocketOptions store all options regarding a socket. For example, the TTL (time to live) of packets sent using UDP. Note that some options can be duplicated SocketOptions = { nameOfOptions: valueWhateverType; }; 2.2.2 UDPSocket interface UDPSocket : Socket { readonly attribute unsigned short ttl; // TTL of the packets sent. // If none of address and port are specified, use default interface and random port. UDPSocket ([DOMString address], [unsigned short port], [SocketOptions options]); // Set the peer address. That way, it is possible to use send() methods without specifying an address. // Does what connecto() do for UDP socket. void setPeer (DOMString address, unsigned short port); // Join or leave a multicast group. Even if the socket is only sending to a multicast address, it is a good practice // to explicitely join the multicast group (otherwise some routers may not relay packets). // Add a method to retrieve membership list ? void MulticastMembership (DOMString address, unsigned short port); void dropMulticastMembership (DOMString address, unsigned short port); // Because UDP is an un-connected protocol, it is possible to send to any valid address. boolean send (DOMString data, DOMString address, unsigned short port); boolean send (Blob data, DOMString address, unsigned short port); boolean send (ArrayBuffer data, DOMString address, unsigned short port); boolean send (ArrayBufferView data, DOMString address, unsigned short port); }; interface UDPMessageEvent : Event { jsVal data; // String or ArrayBuffer depending on binaryType. DOMString address; // Address and port of sender. unsigned short port; }; 2.2.3 TCPSocket Here's a sketch of a TCP socket. There is much to do for SSL key specification, etc. interface TCPSocket : Socket { readonly attribute boolean ssl; // True if this is an SSL socket. readonly attribute boolean isHalfClosed; // // If localAddress is not specified, use default interface. If localPort is unspecified, use a random port. // Need another constructor for SSL socket (specify keys, etc.) TCPSocket (DOMString peerAddress, unsigned short peerPort, [DOMString localAddress], [unsigned short localPort], [SocketOptions options]); // Upgrade socket to SSL, needed for STARTTLS implementation. Add an event for when the upgrade is done ? void UpgradeToSSL (); // Half close the socket (won't send data anymore but still able to receive). void halfClose (); // Nagle algorithm can be enabled or turned off using setOption(). Add also an option to set keep alive. Etc. }; interface TCPMessageEvent : Event { jsVal data; // String or ArrayBuffer depending on binaryType. } 2.2.4 WebSocket A WebSocket interface can actually be an implementor of the Socket interface : interface WebSocket : Socket { readonly attribute DOMString extensions; readonly attribute DOMString protocol; void close([Clamp] optional unsigned short code, optional DOMString reason); }; It will of course inherit additional attributes (ondrain, socketOptions, etc) and method (setOptions()).