Как использовать WebSockets с Play Framework?

#java #javascript #playframework #websocket

#java #javascript #игровая рамка #веб- сокет

Вопрос:

Я скачал Play Framework с GitHub и скомпилировал его. Теперь я хочу использовать WebSockets и создал JavaScript-клиент и контроллер WebSocket, похожие на те, которые используются при использовании WebSockets, но это не работает. Я могу открыть WebSocket, но контроллер не получает никаких сообщений, которые я ему отправляю. И я не могу закрыть WebSocket с ws.close(); помощью , но если я обновлю свою веб-страницу в браузере, WebSocket будет закрыт на сервере.

Как я могу получать и отправлять сообщения WebSocket с помощью Play Framework?

Вот мой игровой фреймворк WebSocketController:

 public class TestSocket extends WebSocketController {

    public static void hello(String name) {

        while(inbound.isOpen()) {
            WebSocketEvent evt = await(inbound.nextEvent());
            if(evt instanceof WebSocketFrame) {
                WebSocketFrame frame = (WebSocketFrame)evt;
                System.out.println("received: "   frame.getTextData());
                if(!frame.isBinary()) {
                    if(frame.getTextData().equals("quit")) {
                        outbound.send("Bye!");
                        disconnect();
                    } else {
                        outbound.send("Echo: %s", frame.getTextData());
                    }
                }
            } else if(evt instanceof WebSocketClose) {
                System.out.println("socket closed");
            }
        }
    }

}
 

Вот мой клиент JavaScript:

 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>WebSocket test</title>
<style>
.message {background: lightgray;}
</style>
<script>
window.onload = function() {
    document.getElementById('sendbutton')
        .addEventListener('click', sendMessage, false);
    document.getElementById('connectbutton')
        .addEventListener('click', connect, false);
    document.getElementById('disconnectbutton')
        .addEventListener('click', disconnect, false);
}

function writeStatus(message) {
    var html = document.createElement("div");
    html.setAttribute('class', 'message');
    html.innerHTML = message;
    document.getElementById("status").appendChild(html);
}

function connect() {
    ws = new WebSocket("ws://localhost:9000/ws?name=TestUser");

    ws.onopen = function(evt) { 
        writeStatus("connected");
    }

    ws.onclose = function(evt) {
        writeStatus("disconnected");
    }

    ws.onmessage = function(evt) {
        writeStatus("response: "   evt.data);
    }

    ws.onerror = function(evt) {
        writeStatus("error: "   evt.data);
    }
}

function disconnect() {
    ws.close();
}

function sendMessage() {
    ws.send(document.getElementById('messagefield').value);
}
</script>
</head>
<body>
<h1>WebSocket test</h1>
<button id="connectbutton">Connect</button>
<button id="disconnectbutton">Disconnect</button><br>
<input type="text" id="messagefield"/><button id="sendbutton">Send</button>
<div id="status"></div>
</body>
</html>
 

Ответ №1:

Я взял ваш код и запустил его в Chrome 14 и 15 и Firefox 7 с последней версией Play из ветки Master, и, похоже, он работает в основном. Я могу

  • Контакты
  • Отправить сообщение

Изменения, которые я внес, где

  • определите ws в глобальной области видимости, поэтому поместите var ws = null непосредственно перед функцией window.onload.
  • для Firefox мне пришлось использовать MozWebSocket вместо WebSocket , поэтому вам может потребоваться ввести оператор if для проверки в зависимости от браузера.
  • изменить frame.getTextData() на frame.textData
  • frame.isBinary() Для frame.isBinary

Вторые два пункта, которые я должен был сделать, чтобы заставить код скомпилироваться ?!

Комментарии:

1. Но я загрузил его с GitHub, см. Мое первое предложение.

2. Хм, Николас упомянул, что это должно быть исправлено. Возможно, это не проблема. К сожалению, я использую более позднюю версию Chome amp; FF, поэтому тоже не могу протестировать.

3. Простой пример с outbound.send("Hello %s!", name); работает нормально.

4. Для меня он не компилируется с frame.textData and frame.isBinary , он компилируется только с frame.getTextData() and frame.isBinary() . "Error raised is : isBinary cannot be resolved or is not a field"

5. Похоже, мы не используем один и тот же исходный код, я загрузил свой код сегодня git clone git://github.com/playframework/play.git --depth 1 и скомпилировал его, используя ant в framework/ папке.

Ответ №2:

У меня были проблемы с приведенным выше кодом в Chrome 20 и Play 1.2.4

Обновлен до Play 1.2.5 и работает как шарм!!