Reputation: 80
I have a scala controller in which I am calling an external webservice using WS
api of Play! framework which returns a json. The same api is now to be called using a WebSocketClient as every connection should be made using a WebSocket instead of http
. So normal Action
in controller are converted to WebSocket
functions, however I am not being able to call a WebSocket
function from within the scala code. I have searched and gone through several places on web for the solution, but I didn't found the solution anywhere. How can this be done, calling a WebSocket function and fetch its json using a WebSocketClient in scala code OR we can say, consuming a WebSocket
from within scala code ? I found a similar to mine questio on SO but none has given an answer to that! I want to know whether its possible or not in Play framework ?
Consume a WebSocket connection using Scala and Play
Edit: I am implementing the following code:
val c = new AsyncHttpClient()
val webSocketClient = c.prepareGet("ws://0.0.0.0:9000/testSocket").execute(new WebSocketUpgradeHandler.Builder().addWebSocketListener(new WebSocketTextListener {
override def onMessage(s: String): Unit = {
}
override def onOpen(webSocket: websocket.WebSocket): Unit = {
webSocket.sendTextMessage("test")
}
override def onFragment(s: String, b: Boolean): Unit = {}
override def onError(throwable: Throwable): Unit = {}
override def onClose(webSocket: websocket.WebSocket): Unit = {
latch.countDown()
}
}).build()).get()
val result = webSocketClient.sendTextMessage("true")
println("================================" + result)
The result
variable is not printed on console giving a json parser exception.
Update: My WebSocket
connection in ws://0.0.0.0:9000/testSocket
which is inside a scala controller of different project, is as under:
def sockeTest = WebSocket.tryAccept[JsValue] { request =>
futureJsonVariable.map { json =>
val in = Iteratee.ignore[JsValue]
// Some database computation here which generated a Future[JsValue] value in futureJsonVariable variable.
val out = Enumerator(json).andThen(Enumerator.eof)
Right((in, out))
} recover {
case err => Left(InternalServerError(err.getMessage))
}
}
Update2: One last thing I would like to ask regarding this is that, we invoke a WebSocket
connection using webSocket.sendMessage("test".getBytes())
which gives us the response of WebSocket
in the overridden method onMessage()
. I want to know, how can we await until a WebSocket
response is being received, so that we can perform the required computations with the WebSocket
response data. I have checked by returning a Future[JsValue]
variable inside the onMessage()
method but that thing is something invalid. So how can we put webSocket.sendMessage("test".getBytes())
in await mode, so that further code is executed upon the response of WebSocket
?
Upvotes: 0
Views: 347
Reputation: 12850
Play doesn't support WebSocket client connections. The best option is probably to use AsyncHttpClient
, this is the library that Play's WS API is built on so it will already be on your classpath, instructions for accessing WebSockets using it are here:
https://github.com/AsyncHttpClient/async-http-client
Upvotes: 1