Interested in what our friends are up to, even if no-one else cares (as twitter illustrates). And also interested in what systems/things are doing, not just people. Chat (meebo), collaborative editing (google docs), streaming financial data (lightstreamer), async updates (yes.com), online gaming, async server processing (polar rose, i.e. shift processing complexity to the server – note this could be seen as an alternative to Gears-style local processing in some situations).
The web was designed to be connectionless – Comet blatently aims to make it connected.
Performance
Actually does scale. Joe shows the following graph:
Technical
Seven ways (!) to implement Comet.
Long polling – “slow” XHR request. Server doesn’t answer immediately. Special part of HTTP to do this – chunked mode. However, IE “lies to you” – keeps saying it’s got something, but you can’t actually inspect it.
Forever frame – Send text/plain and 4k whitespace to flush IE’s buffer. Flush with script tag for each data block. Must keep restarting to avoid memory leak.
Script tags – Dynamic script blocks, can point to any domain.
WebSockets – HTML 5 standard. Cleaner solution.
ActiveXObject(”htmlfile”) – htmlfile is an activeX control similar to XHR. Normally causes “clicking” noise in browser, but there’s a hack to turn it off in most cases. Obviously, this only works in IE. Most bizzare thing is you get 49 Javascript before garbage collection, leading to hair-pulling moments when you try to work out why your 50th command isn’t executing!
Mime messaging – “What push was built on 11 years ago” – x-multipart-replace. Works really well, though with memory leakage issues, but not in IE and historically not in the other browsers either.
Flash remoting
Forever GIF (bonus technique) – keep sending out new slices of an animated GIF!
Technical Issues
Co-ordination when browser has multiple tabs open to the same server – using window.name or cookies, but better solution is multi-home DNS – each call points to the server using a different name (1.example.com, 2.example.com etc all pointing to the same IP address).
Issues detecting when browser or connection has broken.
Proxies which don’t let the stream go through in real-time – hold on to the chunks for a while before releasing them all at once. Can detect if this is happening from the browser using a timestamp technique.
… so just like with Ajax, we have to come up with hacks, likewise with Comet. Facebook and GMail show it’s possible to work around these problems and get Comet working at scale.
API Styles
e.g. with WebSocket you’re simply posting and receiving data. Event handlers for onOpen, onRead etc. Joe says this will be too low-level in many cases, hence the following styles.
PubSub – e.g. cometd. Low coupling (server-browser separation – Joe describes demo where servers hot-swapped without affecting client), inter-language interop. Good analogy to SOAP, which has gradually shifted from RPC to document exchange.
API – this looks to me like Ruby’s remote JS – server controls what’s happening on the browser. e.g. Effect.shake(”price”) on the server will make the price div shake on the client.
Data Syc API – Keep changing/updating data store. Simplest to understand.
Offline Support (Google Gears and/or Dojo Offline)
TIBCO General Interface integration
Aptana Jaxer integration
OpenAjax Hub, PubSub, Bayeux, etc.
Joe gave a nice example of how the offline functionality could work:
For example, InfoQ uses DWR. If we get it right, it should be easy for you to make it so that if the network dies while a user is writing a comment, then the comment doesn’t get lost. When the network is next up, and the user visits InfoQ, the comment will be resent then. It’s a cool feature, and using DWR it should come almost for free.
Joe Walker tipped me off to a preview of iWebMvc which is meta framework that ties together DWR, Dojo, Spring and Hibernate/JPA a la AppFuse or Grails.
It is created by Jose Noheda, a DWR commiter, and the project aims are:
Is based on Java
Although supporting Grooy / JRuby is a plus
Helps me to kick start a project
But simplifying the process by giving me the best (and this can be tricky) set of frameworks for each task
Integrates both server and client sides
And it’s lightweight, robust and extensible. Read enterprise quality.
Supports all the common tasks a web app has to handle
I include here: User Management, CRUD operations, i18n support (both framework & data), AJAX and astounding visuals
Ajax represents a brave, new(ish) world of web development where coding on the client is just as important as on the server side. Hundreds of libraries exist that purport to make it easier for you, and there’s always the “Do It Yourself” approach. Which route should you take?
If you work with Java technologies, one choice that stands out is DWR, or Direct Web Remoting. With DWR, JavaScript-based client code that calls server-side objects works as if it were all running in the same process space. The simplicity and power DWR blends together has few rivals today.
In this, the first DWR book to be published, you’ll be introduced to DWR and all it has to offer, including reverse Ajax, XML and annotation-based configuration, container-managed security, simple POJO-based development, and greatly simplified client-side coding. You’ll learn by doing as you explore six fully functional applications including the following:
A webmail client for remotely accessing your e-mail accounts
A wiki for collaborative efforts
A file manager for remotely managing your server’s file system
A portal for enterprise reporting needs
A project management/time-tracking system
Even a fun little game!
In addition to DWR, you’ll also see how other popular libraries help realize the RIA/Web 2.0 vision, including Spring, Hibernate, dHTMLx, DataVision, Freemarker, and Ext JS. If you’re doing RIA development in Java, DWR is for you, as too is this book.
(and if you like sci-fi and pop culture references strewn throughout your reading material, and a touch of wise a**-edness too, you’re in for a good time to boot!)
gi.js is a library to help integrate DWR with TIBCO GI. It is due for official release with DWR 3.0, however it is reasonably stable now, and will probably only undergo performance tweaking before the official 3.0 release.
Since it doesn't have any dependencies on DWR, it can be used without waiting for an official release. The best place to download it is either via a milestone release of DWR (see the java.net download page), or through the FishEye view of the DWR CVS repository. See this direct link to gi.js.
The article walks through a simple example integrating with a fake social network backend:
When the news broke that DWR had joined the Dojo Foundation, it left a lot of questions regarding the future of the DWR framework. Joe Walker aims to address the future of DWR in his recent post, DWR: State of the Union.
So DWR is now part of the Dojo Foundation. I thought it would be good to quickly summarize where we are, and what I'm working on, and to give everyone a chance to comment.
DWR 2.0 has been out for 6 months or so. At the time, I swore that the next release would be a small one, called 2.1. However it appears that I’m not good at swearing because there is lots in the next release - I think we’re going to have to call it 3.0.
The next release of DWR looks feature rich adding enhanced JSON support and Gears integration among other things.
I am really excited to post this piece of news, as I genuinely like everyone involved. At the last Ajax Experience, Alex Russell and Joe Walker gave a joint keynote. At one point it was going to be slightly different, but this news hadn't been totally completed so it was held off (having to start a UK company, blah blah).
The news is that DWR has joined the Dojo Foundation. This is all thanks to SitePen, which Joe Walker has joined (technically, he has joined the UK Ltd etc).
I am excited to see what will come out of a closer collaboration. Ben recently had to implement a dashboard that needed to tie in to backend Java code, and DWR was a breeze and handled everything for him, including batching, which meant that only a few larger transactions were occurring instead of millions of little calls.
Anyway, back to the news:
“SitePen has experienced significant growth this year and we’re well
aware of the amazing talent and opportunity that will open up by
expanding in the UK, and all of Europe for that matter,†said SitePen
CEO, Dylan Schiemann. “Having a developer as talented as Joe Walker
join SitePen and head up our UK operations is an amazing win for SitePen
and its clients, who will now have access to even more valuable
expertise with DWR and related technologies.â€
DWR is an important open source library for Ajax and Java developers
because it simplifies development of applications based on Ajax, Reverse
Ajax, and Comet techniques. DWR will become part of the Dojo
Foundation, home of the Dojo Toolkit, Cometd and OpenRecord projects.
All Dojo Foundation projects exist separately, preserving flexibility
and choice for the varying development communities.
“SitePen is an extremely forward-thinking company that understands the
tremendous value of open source and I’m excited to be a part of it,â€
said Joe Walker. “Donating DWR to the Dojo Foundation will allow for
increased adoption and a stable environment in a great organization.â€
“Development teams, both small and large, have quickly discovered the
benefits of using DWR in conjunction with leading Ajax libraries like
Dojo, TIBCO General Interface, Scriptaculous, and others. "DWR joining
the Dojo Foundation is a great win for the DWR community," said Kevin
Hakman, director, TIBCO Software, Inc. who has been a corporate sponsor
of DWR's development for more than a year. "The close alignment of these
projects, and the anticipated integration points between them, will
serve to further simplify creating Ajax applications for Java developers."
A huge congrats to Joe, Dylan, Alex, and the rest of the teams.
I asked Joe to show us something interesting that he is playing with on DWR and he quickly obliged by showing us a new file upload and download feature that allows you to do new fancy things with files.
What is cool about this is that the APIs from Java and JavaScript lands feel right in each, but to do this DWR has to do a lot of fancy work to hide the details.
In Java land you write something like the following, which uses Java BufferedImages.
Greg Wilkins wrote a session rater for conferences that showcases how Jetty, Dojo and DWR can work together to provide real-time, two way communication.
The application gives a live 1 to 5 star rating of the sessions, speaker awards (Rockstar, Vulcan, Uber Geek or Droid) and per session chat rooms.
He delves into the details of Comet, Jetty, Continuations, and DWR "Reverse Ajax":
You've now seen how Jetty Continuations combined with Comet can provide an efficient, scalable solution for event-driven Ajax applications. I haven't given any figures for the scalability of Continuations because performance in a real-world application depends on so many variables. Server hardware, choice of operating system, JVM implementation, Jetty configuration, and indeed your Web application's design and traffic profile all affect the performance of Jetty's Continuations under load. However, Greg Wilkins of Webtide (the main Jetty developers) has published a white paper on Jetty 6 that compares the performance of a Comet application with and without Continuations, handling 10,000 concurrent requests. In Greg's tests, using Continuations cuts thread consumption, and concomitantly stack memory consumption, by a factor of more than 10.
You've also seen how easy it is to implement an event-driven Ajax application using DWR's Reverse Ajax technology. Not only does DWR save you much client- and server-side coding, but Reverse Ajax also abstracts the whole server-push mechanism away from your code. You can switch freely among the Comet, polling, or even piggyback methods, simply by altering DWR's configuration. You're free to experiment and find the best-performing strategy for your application, without any impact on your code.
If you'd like to experiment with your own Reverse Ajax applications, a great way to learn more is to download and examine the code of the DWR demos .
We have been talking about this release for awhile, and it is great stuff. Now you can do amazing things with Reverse Ajax, and know that security is core to the framework.
We asked Joe now that this version is out of the door, what is he looking to do for future releases:
JMS support, and OpenAjax Hub support so you can do pub/sub across
reverse ajax from one browser to another and back onto an enterprise
message bus.
ImageConverter to take Swing Images and turn them into Gifs. This would
make things like JCaptcha easy, but it also enable sexy things like
running a Swing app with -headless, taking screenshots and broadcasting
them to browsers. Add some event handling and you have multi-user X over
Ajax.
A Reverse Ajax compiler so we can take a large Javascript API (like for
example GI ;-) and create a Java version that generates script that can
be posted over reverse ajax.
An a million dull things like a better API to convert from
ScriptSessions to HttpSessions, session delete on window close, etc.
DWR has a new release that should be pretty stable, with a final release coming soon.
Features
The biggy is Guice support. If it wasn't for the fact that we could add this in without touching the core of DWR, I'd say this was too big a change at this point in the release cycle, however Tim Peierls (who you might know from this project) has done a stack of work to make DWR and Guice play really well together. You can read more about the background on Tim's blog.
Security: The Fortify review highlighted some areas where DWR was lacking. You can read more about what DWR now does to protect you in the DWR security documentation.
Reverse Ajax: There have been some cases where reverse ajax has not been as stable as it should be. I hope that most of those are now behind us.
The reverse Ajax features are really quite something. If you haven't checked them out yet, do so.
Joe Walker has discussed the progress of the OpenAjax Hub. He has participated in a demo of using the OpenAjax Hub with DWR or Lightstreamer. TIBCO GI is the UI side, and it plugs into either backends with no code changes.
With a traditional request/response model, DWR (and Lightstreamer) would be calling GI routines to update. With the pub/sub model the distinction between client and server is gone because the UI publishes things it's interested in back to the hub. There's no reason the UI has to be GI even: any UI that groks the OpenAjax hub can play. We could even have several UI components listening to the same messages on one page.
The OpenAjax Hub is getting close to a 1.0 release, and I'm hoping that DWR will have a server-side version of the OpenAjax hub soon after. This would allow you to transparently co-ordinate remote hubs, and even allow publishing of messages from one browser to another.
I've put the DWR version live so anyone can have a play. It's not exciting, but you can see it in action. Just click on an "Industry Sector" to see messages published to that sector. See the DWR/OpenAjax/GI demo. I hope to move where it is hosted soon, and this is definitely something of a test, so don't be surprised if you get a 404. I hope we can get a demo of the Lightstreamer version live soon too.
TIBCO has announced that they are doing to sponsor work by the DWR lead (Joe Walker) to integrate DWR and TIBCO GI.
This is good news for both parties:
TIBCO GI users will have a new way to integrate with Java web applications
DWR: The integration work between DWR and TIBCO GI will probably help integrate with other frameworks. Changes made to DWR to work with GI will be exposed for other work. For example, the DWR team will look at automating the currently-hand written server-side version of Scriptaculous Effects.
JBI users may get some tighter integration too, making your life easier. We are excited to see what comes of this.
More details (from the Press Releases)
TIBCO will work with DWR founder, Joe Walker, to provide ready-made integration points between DWR and TIBCO General Interface™, TIBCO’s Ajax Rich Internet Application toolkit for creating rich graphical GUIs in a browser. Additionally, the collaboration will seek to extend DWR so that it can function as a Java Business Integration (JBI) standard service engine and be deployed on TIBCO ActiveMatrix™, the industry’s first service virtualization platform. The complementary components of DWR and General Interface™ will ultimately enable businesses to expand their uses of message and event-based service-oriented architectures.
“We are excited to be working with TIBCO to push adoption of DWR further into the enterprise,†said Joe Walker, DWR founder. “DWR has been a leading Ajax framework for some time but working with TIBCO will help take DWR further into the realm of full Ajax Rich Internet Applications being deployed alongside message and event-driven service platforms.â€
With substantial application modernization efforts underway and a continued trend towards SOA in business, the combined Ajax libraries of General Interface and DWR will provide capabilities that deliver rich user features such as editable grids, real-time events and notifications, and streaming data. By running on Internet technology rather than operating or runtime environment dependent technologies, businesses will experience much lower costs of ownership.
“DWR is a rapid way for Java developers to expose Java objects as simple Ajax services without the need for additional configuration or transformation. We have many customers already using DWR with the General Interface Ajax library,†said Kevin Hakman, director product marketing, TIBCO General Interface. “With DWR’s reverse Ajax capability, messages and events can be pushed from the server to the browser so that Web applications can also have real-time notification and streaming data features.â€
So we're calling a function "google()" and passing it a data structure that includes all your contacts. So all we need to do is to do something with this data. The page I linked-to earlier creates a list from it using code like this:
There are 2 known solutions to CSRF attacks: secret hidden fields and scripted cookies.
Things that wont protect you:
Switching to POST and denying GET: Forms can be trivially altered with DOM manipulation to forge POST requests.
Checking the referrer field: the referrer field is open to manipulation and it is sometimes not sent by browsers. So you are left with a choice between allowing no referrer (an attacker can get around this) and denying no referrer (breaks many innocent users).
JSON: Removing the function call in the GMail example would mean we would have to use XHR rather then just a simple Script Tag. The door is still wide open.
Secret Hidden Fields
If all your sensitive URLs contain some secret shipped with the page, then the cross-domain rules in the browser will stop an attacker from discovering the secret, so the server can distinguish between submissions that come from pages supplied by the server (which are safe).
This technique is good for the "Web 1.0" situations which are light on scripting. It is fairly complex to setup because it requires the server to keep a track of the secret, and to manipulate all forms to contain a hidden field.
Double Submit the Cookie
The CSRF attack works by subverting what the browser will do with the cookie. Ideally, your cookies would be totally unavailable to anyone outside of your domain. This attack works because XMLHttpRequest in some page can use the cookies of some foreign domain when posting to that foreign domain. However the script can not read the cookie directly due to the cross-domain rules, so a slight modification of the hidden field solution is to read the session cookie using JavaScript and then adding to URLs, forms or the body of a POST request, and then checking in the server that the session cookie value that the browser sends in the header (which is subvertable) is the same as the session cookie in the request (this is not subvertable in the same way).
If you are using Ajax or a significant amount of scripting then this solution is a simple fix once solution.
Use a Library
Specifically - use DWR. If you are using DWR version 2 then this CSRF protection comes for free. DWR implements the double cookie submission pattern transparently.
DWR can dynamically generate JavaScript from a Java API. This is done at runtime rather than compile time, so we can use it to remote control many browsers. This makes it very easy to write things like chat applications, or anything particularly dynamic. Messages are sent to clients using Reverse Ajax.
Reverse Ajax
DWR supports 3 ways to asynchronously transfer messages from the server to the browser: Comet (long-lived HTTP connections), Polling and Piggyback. Of these Comet and Polling are active (fast but require extra network traffic) and Piggyback is passive (slower but doesn't need extra network traffic). DWR automatically selects the best method transparently to the programmer.
Security
Two of the the biggest generic dangers to ajax applications today arr Cross-Site Scripting (XSS), which most people are aware of, and the new tool in the hack-box: Cross-Site Request Forgery (CSRF). DWR helps you protect your site against these attacks by providing automatic protection against CSRF attacks for many configurations, and by defaulting to a mode where XSS attacks are reduced.