2016-04-22 2 views
1

Прежде всего, спасибо вам за то, что нашли время, чтобы просмотреть мою проблему. Я новичок в экосистеме scala, поэтому я думаю, что я не согласен с некоторыми понятиями.Play 2.4 создайте актера для ручки websocket с Guice

Я представляю Guice в проекте Play 2.4 и работает на некоторых контроллерах REST. Я редактировал build.sbt, добавляемых routesGenerator := InjectedRoutesGenerator как играть в официальных recomends DOC и редактировать мои маршруты, как вы можете видеть в следующем примере:

GET  /socket  @com.letgo.chat.controllers.ChatController.socket 

Мой модуль для инъекций актеров выглядит следующим образом:

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

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

И все это, кажется, работает.

Но другая конечная точка обрабатывает веб-карту с методом воспроизведения WebSocket.acceptWithActor. Мне нужно создать актера, который также нуждается в некоторых зависимостях.

Контроллер создает 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.

Я создал несколько актеров в других частях приложения, используя bindActorFactory метод, предоставленного AkkaGuiceSupport:

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") 
    } 

} 

Как вы можете видеть, что есть поставщик впрыскивается Guice, который имел WSClient впрыскивается и при создании актера, он проходит в зависимости

+0

спасибо roger! Я взгляну. – SergiGP

Смежные вопросы