Unfortunately we don't provide anything out of the box in Java to do this. Fortunately, it's really easy to implement:
import play.libs.F.Callback0;
import play.mvc.Results.Chunks;
import java.util.HashMap;
import java.util.Map;
/**
* A Chunked stream sending event source messages.
*/
public abstract class EventSource extends Chunks<String> {
private Out<String> out;
/**
* Create a new event source socket
*/
public EventSource() {
super(play.core.j.JavaResults.writeString("text/event-stream", play.api.mvc.Codec.javaSupported("utf-8")));
}
public final void onReady(Out<String> out) {
this.out = out;
onConnected();
}
/**
* Send an event on this socket.
*/
public void sendMessage(String message) {
out.write("data:" + message.replaceAll("\r?\n", "\r\ndata:") + "\r\n");
}
/**
* Send an event on this socket.
*/
public void sendMessage(Event event) {
StringBuilder buffer = new StringBuilder();
for (Map.Entry<String, String> field: event.fields.entrySet()) {
buffer.append(field.getKey()).append(":").append(field.getValue()).append("\r\n");
}
buffer.append("data:").append(event.message.replaceAll("\r?\n", "\r\ndata:")).append("\r\n\r\n");
out.write(buffer.toString());
}
/**
* The socket is ready, you can start sending messages.
*/
public abstract void onConnected();
/**
* Add a callback to be notified when the client has disconnected.
*/
public void onDisconnected(Callback0 callback) {
out.onDisconnected(callback);
}
/**
* Close the channel
*/
public void close() {
out.close();
}
/**
* An EventSource event.
*/
public static class Event {
private String message;
private final Map<String, String> fields = new HashMap<String, String>();
/**
* Create an event
*
* @param message The message to send
*/
public Event(String message) {
this.message = message;
}
/**
* Set the id for the event
*/
public Event withId(String id) {
if (id != null) {
fields.put("id", id);
}
return this;
}
/**
* Set the name for the event
*/
public Event withName(String name) {
if (name != null) {
fields.put("name", name);
}
return this;
}
/**
* Set the reconnection timeout that the client should use
*/
public Event withRetry(int milliseconds) {
fields.put("retry", Integer.toString(milliseconds));
return this;
}
}
}
Note I haven't tested this yet, you may need to do some debugging.