1
votes

I want two actors to communicate. I have a local system (client) on my local machine and remote actor (server) on EC2. But I am unable to send a message from the client system to a remote actor.

testClient.fs

#if INTERACTIVE
#time "on"
#r "nuget: Akka.FSharp" 
#r "nuget: Akka.TestKit" 
#endif

open System
open Akka.Actor
open Akka.Configuration
open Akka.FSharp
open System.Collections.Generic

let configuration = 
                    ConfigurationFactory.ParseString(
                        @"akka {
                            actor {
                                provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
                            }
                            remote {
                             transport = ""akka.remote.netty.NettyRemoteTransport""
                             netty {
                               hostname = localhost
                               port = 0
                             }
                           }
                        }")

let system = ActorSystem.Create("System", configuration)

[<EntryPoint>]
let main args =               
    let remoteClient = system.ActorSelection(
                            "akka.tcp://[email protected]:2552/user/remoteActor")
    printfn "%A" remoteClient
    remoteClient <! "message from client"
    Console.ReadLine() |> ignore
    0

testServer.fs

#if INTERACTIVE
#time "on"
#r "nuget: Akka.FSharp" 
#r "nuget: Akka.TestKit" 
#endif
open System
open Akka.Actor
open Akka.Configuration
open Akka.FSharp
open System.Collections.Generic

let helper msg = printfn "hello from server : %A" msg

let configuration = 
                    ConfigurationFactory.ParseString(
                        @"akka {
                            actor {
                                provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
                            }
                            remote {
                             transport = ""akka.remote.netty.NettyRemoteTransport""
                             netty {
                               hostname = ""A.B.C.D""
                               port = 2552
                             }
                           }
                        }")

let remoteSystem = ActorSystem.Create("RemoteSystem", configuration)

let createActor (f : 'a -> unit) = actorOf f

[<EntryPoint>]
let main args =  
  let remoteActor = createActor helper |> spawn remoteSystem "remoteActor"
  Console.ReadLine() |> ignore
  0

First when I start my server and the run client which in turn lookup the remote actor and send a message. Then I get the follwing error in server on EC2.

[INFO][09/25/2020 19:20:07][Thread 0001][remoting (akka://RemoteSystem)] Starting remoting [INFO][09/25/2020 19:20:08][Thread 0001][remoting (akka://RemoteSystem)] Remoting started; listening on addresses : [akka.tcp://[email protected]:2552] [INFO][09/25/2020 19:20:08][Thread 0001][remoting (akka://RemoteSystem)] Remoting now listens on addresses: [akka.tcp://[email protected]:2552] [akka://RemoteSystem/user/remoteActor#1987516675] [ERROR][09/25/2020 19:20:23][Thread 0007][akka.tcp://[email protected]:2552/system/endpointManager/reliableEndpointWriter-akka.tcp%3A%2F%2FSystem%400.0.0.0%3A2552-1/endpointWriter] Dropping message [Akka.Actor.ActorSelectionMessage] for non-local recipient [[akka.tcp://[email protected]:2552/]] arriving at [akka.tcp://[email protected]:2552] inbound addresses [akka.tcp://[email protected]:2552]

output on client sie when i run it [INFO][9/25/2020 7:20:21 PM][Thread 0001][remoting (akka://System)] Starting remoting [INFO][9/25/2020 7:20:22 PM][Thread 0001][remoting (akka://System)] Remoting started; listening on addresses : [akka.tcp://[email protected]:2552] [INFO][9/25/2020 7:20:22 PM][Thread 0001][remoting (akka://System)] Remoting now listens on addresses: [akka.tcp://[email protected]:2552] ActorSelection[Anchor(akka.tcp://[email protected]:2552/), Path(/user/remoteActor)]

Then I searched a lot for this error and tried the following options in config file on server public-hostname = localhost, bind-hostname = ""A1.B1.C1.D1"" where ""A1.B1.C1.D1"" is private IP address of EC2 instance, bind-port = 2552

What might be the error? Any idea on how to fix it ? Thanks

1

1 Answers

0
votes

My guess is that this is due to NAT being involved. You need to tell Akka what your external / internal hostnames are :

https://doc.akka.io/docs/akka/current/remoting.html#akka-behind-nat-or-in-a-docker-container

If there is 2 NAT levels involved, it might need some extra trail-and-error.