Akka -在f#中无法发送歧视联合作为消息



Akka -区分联合作为f#

中的消息我不能使用歧视联合作为akka演员的消息。如果有人能给我指一个这样做的例子,我将不胜感激。

我自己的尝试是在git@github.com:Tweega/AkkaMessageIssue.git。(片段)。它是在https://github.com/rikace/AkkaActorModel.git(聊天项目)

找到的示例的精简版本。

问题DU消息永远不会在服务器参与者上找到它的目标,而是被发送到死信框。如果我发送object,它们就会到达。

如果我发送一个DU,但是设置我的服务器参与者监听泛型对象,消息确实到达,但是它的类型是

seq [seq [seq []]

和我不能得到底层的DU。

我试图作为消息发送的DU

type PrinterJob =
| PrintThis of string
| Teardown 
客户端代码
let system = System.create "MyClient" config
let chatClientActor =
spawn system "ChatClient" <| fun mailbox ->
let server = mailbox.Context.ActorSelection("akka.tcp://MyServer@localhost:8081/user/ChatServer")
let rec loop nick = actor {
let! (msg:PrinterJob) = mailbox.Receive()
server.Tell(msg)
return! loop nick
}
loop ""
while true do
let input = Console.ReadLine()        
chatClientActor.Tell(PrintThis(input))

消息从控制台输入转发到客户端

while true do
let input = Console.ReadLine()     
chatClientActor.Tell(PrintThis(input))
服务器代码
let system = System.create "MyServer" config
let chatServerActor =
spawn system "ChatServer" <| fun (mailbox:Actor<_>) ->
let rec loop (clients:Akka.Actor.IActorRef list) = actor {
let! (msg:PrinterJob) = mailbox.Receive()
printfn "Received %A" msg   //Received seq [seq [seq []]; seq [seq [seq []]]]  ???
match msg with                
| PrintThis str -> 
Console.WriteLine("Printing: {0} Do we get this?", str)
return! loop clients
| Teardown -> 
Console.WriteLine("Tearing down now")                        
return! loop clients                
}
loop []

的依赖关系(我在这里没有使用包)- PM命令如下:

  • Install-Package Akka -Version 1.4.23
  • 安装包Akka。Remote -Version 1.4.23
  • 安装包Akka。FSharp -Version 1.4.23

我在net5.0中托管应用程序

构造函数参数名称-奇怪吗?

当类实例作为对象传入时,akka似乎对构造函数参数的名称很敏感。消息得到处理,但数据不会从客户机复制到服务器。如果您有一个名为Username的属性,则构造函数参数不能为uName,否则当它到达服务器时其值为空。此代码在分支参数中。

type DoesWork(montelimar: string) =
member x.Montelimar = montelimar

type DoesNotWork(montelimaro: string) =
member x.Montelimar = montelimaro

我在Akka中打开了一个问题。. NET存储库:https://github.com/akkadotnet/akka.net/issues/5194

并添加了详细的复制:https://github.com/akkadotnet/akka.net/pull/5196

但是它看起来像Newtonsoft。如果没有类型提示,Json确实无法执行这种反序列化,而Akka。. NET的网络序列化默认情况下不会对JSON执行:

type TestUnion = 
| A of string
| B of int * string
type TestUnion2 = 
| C of string * TestUnion
| D of int

[<Fact(Skip="JSON.NET really does not support even basic DU serialization")>]
member _.``JSON.NET must serialize DUs`` () =
let du = C("a-11", B(11, "a-12"))
let settings = new JsonSerializerSettings()
settings.Converters.Add(new DiscriminatedUnionConverter())

let serialized = JsonConvert.SerializeObject(du, settings)
let deserialized = JsonConvert.DeserializeObject(serialized, settings)

Assert.Equal(du :> obj, deserialized)

这个测试不会通过,它不使用任何Akka。所以默认的JSON序列化器根本不适用于实际的f#用例。

我们可以尝试改变序列化系统的默认值以包含类型提示,但这将需要大量的验证测试(对于旧的Akka)。序列化的持久化数据(不需要)。

一个更好的解决方案,我的pull请求验证,是使用Hyperion多态序列化代替-它将类似地对你透明,但它有更强大的处理复杂类型比Newtonsoft。Json,实际上更快:https://getakka.net/articles/networking/serialization.html#how-to-setup-hyperion-as-default-serializer

最新更新