[Play-2.1.1][Java] Server Sent Events in Java

826 views
Skip to first unread message

Elvander

unread,
Aug 12, 2013, 3:55:33 PM8/12/13
to play-fr...@googlegroups.com
Hi,

I'm trying to implement Server Sent Events to send notifications to all my clients connected. But I'm having a hard time finding an example in Java.
But everything I find is for scala ...

Does anyone have a simple example in Java?
Or able to get me going?

I started from the sample provided by play!, using the websockets. But it seems it's not the way to go, to simple leave out the in channel and use a StringChunk ...

Kind regards,
Bart

James Roper

unread,
Aug 13, 2013, 3:26:58 AM8/13/13
to play-framework
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;
        }

    }
}      

Then you can do:

public static Result events() {
    return ok(new EventSource() {
        public void onConnected() {
            sendMessage("Hello world!");
            close();
        }
    });
}

Note I haven't tested this yet, you may need to do some debugging.


--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
James Roper
Software Engineer

Typesafe – Build reactive apps!
Twitter: @jroper

Elvander

unread,
Aug 14, 2013, 9:11:41 AM8/14/13
to play-fr...@googlegroups.com
Thanks a lot for the information and code . :-)

I'll give it a go this evening!

Philip Johnson

unread,
Aug 14, 2013, 12:27:18 PM8/14/13
to play-fr...@googlegroups.com
Elvander, if you get it working, could you publish a small demo systemthat the rest of us could look at as well?

Thanks!
Philip

Will Sargent

unread,
Aug 14, 2013, 12:29:57 PM8/14/13
to play-fr...@googlegroups.com
Nilanjan has a PR open for Java EventSource and a sample project:



--

Markus Jura

unread,
Apr 25, 2014, 2:19:21 AM4/25/14
to play-fr...@googlegroups.com, will.s...@gmail.com
Here is an Activator template which demonstrates SSE with Play Java and AngularJS: https://typesafe.com/activator/template/sse-chat-template-java

Enjoy!
Markus
Reply all
Reply to author
Forward
0 new messages