Play Framework 2.x: Как обновить отображаемый вид со стороны сервера?

У меня есть некоторые проблемы с игрой! фреймворк. Этот фреймворк является новым для меня, и моя первая и единственная практика с ним - это руководство здесь.

У меня есть представление, которое перечисляет некоторые данные. Контроллер, у которого есть один метод для отображения представления и другой метод, который может получать некоторые данные с помощью JSON. Теперь я хотел бы обновить представление при получении новых данных (JSON).

Я обнаружил, что я могу использовать либо кометный сокет, веб-сокет или отправленные сервером события, чтобы реализовать это. (Постоянный AJAX-опрос для меня не вариант).

Каков наилучший способ сделать это?

Я пытался решить его с помощью веб-сокетов, но он не работает, как я хочу...

Вот мой код:

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!");
            }
        };
    }
}

Есть ли способ отправить сообщения или другие данные через сокет с позиции /*FLAG*/ в коде выше?

Мой взгляд выглядит так:

@(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>
}

Кто-нибудь может мне здесь помочь? Я не знаю, как обновить представление, когда новые данные получены.

Я был бы очень признателен, если бы вы могли показать это на основе моего примера кода выше. если проще сделать это другим способом (кометные или отправленные сервером события), я также очень благодарен за примеры.

В моем предыдущем исследовании я нашел несколько примеров кометных и серверных событий, но они были только в scala, и я их не понял.

Я использую Play Framework 2.2.2 с Java.

1 ответ

Решение

Каждый клиент будет генерировать WebSocket.Out на вашем сервере.

Сохраните их в списке, а затем позвоните 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);
            }
        };
    }

}

Другие вопросы по тегам