0

I have created a web socket that receives a single message, that will do some processing and returns the response message to the client. I have created web socket using Play framework. The code snippet is given below.

Code snippet:

def multi_request = WebSocket.tryAccept[String] {
    request =>
      val (out, channel) = Concurrent.broadcast[String]
      val in = Iteratee.foreach[String] {
        msg =>
          channel push ("message " + msg +" request Time: " + System.currentTimeMillis()/1000)
          if(msg.equals("1")) {
            Thread.sleep(20000);
            println(msg);
          } else if(msg.equals("2")) {
            Thread.sleep(10000);
            println(msg);
          } else {
            println(msg);
          }
          channel push ("message " + msg +" response Time: " + System.currentTimeMillis()/1000)
      }
      Future.successful(Right(in, out))
  }

I have tested my web socket from the http://www.websocket.org/echo.html. I have connected my web socket and passed three messages sequentially as "1", 2" and "3". I got the below response while passing these messages.

SENT: 1

RESPONSE: message 1 request Time: 1457351625

SENT: 2

SENT: 3

RESPONSE: message 1 response Time: 1457351645

RESPONSE: message 2 request Time: 1457351646

RESPONSE: message 2 response Time: 1457351656

RESPONSE: message 3 request Time: 1457351656

RESPONSE: message 3 response Time: 1457351656

It seems that, the web socket request hits the server sequentially not In parallel. The three messages sent from the client immediately when I pass it. But it is not hitting server in parallel.

That is, the second request hits after the first response message. The third message hits after the second response message.

Is this the default web socket behaviour?

Or Do I want to implement multi-threading to handle this kind of request in Scala play Framework?

Or Did I miss anything in the code to handle multiple requests from the single client?

SKK
  • 1,705
  • 3
  • 28
  • 50

1 Answers1

1

I understand this is web socket behaviour. This SO question explains in details how your web socket connection is uniquely identified by the pairs (IP,PORT) for both your client machine and the server as well as by the protocol used.

So basically you can have only one "physical websocket connection" (using the same port) between your client and your server. Looking at the documentation for accept, I read

If no pending connections are present on the queue, and the socket is not marked as nonblocking, accept() blocks the caller until a connection is present. If the socket is marked nonblocking and no pending connections are present on the queue, accept() fails with the error EAGAIN or EWOULDBLOCK.

I would love for someone more knowledgeable to confirm it, but I understand from this quote that since your potential connection is busy handling the first message, accept will tell your second request "try later", hence the sequential effect.

If you really need parallel websockets for one client, I guess opening connections on different ports would do the trick.

Community
  • 1
  • 1
John K
  • 1,285
  • 6
  • 18
  • Thank you for the reply. I confirmed that this is the web socket's behaviour by the http://stackoverflow.com/q/11976877/1584121 SO question. Will I able to implement multi-threading (or) multi-processing concepts here to handle this kind of request. – SKK Mar 09 '16 at 05:14
  • I would say yea by opening multiple connections per client (using different ports, either on server or client side). But I don't see what use case would require you to so (the purpose of websocket is to send notifications to clients), and be careful not to overload your server if you have too many clients. – John K Mar 09 '16 at 06:33