如何使用 F# 在 Akka.Remote 中发送带有元组的消息?
How to send a message with tuples in Akka.Remote with F#?
我正在尝试在 F# 中使用远程发送消息,但我一直遇到此问题,即永远不会发送具有某种类型的消息。当我使用下面给出的代码时:
Server.fsx
#r "nuget: Akka.FSharp"
#r "nuget: Akka.TestKit"
#r "nuget: Akka.Remote"
open System
open Akka.FSharp
open Akka.Remote
open Akka.Configuration
let configuration =
ConfigurationFactory.ParseString(
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
debug : {
receive : on
autoreceive : on
lifecycle : on
event-stream : on
unhandled : on
}
}
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()
printfn "%s" message
}
loop ()
let serveRef = spawn serversystem "server" server
Console.ReadLine() |> ignore
Client.fsx
#r "nuget: Akka.FSharp"
#r "nuget: Akka.TestKit"
#r "nuget: Akka.Remote"
open System
open Akka.FSharp
open Akka.Remote
open Akka.Configuration
let configuration =
ConfigurationFactory.ParseString(
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
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 <! "Register"
Console.ReadLine()
消息已发送,我可以看到服务器端打印了“Register”。但是当我尝试使用正在发送的特定类型的消息时出现问题。
服务器终端输出:
[INFO][12/1/2020 2:37:43 AM][Thread 0001][remoting (akka://Server)] Starting remoting
[INFO][12/1/2020 2:37:43 AM][Thread 0001][remoting (akka://Server)] Remoting started; listening on addresses : [akka.tcp://Server@192.168.0.94:9002]
[INFO][12/1/2020 2:37:43 AM][Thread 0001][remoting (akka://Server)] Remoting now listens on addresses: [akka.tcp://Server@192.168.0.94:9002]
Register
现在密码是
Server.fsx
#r "nuget: Akka.FSharp"
#r "nuget: Akka.TestKit"
#r "nuget: Akka.Remote"
#load "Message.fsx"
open Message
open System
open Akka.FSharp
open Akka.Remote
open Akka.Configuration
let configuration =
ConfigurationFactory.ParseString(
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
debug : {
receive : on
autoreceive : on
lifecycle : on
event-stream : on
unhandled : on
}
}
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) -> printfn "Got a number %d" num
}
loop ()
let serveRef = spawn serversystem "server" server
Console.ReadLine() |> ignore
Client.fsx
#r "nuget: Akka.FSharp"
#r "nuget: Akka.TestKit"
#r "nuget: Akka.Remote"
#load "Message.fsx"
open Message
open System
open Akka.FSharp
open Akka.Remote
open Akka.Configuration
let configuration =
ConfigurationFactory.ParseString(
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
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(10)
Console.ReadLine()
Message.fsx
type Message =
| Message of int
在这种情况下,消息永远不会打印出来。我们需要在发送前序列化消息吗?如果是,那么该怎么做?
否则,我做错了什么?
感谢任何帮助。
Akka 默认使用 Newtonsoft.Json,cannot roundtrip discriminated unions. You can switch to a different serializer (such as Akka.Serialization.Hyperion) or use e.g. Akkling,F# 优化的 Akka.FSharp 分支。
使用 Akkling 你的系统可能看起来像:
Message.fsx
#r "nuget: Akkling"
#r "nuget: Akka.Remote"
#r "nuget: Newtonsoft.Json"
type Message = Message of int
Server.fsx
#load "Message.fsx"
open Message
open System
open Akkling
let configuration =
Configuration.parse
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
debug : {
receive : on
autoreceive : on
lifecycle : on
event-stream : on
unhandled : on
}
}
remote {
helios.tcp {
port = 9002
hostname = localhost
}
}
}"
let serversystem = System.create "Server" configuration
let rec server = function
| Message(num) ->
printfn "Got a number %d" num
become server
let serveRef = spawn serversystem "server" <| props(actorOf server)
Console.ReadLine() |> ignore
Client.fsx
#load "Message.fsx"
open Message
open System
open Akkling
let configuration =
Configuration.parse
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
remote {
helios.tcp {
port = 2552
hostname = localhost
}
}
}"
let clientSystem = System.create "client" configuration
let serveRef = select clientSystem "akka.tcp://Server@localhost:9002/user/server"
serveRef <! Message(10)
Console.ReadLine()
我正在尝试在 F# 中使用远程发送消息,但我一直遇到此问题,即永远不会发送具有某种类型的消息。当我使用下面给出的代码时:
Server.fsx
#r "nuget: Akka.FSharp"
#r "nuget: Akka.TestKit"
#r "nuget: Akka.Remote"
open System
open Akka.FSharp
open Akka.Remote
open Akka.Configuration
let configuration =
ConfigurationFactory.ParseString(
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
debug : {
receive : on
autoreceive : on
lifecycle : on
event-stream : on
unhandled : on
}
}
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()
printfn "%s" message
}
loop ()
let serveRef = spawn serversystem "server" server
Console.ReadLine() |> ignore
Client.fsx
#r "nuget: Akka.FSharp"
#r "nuget: Akka.TestKit"
#r "nuget: Akka.Remote"
open System
open Akka.FSharp
open Akka.Remote
open Akka.Configuration
let configuration =
ConfigurationFactory.ParseString(
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
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 <! "Register"
Console.ReadLine()
消息已发送,我可以看到服务器端打印了“Register”。但是当我尝试使用正在发送的特定类型的消息时出现问题。
服务器终端输出:
[INFO][12/1/2020 2:37:43 AM][Thread 0001][remoting (akka://Server)] Starting remoting
[INFO][12/1/2020 2:37:43 AM][Thread 0001][remoting (akka://Server)] Remoting started; listening on addresses : [akka.tcp://Server@192.168.0.94:9002]
[INFO][12/1/2020 2:37:43 AM][Thread 0001][remoting (akka://Server)] Remoting now listens on addresses: [akka.tcp://Server@192.168.0.94:9002]
Register
现在密码是
Server.fsx
#r "nuget: Akka.FSharp"
#r "nuget: Akka.TestKit"
#r "nuget: Akka.Remote"
#load "Message.fsx"
open Message
open System
open Akka.FSharp
open Akka.Remote
open Akka.Configuration
let configuration =
ConfigurationFactory.ParseString(
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
debug : {
receive : on
autoreceive : on
lifecycle : on
event-stream : on
unhandled : on
}
}
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) -> printfn "Got a number %d" num
}
loop ()
let serveRef = spawn serversystem "server" server
Console.ReadLine() |> ignore
Client.fsx
#r "nuget: Akka.FSharp"
#r "nuget: Akka.TestKit"
#r "nuget: Akka.Remote"
#load "Message.fsx"
open Message
open System
open Akka.FSharp
open Akka.Remote
open Akka.Configuration
let configuration =
ConfigurationFactory.ParseString(
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
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(10)
Console.ReadLine()
Message.fsx
type Message =
| Message of int
在这种情况下,消息永远不会打印出来。我们需要在发送前序列化消息吗?如果是,那么该怎么做? 否则,我做错了什么? 感谢任何帮助。
Akka 默认使用 Newtonsoft.Json,cannot roundtrip discriminated unions. You can switch to a different serializer (such as Akka.Serialization.Hyperion) or use e.g. Akkling,F# 优化的 Akka.FSharp 分支。 使用 Akkling 你的系统可能看起来像:
Message.fsx
#r "nuget: Akkling"
#r "nuget: Akka.Remote"
#r "nuget: Newtonsoft.Json"
type Message = Message of int
Server.fsx
#load "Message.fsx"
open Message
open System
open Akkling
let configuration =
Configuration.parse
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
debug : {
receive : on
autoreceive : on
lifecycle : on
event-stream : on
unhandled : on
}
}
remote {
helios.tcp {
port = 9002
hostname = localhost
}
}
}"
let serversystem = System.create "Server" configuration
let rec server = function
| Message(num) ->
printfn "Got a number %d" num
become server
let serveRef = spawn serversystem "server" <| props(actorOf server)
Console.ReadLine() |> ignore
Client.fsx
#load "Message.fsx"
open Message
open System
open Akkling
let configuration =
Configuration.parse
@"akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
remote {
helios.tcp {
port = 2552
hostname = localhost
}
}
}"
let clientSystem = System.create "client" configuration
let serveRef = select clientSystem "akka.tcp://Server@localhost:9002/user/server"
serveRef <! Message(10)
Console.ReadLine()