spray-websocket icon indicating copy to clipboard operation
spray-websocket copied to clipboard

Sending messages to particular WS sessions

Open dbousamra opened this issue 10 years ago • 0 comments

Great library, thank you.

I need the ability to, from an outside source (perhaps HTTP, or some RPC call), given an ID that matches with the session, send a message to the WebSocketServerWorker actor. This is quite similar to this issue: https://github.com/wandoulabs/spray-websocket/issues/62

I see two obvious ways of accomplishing this:

  1. Upon connection, when the HttpRequest comes in, we disect the request, perform auth etc, and create the actor with it's name set to whatever session ID we decide. We could then lookup an actor via it's path, and send it messages. This has proved impossible so far. Here is my sample code:
class WebSocketHttpServer extends Actor with ActorLogging {
  def receive = {
    case Http.Connected(remoteAddress, localAddress) => {
      val conn = context.actorOf(Props(classOf[WebSocketSessionWorker], client))
      sender ! Http.Register(conn)
    }
  }

which I modified to become:

class WebSocketHttpServer extends Actor with ActorLogging {
  def receive = {
    case request: HttpRequest =>
      val client = sender
      // disect the request and create a session ID we can associate with
      val conn = context.actorOf(Props(classOf[WebSocketSessionWorker], client), name = "ABC")
      conn ! request

    case Http.Connected(remoteAddress, localAddress) => {
      self ! Http.Register(self)
    }
  }

The issue is that when the request is forwarded to the WebSocketSessionWorker, when it executes the Handshake, it sends the UpgradeServer message BACK to the WebSocketHttpServer, not the WebSocketSessionWorker. Not sure why. Gave up.

Edit: I have solved this issue. i didn't know about the forward method on ActorRefs. Retains the sender reference correctly.

  1. The second approach would be to construct WebSocketSessionWorker's with some sort of ActorCommunication actor, that it then registers with (and inside this ActorCommunication actor). Communication would then go through this actor, as it would maintain state around all WebSocket sessions currently going on.

    Thoughts?

dbousamra avatar Nov 10 '15 04:11 dbousamra