问题描述
我遵循了使用Scala Play和Akka演员创建Web套接字的示例:
I've followed the example for creating Web Sockets with Scala Play and Akka actors:
在恢复时,控制器:
import play.api.mvc._
import play.api.libs.streams._
class Controller1 @Inject() (implicit system: ActorSystem, materializer: Materializer) {
def socket = WebSocket.accept[String, String] { request =>
ActorFlow.actorRef(out => MyWebSocketActor.props(out))
}
还有演员:
import akka.actor._
object MyWebSocketActor {
def props(out: ActorRef) = Props(new MyWebSocketActor(out))
}
class MyWebSocketActor(out: ActorRef) extends Actor {
def receive = {
case msg: String =>
out ! ("I received your message: " + msg)
}
}
创建的actor(每个websocket连接一个)是/user actor的子级.我已经创建了3个连接,并且创建的演员是:
The actors created (one per websocket connection) are child of /user actor. I've created 3 connections and the actor created were:
- /user/$ b
- /user/$ c
- /user/$ d
我想基于Web套接字消息的字段更改演员的姓名.我该怎么办?.
I want to change the actors' name based in a field of the web socket message. How could i do this?.
推荐答案
您可以如下设置参与者的名称:
You can set the name of the actor as follows:
-
创建文件BetterActorFlow.scala
Create a file BetterActorFlow.scala
package your.package
import akka.actor._
import akka.stream.scaladsl.{Keep, Sink, Source, Flow}
import akka.stream.{Materializer, OverflowStrategy}
object BetterActorFlow {
def actorRef[In, Out](props: ActorRef => Props, bufferSize: Int = 16, overflowStrategy: OverflowStrategy = OverflowStrategy.dropNew, maybeName: Option[String] = None)(implicit factory: ActorRefFactory, mat: Materializer): Flow[In, Out, _] = {
val (outActor, publisher) = Source.actorRef[Out](bufferSize, overflowStrategy)
.toMat(Sink.asPublisher(false))(Keep.both).run()
def flowActorProps: Props = {
Props(new Actor {
val flowActor = context.watch(context.actorOf(props(outActor), "flowActor"))
def receive = {
case Status.Success(_) | Status.Failure(_) => flowActor ! PoisonPill
case Terminated(_) => context.stop(self)
case other => flowActor ! other
}
override def supervisorStrategy = OneForOneStrategy() { case _ => SupervisorStrategy.Stop }
})
}
def actorRefForSink =
maybeName.fold(factory.actorOf(flowActorProps)) { name => factory.actorOf(flowActorProps, name) }
Flow.fromSinkAndSource(Sink.actorRef(actorRefForSink, Status.Success(())), Source.fromPublisher(publisher))
}
}
使用BetterActorFlow代替ActorFlow:
Use BetterActorFlow instead of ActorFlow:
BetterActorFlow.actorRef(out =>
ChatActor.props(out), 16, OverflowStrategy.dropNew, Some("alicebob"))
这对我有用.创建的actor位于user/alicebob
(与context.system.actorSelection("user/alicebob")
结合使用)
This worked for me. The created actor is at user/alicebob
(use this with context.system.actorSelection("user/alicebob")
)
这篇关于播放Scala Akka WebSockets更改演员路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!