加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

玩Scala Akka WebSockets改变演员路径

发布时间:2020-12-16 10:05:29 所属栏目:安全 来源:网络整理
导读:我已经按照使用 Scala Play和Akka actor创建Web套接字的示例: https://www.playframework.com/documentation/2.5.x/ScalaWebSockets#Handling-WebSockets-with-Akka-Streams-and-actors 在恢复时,控制器: import play.api.mvc._import play.api.libs.strea
我已经按照使用 Scala Play和Akka actor创建Web套接字的示例:

https://www.playframework.com/documentation/2.5.x/ScalaWebSockets#Handling-WebSockets-with-Akka-Streams-and-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个连接,创建的actor是:

> / user / $b
> / user / $c
> / user / $d

我想基于Web套接字消息的字段更改actor的名称.我怎么能这样做?

解决方法

您可以按如下方式设置actor的名称:

>创建一个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:

BetterActorFlow.actorRef(out =>
  ChatActor.props(out),16,OverflowStrategy.dropNew,Some("alicebob"))

这对我有用.创建的actor位于user / alicebob(使用context.system.actorSelection(“user / alicebob”))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读