如何在Play框架中使用WebSockets?

9
我已经从GitHub下载了Play Framework并进行了编译。现在我想使用WebSockets,并制作一个类似于使用WebSockets中的JavaScript客户端和WebSocket控制器,但它不起作用。我可以打开WebSocket,但控制器没有接收到我发送给它的任何消息。我也无法用ws.close();关闭WebSocket,但如果我在浏览器中更新我的网页,则服务器上的WebSocket会被关闭。
如何使用Play Framework接收和发送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>
2个回答

6
我已经拿到你的代码并在Chrome 14、15和Firefox 7上运行,使用了最新版本的Play主分支,它似乎大多数情况下可以工作。我可以:
  • 连接
  • 发送消息
我所做的更改是:
  • ws定义为全局变量,在window.onload函数之前加入var ws = null
  • 对于Firefox,我必须使用MozWebSocket代替WebSocket,因此您可能需要根据浏览器放置一个if语句进行检查。
  • frame.getTextData()更改为frame.textData
  • frame.isBinary()更改为frame.isBinary
我必须执行后两个步骤才能使代码编译通过?!

嗯,Nicolas提到过要修复这个问题。也许这不是问题的原因。不幸的是,我使用的是Chrome和FF的较新版本,所以无法进行测试。 - Codemwnci
使用 outbound.send("Hello %s!", name); 的简单示例运行良好。 - Jonas
对于我而言,使用frame.textDataframe.isBinary无法编译通过,只有frame.getTextData()frame.isBinary()可以编译通过。"错误信息显示:isBinary无法解析或不是一个字段"。 - Jonas
听起来我们没有使用相同的源代码,我今天使用 git clone git://github.com/playframework/play.git --depth 1 下载了我的代码,并在 framework/ 文件夹中使用 ant 进行编译。 - Jonas
你在哪个平台上?我现在已经在 Mac OS X 上尝试了,它像你描述的那样工作。但是现在当我再次在 Windows 上尝试时,我遇到了与之前相同的问题。 - Jonas
显示剩余2条评论

0

我在Chrome 20和Play 1.2.4上遇到了以上代码的问题。

升级到Play 1.2.5后,一切都运行得很好!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接