Akka.Удаленная сериализация F # работает только с первым полем дискриминируемого объединения

#f# #akka #akka.net #f#-interactive

#f# #akka #akka.net #f # -интерактивный

Вопрос:

Чтобы отправить дискриминируемое поле объединения удаленному субъекту, я использую Hyperion в качестве сериализатора, но, похоже, он сериализует только первое поле, но не сериализует остальную часть объединения. Пример кода выглядит следующим образом:

Server.fsx

 #r "nuget: Akka.FSharp" 
#r "nuget: Akka.TestKit"
#r "nuget: Akka.Remote"
#r "nuget: Akka.Serialization.Hyperion"
#load "Message.fsx"

open Message
open System
open Akka.FSharp
open Akka.Remote
open Akka.Configuration
open Akka.Serialization
let configuration = 
    ConfigurationFactory.ParseString(
        @"akka {
            actor {
                provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
                debug : {
                    receive : on
                    autoreceive : on
                    lifecycle : on
                    event-stream : on
                    unhandled : on
                }
                serializers {
                    hyperion = ""Akka.Serialization.HyperionSerializer, Akka.Serialization.Hyperion""
                }
                serialization-bindings {
                    ""System.Object"" = hyperion
                }                
            }
            remote {
                helios.tcp {
                    port = 9002
                    hostname = 192.168.0.94
                }
            }
        }")

let serversystem = System.create "Server" configuration



let server (mailbox:Actor<_>) =
    let rec loop () = actor {
        let! message = mailbox.Receive()
        match message with
        | Message(num, num1, str) -> printfn "Got a number %d %d %s" num num1 str
        | CreateDone(num, num1, str) -> printfn "Got a create %d %d %s" num num1 str
    }
    loop ()

let serveRef = spawn serversystem "server" server
Console.ReadLine() |> ignore
 

Client.fsx

 #r "nuget: Akka.FSharp" 
#r "nuget: Akka.TestKit"
#r "nuget: Akka.Remote"
#r "nuget: Akka.Serialization.Hyperion"
#load "Message.fsx"

open Message
open System
open Akka.FSharp
open Akka.Remote
open Akka.Configuration
open Akka.Serialization

let configuration = 
    ConfigurationFactory.ParseString(
        @"akka {
            actor {
                provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
                serializers {
                    hyperion = ""Akka.Serialization.HyperionSerializer, Akka.Serialization.Hyperion""
                }
                serialization-bindings {
                    ""System.Object"" = hyperion
                }               
            }
            remote {
                helios.tcp {
                    port = 2552
                    hostname = localhost
                }
            }
        }")

let clientSystem = System.create "client" configuration

let serveRef = select ("akka.tcp://Server@192.168.0.94:9002/user/server") clientSystem
serveRef <! Message(10L, 20, "Hello")
serveRef <! CreateDone(10L, 20, "Hi")
Console.ReadLine()
 

Message.fsx

 type Message = Message of int64 * int * string
              | CreateDone of int64 * int * string
 

Вывод сервера:

 F:UFCoursesFALL2020DOSProjectsProject4.1>dotnet fsi --langversion:preview serve.fsx
[INFO][12/2/2020 1:42:13 AM][Thread 0001][remoting (akka://Server)] Starting remoting
[INFO][12/2/2020 1:42:13 AM][Thread 0001][remoting (akka://Server)] Remoting started; listening on addresses : [akka.tcp://Server@192.168.0.94:9002]
[INFO][12/2/2020 1:42:13 AM][Thread 0001][remoting (akka://Server)] Remoting now listens on addresses: [akka.tcp://Server@192.168.0.94:9002]
Got a number 10 20 Hello

 

Таким образом, похоже, что только первое поле сериализуется в дискриминируемом объединении. Как это преодолеть?

Комментарии:

1. Я вижу, вы используете helios.tcp, но я использую dot-netty.tcp. Хорошо работает уже много лет.

Ответ №1:

Ваш актер не выполняет цикл, поэтому завершается после первого сообщения

Добавьте

 return! loop()
 

внутри вашего рекурсивного цикла.

Я думаю, что вопрос немного сбивает с толку. В нем указано, что 1-е поле напечатано, но все поля присутствуют в выводе на печать. Я полагаю, вы имеете в виду только первое сообщение

Akka в примерах c # не нуждается в цикле, но Akka.fsharp соответствует синтаксису MailboxProxessor, поэтому требует явного цикла.

Комментарии:

1. Я чувствую себя очень плохо, так как пропустил это при редактировании:-(