設定
Akka (2.3.9) リモーティングの使用。
別のリモート バックエンド akka システムと通信する io.Tcp akka システムがあります。
問題は、リモートから送り返されたメッセージが tcp システムに届かないことです。
フロント ( Tcp ) システムは、接続が受信されると「フォロワー」クラスを登録します。
フォロワーはリモート バックエンド システムを (正常に) 識別し、受信したデータを転送します。
フォロワーからのスニペット:
def receive = {
case ActorIdentity(`identifyId`, Some(ref)) =>
log.error( "Identified successfully" )
context.watch(ref)
context.become(active(ref))
case ActorIdentity(`identifyId`, None) =>
log.error( "Failed to identify remote" )
context.stop(self)
}
def active(another: ActorRef): Actor.Receive = {
case Terminated(`another`) => context.stop(self)
case data: Received =>
log.debug( "Forwarding message" )
another forward data
case other : Any =>
log.warning( "Unexpected case :" + other.getClass )
}
リモート システムは、Received ケースをリッスンし、送信者に返信を書き込みます。
override def receive = ( {
case Received( data ) =>
sender() ! Write( processData( data ) )
case _ => log.debug( "Unexpected receive" )
} : PartialFunction[Any, Unit] ) orElse super.receive
問題
すべてが機能し、リモートの akka システムは受信したデータを正しく読み取り、処理しますが、結果を書き戻すときに自分自身をうんざりさせます。
EndpointWriter - AssociationError [akka.tcp://front-tcp@127.0.0.1:2553] -> [akka.tcp://backend@127.0.0.1:2552]: Error [akka.io.Tcp$Write; unable to create instance]
何がうまくいかないのですか?
アップデート:
リモートから Ack を返すようになりました (バックエンド システムで)
case object Ack extends Event
override def receive = ( {
case Received( data ) =>
sender() ! Write( processData( data ), Ack )
ここで、リモート アクター (このログの MyHandler ) はシリアル化できないと言われます。
java.io.NotSerializableException: handler.MyHandler
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183) ~[na:1.7.0_65]
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) ~[na:1.7.0_65]
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) ~[na:1.7.0_65]
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) ~[na:1.7.0_65]
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) ~[na:1.7.0_65]
MyHandler はアクターであるため、自動的にシリアライズ可能にすべきではありませんか?
更新 2
私は今、リモートへの「質問」の結果を待っています:
def active(another: ActorRef): Actor.Receive = {
case Terminated(`another`) => context.stop(self)
case Received( message ) =>
val futRemoteAnswer = ask( another, message ).mapTo[ Message ]
val result = Await.result( futRemoteAnswer, timeout.duration )
sender() ! Write( result )
case other : Any =>
log.warning( "Unexpected case :" + other.getClass )
}