A new version of the library packed with lots of bug fixes and a fair share of new features.
The highlights of this release are:
WebSockets, part of W3C’s HTML5 draft and whose underlying BiDirectional or Server-Initiated HTTP protocol is currently being drafted by IETF, is promising to be an interesting revolution for web applications.
It gives stateful web applications (that keep state between requests not simply in a database but also communication state such as open sockets and other in-memory state) a suitable and reliable transport, which has virtually no overhead compared to bare TCP. While it is frequently introduced as a good solution to implement "server-push", we believe it is simply going to replace Ajax as the preferred communication protocol, also for client-initiated events.
HTTP is a stateless protocol: there is nothing in the protocol that implies that requests belong to a single conversation. As a consequence, stateful web application frameworks (such as Wt) bend the protocol to adapt it to its needs: including session information in each and every request, preventing request reordering, and in case of server push, adding reliability features in the face of intermediaries that can drop the connection whenever they feel like it.
Unlike plain HTTP, the WebSockets no longer mandates a request/response scheme. Unlike most web frameworks, Wt and JWt do not expose an API that works in terms of requests and responses, and existing Wt application can benefit from WebSockets using a simple configuration setting.
|The advent of WebSockets means bad luck for web applications developed in a stateless framework designed in terms of requests and responses, such as Django and Ruby on Rails — WebSockets are inherently stateful because of the open connection maintained between client and server.
WebSockets are currently implemented only using the C++ built-in HTTP server (effectively acting now as a WebSocket server as well). To enable it, add <web-sockets>true</web-sockets> to your configuration file. WebSockets are currently unsupported in JWt since they are not part of the servlet specification and would need some kind of support to share the same HTTP port. But some application servers already provide non-standard implementations (such as Jetty).
Despite that HTML5 is still a draft specification, and the WebSockets protocol itself in great state of flux (in fact, almost every aspect of it is being debated, including its unorthodox handshake), it has been implemented in current stable versions of Chrome and Safari, and in upcoming versions of Firefox (4.0) and Opera (10.70) (but no mention of it from the Microsoft Internet Explorer development team).
WebSockets requires however active cooperation of intermediaries (either through an HTTP/1.1 CONNECT, or through a protocol upgrade hand-shake). Most proxy software will need to be upgraded to provide support for WebSockets. This may seem like a show-stopper, but it isn’t. Reliability (and simplicity) is the only new feature that WebSockets add compared to existing workarounds based on XMLHttpRequest. This unreliability is caused mostly (only?) by these intermediaries. To solve the one problem of server push workarounds these days there is thus a need to involve the intermediaries and to detect whether they indeed will cooperate.
But that should not ruin the party: it is straight forward to detect availability of WebSockets on an individual basis, and simply continue using the current solutions otherwise. That is exactly what Wt does, extending its current progressive enhancement setup:
Because WebSockets have been designed to share the same port number as HTTP, firewalls are not going to get in the way. Wt’s builtin httpd now interprets both HTTP and WebSocket requests on port 80 (and HTTPS and WebSocket-over-SSL on port 443).
Wt and JWt already implement XMLHttpRequest-based long polling as a reliable server push solution in a unique way.
Most solutions using long polling suffer from a "two connection limit" problem that causes most alternatives to be unreliable. The unreliability originates from the fact that the browser has to decide how it reuses connections to a server and there is a risk that a request is blocked behind a long-polling request. Traditionally, Cometd or Bayeuex is implemented using a long polling request for the server to notify the client, and using a regular XMLHttpRequest to notify an event from client to server. In this scheme, it cannot be ruled out that the second request is queued behind the first request. A common solution is to use a different server/port/domain for the long polling request, which complicates deployment and/or usage of a non-standard port which may be interfered by firewalls.
Instead, Wt uses only a single XMLHttpRequest at any time and is in this way robust to this problem. When a client-side event occurs, the long-polling request is first aborted and then the regular request is made.
API-wise, and regardless of server push implementation, no more than two methods of WApplication deal with server push:
WApplication::enableUpdates(bool enable): Enables or disables server push (yes, you can enable server push even temporarily).
WApplication::triggerUpdate(): Pushes changes to the client. As with normal request handling, the library keeps track of what you changed and what needs to be synchronized with the client.
This release contains a sneak preview of Wt’s WebGL support, in WGLWidget. Although the documentation is still a bit sketchy, the API has evolved already to a point that we hope it will not require major changes. The distribution includes a simple example that works with the few browser that support WebGL (Firefox 4.0 and Chrome Canary).