我在Akka文档中读到,关闭来自封闭演员的变量是危险的.
警告
在这种情况下,您需要小心避免关闭包含actor的引用,即不要在匿名Actor类中调用封闭actor上的方法.这会打破actor封装,并可能引入同步错误和竞争条件,因为其他actor的代码将同时调度到封闭的actor.
现在,我有两个演员,其中一个从第二个请求某些东西并对结果做了一些事情.在下面的这个示例中,我放在一起,演员Accumulator从演员NumberGenerator中检索数字并将它们相加,并沿途报告总和.
这可以通过至少两种不同的方式完成,因为该示例显示具有两个不同的接收功能(A对B).两者之间的区别在于A不会关闭计数器变量; 相反,它等待一个整数并将其求和,而B创建一个关闭计数器并完成总和的Future.如果我正确理解这是如何工作的,那么这是在为处理onSuccess而创建的匿名actor中发生的.
import com.esotericsoftware.minlog.Log
import akka.actor.{Actor, Props}
import akka.pattern.{ask, pipe}
import akka.util.Timeout
import akka.util.duration._
case object Start
case object Request
object ActorTest {
var wake = 0
val accRef = Main.actorSystem.actorOf(Props[Accumulator], name = "accumulator")
val genRef = Main.actorSystem.actorOf(Props[NumberGenerator], name = "generator")
Log.info("ActorTest", "Starting !")
accRef ! Start
}
class Accumulator extends Actor {
var …Run Code Online (Sandbox Code Playgroud) 首先介绍一下上下文:我在Scala(第一人称射击游戏)中编写客户端/服务器游戏,其中客户端需要每秒向服务器发送几十次运动意图并且服务器将实体状态发送回来,实时也是如此.在客户端(用于图形流动性)和服务器端使用JBullet对这些实体进行物理模拟.每当客户端从服务器接收更新时,它都会将其本地状态替换为服务器发送的状态.当然,在给定时刻,同一服务器上可能有许多客户端.简而言之,在这种应用中,通信经常发生,带有小数据包.
目前,我正在使用Akka的演员天真地通过网络将Scala案例类发送到服务器并返回.这是一个例子:
sealed trait PlayerMessage
case class PlayerMove(dir: Vector3, run: Boolean) extends PlayerMessage
// more case classes...
Run Code Online (Sandbox Code Playgroud)
然后在客户端:
server ! PlayerMove(dir, run)
Run Code Online (Sandbox Code Playgroud)
在服务器上:
def receive = {
case pm: PlayerMessage => pm match {
case p @ PlayerMove(dir, run) =>
// Move the player
world.playerMove(dir,run)
// More case tests..
}
// Send back entity states (this in fact occurs elsewhere, asynchronously)
world.entities.foreach(ent => client ! ent.state()))
// More message testing ...
case _ => // ignore
}
Run Code Online (Sandbox Code Playgroud)
ent.state返回EntityState的位置:
case class …Run Code Online (Sandbox Code Playgroud) Scala REPL中是否有一种方法可以设置"活动"包范围?说我有一个package com.package用class A,我希望能够输入new A(),而不是new com.package.A()不明确做import com.package.A.在我感兴趣的包中可能有许多其他类,我不想通过这样做来判断我的REPL的全局命名空间import com.package._.
更好的是,我想在不输入完全限定名的情况下定义 A类.就像是:
package com.package // do this once
class A
class B
val a = new A()
val b = new B()
Run Code Online (Sandbox Code Playgroud)
我知道:paste -raw命令,但这需要我package com.package为每个块输入; 我真的在寻找一个有状态的命令来改变"当前的工作包",如果你愿意的话.
Arduino 兼容设备在我的计算机上枚举为虚拟 COM 端口,但stty报告错误并且cat未从中接收任何内容。
~$ ls -al /dev/ttyS14
crw-rw-rw- 1 user.name None 117, 14 Feb 15 16:26 /dev/ttyS14
~$ stty.exe -F /dev/ttyS14 57600 cs8
stty: /dev/ttyS14: Invalid argument
Run Code Online (Sandbox Code Playgroud)
现在,使用 Putty 打开端口 (COM15) 效果很好。关闭Putty后,stty按预期工作,没有报错:
~$ stty.exe -F /dev/ttyS14 57600 cs8
Run Code Online (Sandbox Code Playgroud)
cat现在从端口接收数据也是如此。想必 Putty 知道如何在 Windows/Cygwin 下正确初始化这些端口。
我正在尝试自动化我的工作流程,但这个手动步骤阻止了我这样做。
任何想法 ?
我有一个Scala/Java OpenGL应用程序,我在其中使用Akka框架.目前,我的OpenGL线程独立于actor系统,因此我可以保证对OpenGL函数的调用始终来自单个线程.这很重要,否则OpenGL会抱怨.
到目前为止,我不得不将OpenGL线程中的消息发送给系统中的actor,这非常有效.我现在面临着以相反的方式发送消息的需要,但当然我不能简单地将OpenGL放在一个actor中,因为这将打破它从单个线程运行的要求.
另一种方法是手动使用队列和锁来进行actor和OpenGL线程之间的通信,但是我想知道是否有办法将OpenGL调用放在一个特殊的Actor中,Akka将给予它一个保证.在单个线程中运行.
问候
Akka Scala actor必须扩展akka.actor.Actor
Akka Java actor必须扩展akka.actor.UntypedActor
因此,在使用非默认构造函数定义Scala actor并从Java代码创建它时,我遇到了这个问题:
ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new MyActor("...");
}
}), "myactor");
Run Code Online (Sandbox Code Playgroud)
当然,UntypedActorFactory期望创建一个UntypedActor类型的对象,但我的actor是Actor类型.
解决方法是什么?
编辑:
按照Viktor的指示使用akka.japi.Creator,这有效:
Props props1 = new Props();
Props props2 = props1.withCreator(new akka.japi.Creator() {
public Actor create() {
return new MyActor("...");
}
});
ActorRef actorRef = Main.appClient().actorOf(props2, "myactor");
Run Code Online (Sandbox Code Playgroud) 对于下面选项[实体]的匹配,第三种情况需要详尽无遗.为什么?
entitiesMap是一个包含不可变Map [UUID,Entity]的var.它在一个Akka Actor中被访问和更新,以避免线程问题.以下是接收函数的摘录:
class WorldActor extends Actor {
var world: World = null
override def receive = {
case WorldSet(w) =>
world = w
// get that state and apply it to its entity
case s: State if (world != null) =>
val uuid = new UUID(s.getUuid().getL1(), s.getUuid().getL2())
world.entitiesMap.get(uuid) match {
case Some(ent) =>
// Update entity's state
ent.setEntityState(s)
case None =>
Log.error("World doesn't contain entity uuid: " + uuid) …Run Code Online (Sandbox Code Playgroud)