playframework/playframework — pull request #2573 by jroper (2014-03-31 07:15:44+00:00)
Title: WebSockets refactoring

There are two main new features here, one is, in built support for handling WebSockets using actors (this code came from reactive maps and has been thoroughly reviewed by the Akka team). The other is the ability to reject a WebSocket by sending a Result.

In addition to this, since when working with actors, it might make sense to use higher level message types (when using iteratees/enumerators you can easily use enumeratees to address this), and the type of the messages coming in might be different to the type of the messages going out, this makes it possible to use different message types of incoming messages and outgoing messages.

This however is not implemented on the Java side, since the Java side does not provide any existing mechanism to format incoming messages, you can only handle them as strings, bytes or JSON. Adding this to the Java API would be a considerably large amount of work that I didn't want to take on just yet.

Of course, I also added tests, and this meant writing a WebSocket client (uses Netty).

In the process of writing tests, I found and fixed several bugs in Play's WebSocket support, including 2 race conditions and 2 spec non conformance bugs. In the process of fixing these I did some substantial refactorings to the WebSockets implementation in general.

I've added fairly comprehensive docs of the new features, and also extracted code samples that weren't previously extracted in the Scala WebSockets docs.

Summary of changes:

* WebSockets can now have both an input and output frame formatter (just scala)
* WebSocket actor support (java and scala)
* WebSocket handlers can reject a WebSocket with a Result (java and scala)
* Fixed race condition in Netty WebSocketHandler code that could cause incoming messages to be missed when the WebSocket is first created
* Fixed race condition in JavaWebSocket code that could cause incoming messages to be missed when the WebSocket is first created
* Fixed bug where close frame was not being sent when the consuming iteratee was done.
* Fixed bug where close frame was not being sent when the EOF was sent from the enumerator.
* Renamed NettyPromise to NettyFuture and made it an implicit conversion that provides a toScala method that converts ChannelFuture to scala.concurrent.Future[Channel]
* Added fairly comprehensive tests for WebSockets, handled with iteratees/actors/java actions
* Added documentation for all new functionality
* Extracted Scala code snippets