Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use WebSockets with Play Framework?

I have downloaded Play Framework from GitHub and compiled it. Now I want to use WebSockets and made a JavaScript client and a WebSocket controller similar to the one on Using WebSockets, but it doesn't work. I can open the WebSocket, but the controller doesn't receive any message I send to it. And I can't close the WebSocket with ws.close();, but if I update my webpage in the browser, the WebSocket is closed on the server.

How can I receive and send WebSocket messages using Play Framework?

Here is my 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");
            }
        }
    }

}

Here is my JavaScript client:

<!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>
like image 561
Jonas Avatar asked Oct 27 '11 17:10

Jonas


1 Answers

I have taken your code and run it on Chrome 14 and 15 and Firefox 7, with the latest version of Play from the Master Branch, and it seems to work mostly. I can

  • connect
  • send message

The changes I made where

  • define ws at a global scope, so put var ws = null just before the window.onload function.
  • for Firefox, I had to use MozWebSocket instead of WebSocket, so you may need to put an if statement to check based on browser.
  • change frame.getTextData() to frame.textData
  • frame.isBinary() to frame.isBinary

The second two bullets I had to do to get the code to compile?!

like image 182
Codemwnci Avatar answered Oct 08 '22 15:10

Codemwnci