本文介绍了播放Scala Akka WebSockets更改演员路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循了使用Scala Play和Akka演员创建Web套接字的示例:

I've followed the example for creating Web Sockets with Scala Play and Akka actors:

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个连接,并且创建的演员是:

The actors created (one per websocket connection) are child of /user actor. I've created 3 connections and the actor created were:

  1. /user/$ b
  2. /user/$ c
  3. /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:

  1. 创建文件BetterActorFlow.scala

  1. 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更改演员路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-20 00:49