Question

I have some problems with the play! framework. The framework is new for me and my first and only practise with it, is this tutorial here.

I have a view which lists up some data. A Controller which have one method to show the view and another method which can receive some data with JSON. Now i would like to update the view when new data(JSON) is received.

I found out, that i can use either a comet socket, a websocket or server-sent events to implement this. (A permanent AJAX-polling ist not a option for me to do it.)

What is the best way to do this?

I tried to solve it with websockets, but it does not work as i want...

Here is my code:

public class MyController extends Controller{   
    public static Result showMyView() {
        return ok(views.html.showMyView.render(Data.all()));
    }

    @BodyParser.Of(play.mvc.BodyParser.Json.class)
    public static Result jsonReceiver() {
        JsonNode json = request().body().asJson();
        String rcvData = json.findPath("someData").textValue();

        if(rcvData != null) {
            /*FLAG*/
            //SEND SOME DATA OVER THE WEBSOCKET FROM HERE?! ..To update the view
            //something like: out.write("Now from here!");
            return ok();
        } else {
            return badRequest();
        }
    }

    public static WebSocket<String> websocket() {
        return new WebSocket<String>() {

            public void onReady(WebSocket.In<String> in, WebSocket.Out<String> out) {
                out.write("Hello!");
            }
        };
    }
}

Is there any way to send messages or other data over the socket from the position /*FLAG*/ in the code above?

My view looks like this:

@(dataContent: List[Data])
@main(title = "MyViews Observation Page") {
    @*
    SOME HTML CODE ...
    *@

<script type="text/javascript">
    var socket = new WebSocket("ws://" + location.host + "/path/to/my/websocket")

    socket.onmessage = function(event) {
        alert("Received: " + event.data); // only for testing... will be replaced later
    }
</script>
}

Can anybody help me here? I don't know how to update the view, when new data is received.

I would be very grateful if you could show it on the basis of my example code above. if it is easier to make it in a different way(comet or server-sent events), I am also very grateful for examples.

In my previous investigation i have found a few examples for comet and server-sent events but they were only in scala and i haven't understood them.

I'm using play framework 2.2.2 with java.

Was it helpful?

Solution

Each client will generate a WebSocket.Out on your server.

Store them in a List, and then call WebSocket.Out.write(objectNode)

public class MyController extends Controller{   
    //1. you store your client channels here
    private static ArrayList<WebSocket.Out> channels=new ArrayList<>();

    public static Result showMyView() {
        return ok(views.html.showMyView.render(Data.all()));
    }

    @BodyParser.Of(play.mvc.BodyParser.Json.class)
    public static Result jsonReceiver() {
        JsonNode json = request().body().asJson();
        String rcvData = json.findPath("someData").textValue();

        if(rcvData != null) {
           //3. you can write in your channels :)
           for(WebSocket.Out channel : channels){
               channel.write("blah");
           }

            return ok();
        } else {
             return badRequest();
        }
    }

    public static WebSocket<String> websocket() {
        return new WebSocket<String>() {

            public void onReady(WebSocket.In<String> in, WebSocket.Out<String> out) {
                  //2. each time a client connects, you save a reference to its channel
                  channels.add(out);
            }
        };
    }

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top