Reputation: 43
I can't seem to get websocket communication to work in the Play Framework version 2.1.
I created a simple test that does nothing but send messages back and forth with a push of a button. All the code for it is below. But nothing shows up except for the button.
Has anybody seen this problem or can someone tell me what I may be doing wrong in the code below?
I am using the latest version of Chrome.
Here is my simple setup.
In Application.java
public static Result index() {
return ok(index.render());
}
public static WebSocket<String> sockHandler() {
return new WebSocket<String>() {
// called when the websocket is established
public void onReady(WebSocket.In<String> in,
WebSocket.Out<String> out) {
// register a callback for processing instream events
in.onMessage(new Callback<String>() {
public void invoke(String event) {
System.out.println(event);
}
});
// write out a greeting
out.write("I'm contacting you regarding your recent websocket.");
}
};
}
In Routes File GET / controllers.Application.index()
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(path="/public", file)
GET /greeter controllers.Application.sockHandler()
In Index.Scala.html
@main(null) {
<div class="greeting"></div>
<button class="send">Send</button>
<script type="text/javascript" charset="utf-8">
$(function() {
var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket
var sock = new WS("@routes.Application.sockHandler()")
sock.onmessage = function(event) {
$('.greeting').append(event.data)
}
$('button.send').click(function() {
sock.send("I'm sending a message now.")
});
})
</script>
}
In Main.scala.html
@(title: String)(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
<script src="@routes.Assets.at("javascripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
</head>
<body>
@content
</body>
Upvotes: 0
Views: 2149
Reputation: 2937
you can use a Route's webSocketURL()
method to retrieve a url that can be passed to a WebSocket's constructor. Here's an example from Play's websocket-chat sample code:
$(function() {
var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket
var chatSocket = new WS("@routes.Application.chat(username).webSocketURL()")
var sendMessage = function() {
chatSocket.send(JSON.stringify(
{text: $("#talk").val()}
))
$("#talk").val('')
}
// ...
So in your code you can use something like
var sock = new WS("@routes.Application.sockHandler().webSocketURL()");
Personally I don't like intermingling interpolated code with JS, since I think that any code executing on the client should only be concerned with the state of the client, and not the server (not to mention it makes refactoring the script out into an external file impossible), so I tend to do something like this:
<div class="container app-container"
data-ws-uri="@routes.Application.WSUri.webSocketURL()">
.......
</div>
Then in my JS I can just do something like
var sock = new WS(document.querySelector(".app-container").dataset.wsUri);
// ....
Upvotes: 3
Reputation: 497
The problem is in
var sock = new WS("@routes.Application.sockHandler()")
you have to specify the protocol and the complete url in the format: ws://localhost:9000/greeter.
Check this question to do it in javascript: How to construct a WebSocket URI relative to the page URI?
Upvotes: 3