[2.4.0][DI] How to start a websocket tied to an Actor with injected dependencies

207 views
Skip to first unread message

Julien L.

unread,
Jun 14, 2015, 8:38:52 AM6/14/15
to play-fr...@googlegroups.com
Hello everyone!

I'm trying to write an application that correctly uses the new DI system.

I've read everything available about Runtime DI and injecting actors, but I have the impression that Play lacks a key component to make `websocket.acceptWithActor` working with DI.

* Creating a Websocket tied to an actor is done with `def acceptWithActor[In, Out](f: RequestHeader => HandlerProps)` who expects an `type HandlerProps = ActorRef => Props`. Play will create a new actor from this props for each incoming connection.
* On the other part, creating an injected Actor required an actor factory binded with `bindActorFactory`.

These 2 approachs are not compatible together.

For what I know, It's currently not possible to use injected dependencies in this actor, and I don't found any workaround to achieve this. 

But maybe I'm wrong? Do you know a way to bind a websocket to an actor allowing dependencies injection?

James Roper

unread,
Jun 15, 2015, 1:19:27 AM6/15/15
to play-framework
The helpers that Play provides for dependency injecting actors are suited for a limited number of use cases.  Though, the helpers are really just very thin wrappers over some common requirements - they're not needed at all.  In the case Play's WebSocket actor support, the thing is, generally you want to manually instantiate the actor since you have to somehow pass it the out ActorRef.  So, you can either do this using Guice assisted inject, and define a factor interface that takes the out actor ref (and whatever other arguments you want to pass to it), or simply instantiate it manually, passing dependencies from the controller to the actor, for example:

import javax.inject._

class MyController @Inject() (myDep: MyDep) extends Controller {
  def socket = WebSocket.acceptWithActor[String, String] { request => out =>
    MyWebSocketActor.props(out, myDep)
  }
}



--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/d292a5ef-3e00-404d-9fea-c5b11e94eed4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
James Roper
Software Engineer

Typesafe – Build reactive apps!
Twitter: @jroper

max square

unread,
Jun 18, 2015, 11:06:38 PM6/18/15
to play-fr...@googlegroups.com
Thanks, was stuck on this for a couple of days.
Manually injecting for now, will try and make the Guice factory method work.

Max

Julien L.

unread,
Jun 19, 2015, 3:17:22 AM6/19/15
to play-fr...@googlegroups.com
Thanks James for this explanation.

I've used this solution and it's works fine.

Erik Frister

unread,
Jul 25, 2016, 3:13:10 PM7/25/16
to play-framework
Hi James

I adapted the "official" (?) implementation of https://github.com/playframework/play-websocket-scala using Akka Streams to handle WebSockets. While I got it to work, I found it quite a lot of lines of code to do what you are doing with WebSocket.acceptWithActor

Are there any real benefits of using the Akka Stream approach to handling the WebSocket, compared to using WebSocket.acceptWithActor? I've been thinking about whether or not I have any tangible benefits for the overhead.

Thanks!
Reply all
Reply to author
Forward
0 new messages