§Comet
§Using chunked responses with Comet
A common use of chunked responses is to create Comet sockets.
A Comet socket is a chunked text/html
response containing only <script>
elements. For each chunk, we write a <script>
tag containing JavaScript that is immediately executed by the web browser. This way we can send events live to the web browser from the server: for each message, wrap it into a <script>
tag that calls a JavaScript callback function, and write it to the chunked response.
Because ok().chunked
leverages Akka Streams to take a Flow<ByteString>
, we can send a Flow
of elements and transform it so that each element is escaped and wrapped in the Javascript method. The Comet helper automates Comet sockets, pushing an initial blank buffer data for browser compatibility, and supporting both String and JSON messages.
§Comet Imports
To use the Comet helper, import the following classes:
import akka.NotUsed;
import akka.stream.javadsl.Source;
import play.core.j.JavaHandlerComponents;
import play.libs.Comet;
import play.libs.Json;
import play.mvc.Http;
import play.mvc.Result;
You will also need a materializer, which is best done by pulling akka.stream.Materializer
from your DI system.
§Using Comet with String Flow
To push string messages through a Flow, do the following:
public static Result index() {
final Source<String, NotUsed> source = Source.from(
Arrays.asList("kiki", "foo", "bar")
);
return ok().chunked(source.via(Comet.string("parent.cometMessage"))).as(Http.MimeTypes.HTML);
}
§Using Comet with JSON Flow
To push JSON messages through a Flow, do the following:
public static Result index() {
final ObjectNode objectNode = Json.newObject();
objectNode.put("foo", "bar");
final Source<JsonNode, NotUsed> source = Source.from(Collections.singletonList(objectNode));
return ok().chunked(source.via(Comet.json("parent.cometMessage"))).as(Http.MimeTypes.HTML);
}
§Using Comet with iframe
The comet helper should typically be used with a forever-iframe
technique, with an HTML page like:
<script type="text/javascript">
var cometMessage = function(event) {
console.log('Received event: ' + event)
}
</script>
<iframe src="/comet"></iframe>
Note: add the following config to your application.conf and also ensure that you have route mappings set up in order to see the above comet in action.
play.filters.headers { frameOptions = "SAMEORIGIN" contentSecurityPolicy = "connect-src 'self'" }
For an example of a Comet helper, see the Play 2.5 Clock Template.
§Debugging Comet
The easiest way to debug a Comet stream that is not working is to use the log()
operation to show any errors involved in mapping data through the stream.
§Legacy Comet Functionality
Previously existing Comet functionality is still available through play.libs.Comet
, but it is deprecated and you are encouraged to move to the Akka Streams based version.
Because the Java Comet helper is based around callbacks, it may be easier to turn the callback based functionality into a org.reactivestreams.Publisher
directly and use Source.fromPublisher
to create a source.
Next: WebSockets