2016-04-22 58 views
1

首先感謝大家抽出一些時間來審查我的問題。我是scala生態系統的新手,所以我覺得我正在說一些概念。播放2.4創建一個演員處理websocket與Guice

我在Play 2.4項目中介紹了Guice,它在一些REST控制器中工作。我已經編輯build.sbt追加routesGenerator := InjectedRoutesGenerator作爲播放官方文檔recomends和編輯我的路線,你可以在下面的例子中看到:

​​

我注射演員模塊的樣子:

class ChatModule extends AbstractModule with ScalaModule with AkkaGuiceSupport with GuiceAkkaActorRefProvider { 
    override def configure() { 

    bindActor[TalkerProviderActor](TalkerProviderActor.name) 
    ... 

而這一切似乎都在起作用。

但另一個端點使用Play方法WebSocket.acceptWithActor處理websocket。我需要創建一個也需要一些依賴關係的actor。

控制器創建一個ConnectionActor

class ConnectionActor(
    @Assisted() websocket: ActorRef, 
    monitoring: Monitoring, 
    @Named(BouncerActor.name) bouncer: ActorRef, 
) extends Actor 

... 

class ChatController @Inject() extends Controller { 
    def socket(): WebSocket[String, JsValue] = WebSocket.acceptWithActor[String, JsValue] { request => out => 
    // I had the following statement in order to build the actor before introducing Guice: 
    // ConnectionActor.props() 
    // Now, I need some magic here 
    } 
} 

因此,大家可以看到我需要一個websocket: ActorRef對於WebSocket的輸出。

我使用AkkaGuiceSupport提供bindActorFactory方法創建應用程序的其他部分有的演員:

bindActorFactory[TalkerActor, TalkerActor.Factory] 

但我不知道我應該如何在這個辦案WebSocket的創建一個演員。你們能幫我嗎?

謝謝

回答

3

我相信這可以做的伎倆:

package controllers 

import javax.inject._ 

import akka.actor.{Actor, ActorRef, ActorSystem, Props} 
import akka.stream.Materializer 
import play.api.libs.streams.ActorFlow 
import play.api.libs.ws.WSClient 
import play.api.mvc._ 

import scala.concurrent.ExecutionContext.Implicits.global 

@Singleton 
class SocketActorProvider @Inject() (ws: WSClient) { 
    def get(out: ActorRef) = Props(new SocketActor(out, ws)) 
} 

class SocketActor(out: ActorRef, ws: WSClient) extends Actor { 
    override def receive: Receive = { 
    case "ping" => ws.url("http://localhost:9000/pong").get().foreach(pong => out ! pong.body) 
    } 
} 

@Singleton 
class HomeController @Inject() (implicit system: ActorSystem, ws: WSClient, materializer: Materializer, provider: SocketActorProvider) extends Controller { 

    // route '/ws' 
    def socket = WebSocket.accept[String, String] { request => 
    ActorFlow.actorRef(out => provider.get(out)) 
    } 

    // route '/pong' 
    def pong = Action { 
    Ok("PONG!") 
    } 

    // route '/' 
    def index = Action { 
    Ok(""" 
     <script> 
     var ws = new WebSocket('ws://localhost:9000/ws'); 
     ws.onopen =() => console.log('I am open!'); 
     ws.onmessage = m => console.log(m.data); 

     setInterval(() => {console.log('ping'); ws.send('ping')}, 1000) 
     </script> 
    """).as("text/html") 
    } 

} 

正如你可以看到有由吉斯其中有WSClient注入和建設一個演員,當它通過在依賴注入的供應商

+0

謝謝羅傑!我會看一看。 – SergiGP