{"id":4680,"date":"2017-03-17T21:21:02","date_gmt":"2017-03-17T21:21:02","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=4680"},"modified":"2017-03-17T21:21:02","modified_gmt":"2017-03-17T21:21:02","slug":"proto-actor-remoting","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/proto-actor-remoting\/","title":{"rendered":"Proto.Actor Remoting"},"content":{"rendered":"<p>I&#8217;m now going to take a look at what&#8217;s required to implement a remote Proto.Actor and a &#8220;client&#8221; to interact with it. I&#8217;m going to stick to the standard Greet class, as shown in my previous post, but we&#8217;re going to generate the Greet class from a .proto (protocol buffers) definition file.<\/p>\n<p>So before we get into the client\/server code, let&#8217;s create the Greet.proto file, here&#8217;s it is<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nsyntax = &quot;proto3&quot;;\r\n\r\npackage messages;\r\noption csharp_namespace = &quot;Messages&quot;;\r\n\r\nmessage Greet {\r\n   string Who = 1;\r\n}\r\n<\/pre>\n<p>The Greet message will generate a Greet type with a property name Who. So once you&#8217;ve created this file, you&#8217;ll need to use protoc.exe with the following command line<\/p>\n<p>protoc.exe &#8211;csharp_out=. Greet.proto<\/p>\n<p>This will generate the Greet.cs file, which I will not bother to show here.<\/p>\n<p>Next up, we&#8217;ll reuse our GreetActor class from the previous post, recreated below<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class GreetingActor : IActor\r\n{\r\n   public Task ReceiveAsync(IContext context)\r\n   {\r\n      var greet = context.Message as Greet;\r\n      if (greet != null)\r\n      {\r\n         Console.WriteLine(&quot;&#x5B;Thread {0}] Greeting {1}&quot;,\r\n            Thread.CurrentThread.ManagedThreadId,\r\n            greet.Who);\r\n      }\r\n      return Actor.Done;\r\n   }\r\n}\r\n<\/pre>\n<p>As we know, strictly speaking Akka.net and also Proto.Actor do not adhere to a client\/server architecture but remote objects are created in a peer to peer architecture. For the sake of this post we will create two separate projects, one named Server the other Client, just for simplicity.<\/p>\n<p><strong>Creating our server<\/strong><\/p>\n<ul>\n<li>Create a Console application, named something like ProtoActorServer<\/li>\n<li>Using Nuget add the Proto.Actor and Proto.Remote packages<\/li>\n<li>Add or link to the Greet.cs file generated by protoc<\/li>\n<li>Add or link to the GreetActor.cs file from above<\/li>\n<li>In Program.cs add the following using clauses\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing Messages;\r\nusing Proto;\r\nusing Proto.Remote;\r\n<\/pre>\n<\/li>\n<li>In the Main method add the following code\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nSerialization.RegisterFileDescriptor(GreetReflection.Descriptor);\r\nRemotingSystem.Start(&quot;127.0.0.1&quot;, 12000);\r\n\r\nvar props = Actor.FromProducer(() =&gt; new GreetingActor());\r\nActor.SpawnNamed(props, &quot;remote&quot;);\r\n\r\n\/\/ just to keep the app. open\r\nConsole.ReadLine();\r\n<\/pre>\n<\/li>\n<\/ul>\n<p><strong>Creating our client<\/strong><\/p>\n<p>As we know, this is going to basically be very similar to the server is set-up, but there are differences in the code, but I&#8217;ll still list all the steps for completeness<\/p>\n<ul>\n<li>Create a Console application, named something like ProtoActorClient<\/li>\n<li>Using Nuget add the Proto.Actor and Proto.Remote packages<\/li>\n<li>Add or link to the Greet.cs file generated by protoc<\/li>\n<li>Add or link to the GreetActor.cs file from above<\/li>\n<li>In Program.cs add the following using clauses\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing Messages;\r\nusing Proto;\r\nusing Proto.Remote;\r\n<\/pre>\n<\/li>\n<li>In the Main method add the following code\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nSerialization.RegisterFileDescriptor(GreetReflection.Descriptor);\r\nRemotingSystem.Start(&quot;127.0.0.1&quot;, 12001);\r\n\r\nvar remote = new PID(&quot;127.0.0.1:12000&quot;, &quot;remote&quot;);\r\nremote.Tell(new Greet { Who = &quot;Hello World&quot; });;\r\n\r\n\/\/ just to keep the app. open\r\nConsole.ReadLine();\r\n<\/pre>\n<\/li>\n<\/ul>\n<p>If you now run the ProtoActorServer and then the ProtoActorClient you should see the <em>Greeting Hello World<\/em> message displayed on the server console via it&#8217;s GreetingActor.<\/p>\n<p><strong>Disclaimer<\/strong><\/p>\n<p>At the time of writing this I&#8217;ve not yet seen documentation to suggest I&#8217;m doing everything 100% by the Proto.Actor book, so to speak, I&#8217;ve based this code on previous use of protobuf and Akka.net as well as a couple of examples from the Proto.Actor git repos. If I find I&#8217;m doing anything incorrectly, I will update this page.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m now going to take a look at what&#8217;s required to implement a remote Proto.Actor and a &#8220;client&#8221; to interact with it. I&#8217;m going to stick to the standard Greet class, as shown in my previous post, but we&#8217;re going to generate the Greet class from a .proto (protocol buffers) definition file. So before we [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[156,159],"tags":[],"class_list":["post-4680","post","type-post","status-publish","format-standard","hentry","category-actor-model","category-proto-actor"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4680","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=4680"}],"version-history":[{"count":4,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4680\/revisions"}],"predecessor-version":[{"id":4687,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4680\/revisions\/4687"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=4680"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=4680"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=4680"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}