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