<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: erikest</title>
    <description>The latest articles on DEV Community by erikest (@erikest).</description>
    <link>https://dev.to/erikest</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F152970%2F81037d6e-fdfb-4c39-99b1-c61b07b3cf07.jpg</url>
      <title>DEV Community: erikest</title>
      <link>https://dev.to/erikest</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/erikest"/>
    <language>en</language>
    <item>
      <title>I'm a new dev blogger - I can has your tools?</title>
      <dc:creator>erikest</dc:creator>
      <pubDate>Mon, 15 Apr 2019 17:19:49 +0000</pubDate>
      <link>https://dev.to/erikest/i-m-a-new-dev-blogger-i-can-has-your-tools-1mkm</link>
      <guid>https://dev.to/erikest/i-m-a-new-dev-blogger-i-can-has-your-tools-1mkm</guid>
      <description>&lt;p&gt;As a new dev blogger, my tool box is a little, er, &lt;em&gt;sparse&lt;/em&gt;.  I've been learning markdown, which is nice for formatting, but then I see other people's beautiful looking posts and I think - I want their tools, their methods, their flare.  As part of my ascent into blogging nirvana, I thought I'd spark a discussion and see what others think.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Screenshots&lt;/strong&gt; - I've seen images that blur all but the important stuff, others that highlight/number the relevant clicks and inputs, etc.  In my StackOverflow posts, I've used... Paint...  Probably time to upgrade, what would you suggest?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code examples&lt;/strong&gt; - There's the gist thing from github which I haven't explored, things like codepen and jsfiddle for web stuff.  Of course I can &lt;code&gt;\&lt;/code&gt;`&amp;lt;language&amp;gt; in markdown - what else?  Any pro tips?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Productivity boosters&lt;/strong&gt; - are you composing your markdown in the dev.to editor or is there a better way? Live previews? Templates?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Other 'nice to haves'&lt;/strong&gt; - Any other wizzbang I should consider to make my posts POP?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>discuss</category>
      <category>beginners</category>
      <category>writing</category>
      <category>tips</category>
    </item>
    <item>
      <title>GitStub - a GitHub-first development boostrapper for dotnet core</title>
      <dc:creator>erikest</dc:creator>
      <pubDate>Mon, 15 Apr 2019 16:50:09 +0000</pubDate>
      <link>https://dev.to/erikest/gitstub-a-github-first-development-boostrapper-for-dotnet-core-1i5f</link>
      <guid>https://dev.to/erikest/gitstub-a-github-first-development-boostrapper-for-dotnet-core-1i5f</guid>
      <description>&lt;h3&gt;
  
  
  tl;dr
&lt;/h3&gt;

&lt;p&gt;My first foray into my own open source project is a tool to lower the barrier to getting code up onto GitHub.  I created it because I wanted to start a different open source project and in the process of learning what to do, realized that there are a number of repetitive steps.  At first, I sought to create myself a set of scripts that would ease the process by interacting with the GitHub rest api and the dotnet core cli.  Soon, I realized that taking these steps and creating a cross platform dotnet core global tool would both be better in terms of ease of use and also allow me to share this with the widest audience - hopefully saving someone else some time and tedium.&lt;/p&gt;

&lt;p&gt;You can install it and try it yourself with&lt;br&gt;
&lt;code&gt;dotnet tool install --global gitstub&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For issues, requests and ideas to make it better&lt;br&gt;
&lt;a href="https://github.com/erikest/gitstub"&gt;GitStub on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;You want to create a new dotnet core project so you&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir  &lt;/span&gt;MyKillerWebApp
&lt;span class="nb"&gt;cd &lt;/span&gt;MyKillerWebApp
dotnet new webapp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Actually, it needs a solution and a little rearranging you decide&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p src/MyKillerWebApp
mv * src/MyKillerWebApp
dotnet sln -n MyKillerWebApp

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then you want to put it into a git repository, but first you need to find a &lt;code&gt;.gitignore&lt;/code&gt; to add - maybe you have one you used before in another project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; /users/myuser/repos/someotherdotnetproject/.gitignore ./
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now you can set up your first commit&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
git add &lt;span class="nt"&gt;-A&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"First Commit! The only way is up from here!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;At some point you realize, it should actually be a GitHub project, because you want to share this killer webapp with the world.  From here, you go to your browser and GitHub.com, you log in, create a new project, filling out the details.&lt;/p&gt;

&lt;p&gt;A few minutes later, the GitHub project is there, but it and your local git are not connected so you still have to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote add origin https://user:pass@github.com/user/projectName.git
git push &lt;span class="nt"&gt;--set-upstream&lt;/span&gt; origin master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally, you've got everything on GitHub and you can iterate from there.&lt;/p&gt;

&lt;p&gt;Or maybe you stop somewhere before that, before even creating the local git repo.  You tell yourself, "once it is 'worth it'" you'll take those steps and make a GitHub project.  Then maybe you do, maybe you don't.  Perhaps you get second thoughts - what if my code isn't 'good enough' yet.  Sometimes though, code that is good enough or would be good enough just stays on your laptop, where it dies.  Or another time, away from your machine, you are with another dev and you think - "Oh! I started working on something like this - but, ack, it's on &lt;em&gt;my&lt;/em&gt; machine, so I'll have to go create a GitHub project and push it up for &lt;em&gt;you&lt;/em&gt; to see it... maybe when I get back to my computer."  Or maybe it's not that big of a barrier and you do go through those steps every time - but wouldn't it be nice if it was just a little faster, a little easier?&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution - GitHub-first development with GitStub
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;goals&lt;/strong&gt; of this project are two fold.  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Save time&lt;/strong&gt; - simply put, these are repetitive tasks, they are begging for automation.&lt;/li&gt;
&lt;li&gt;Promote a development paradigm where you start projects, public or private, on GitHub and commit right away - &lt;strong&gt;GitHub-first&lt;/strong&gt;.

&lt;ul&gt;
&lt;li&gt;This not only makes the code immediately available everywhere, it also facilitates your progress in open source by having the initiation of the project start the cycle of contributions.  You get to overcome your fear and perfectionism and replace it with continual public improvement as a feature of your dev life.
&lt;/li&gt;
&lt;li&gt;By combining that with dotnet new project templates, you get a bootstrapped, scaffolded project up and ready to be iterated.  The first commit is the template, outta the box.  Your second commit will contain all the deltas between the base template and what value you've added thus far - and away ye go!&lt;/li&gt;
&lt;li&gt;Hopefully, it takes one small barrier out of the way that might stop you, on the margin, from trying something and putting it on GitHub because you "can't be bothered" to set up the project and connect everything.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How To Use
&lt;/h2&gt;

&lt;p&gt;First, install the tool using&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet tool install --global gitstub&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, suppose I want to start a new console application in a folder called &lt;code&gt;MyKillerApp&lt;/code&gt;.&lt;br&gt;
From the command line in the that folder, I can&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gitstub console &lt;span class="nt"&gt;-gsu&lt;/span&gt; myusername &lt;span class="nt"&gt;-gsp&lt;/span&gt; mypassword
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By default, &lt;code&gt;gitstub&lt;/code&gt; will use the current folder as the name for a public project on GitHub.  The two parameters after &lt;code&gt;console&lt;/code&gt; are my GitHub username (&lt;code&gt;-gsu&lt;/code&gt;) and GitHub password (&lt;code&gt;-gsp&lt;/code&gt;).  This will do the stuff, including adding a .gitignore file that ignores most of the common things for dotnet projects.  A few moments later, voila, I can now go to &lt;a href="https://github.com/myusername/MyKillerApp"&gt;https://github.com/myusername/MyKillerApp&lt;/a&gt; and see everything there.  If I open up the project in Visual Studio, I can proceed to use the Team Explorer window to process further commits.  &lt;/p&gt;

&lt;p&gt;Perhaps I want a little more structure with a solution/project laid out like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/

&lt;ul&gt;
&lt;li&gt;MyKillerApp.sln&lt;/li&gt;
&lt;li&gt;src/

&lt;ul&gt;
&lt;li&gt;MyKillerApp/

&lt;ul&gt;
&lt;li&gt;MyKillerApp.csproj&lt;/li&gt;
&lt;li&gt;&amp;lt;other files&amp;gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I can say&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gitstub console &lt;span class="nt"&gt;--sln&lt;/span&gt; &lt;span class="nt"&gt;-gsu&lt;/span&gt; myusername &lt;span class="nt"&gt;-gsp&lt;/span&gt; mypassword
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;gitstub&lt;/code&gt; will create a solution and a project and arrange them thus.&lt;/p&gt;

&lt;p&gt;If I had a different name I wanted to use for the project and solution, I can specify that as well&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gitstub console &lt;span class="nt"&gt;-gsr&lt;/span&gt; &lt;span class="s2"&gt;"FirstKillerApp"&lt;/span&gt; &lt;span class="nt"&gt;-gss&lt;/span&gt; &lt;span class="s2"&gt;"KillerApps"&lt;/span&gt; &lt;span class="nt"&gt;-gsu&lt;/span&gt; myusername &lt;span class="nt"&gt;-gsp&lt;/span&gt; mypassword
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If it needs to be a private repository, then I can add &lt;code&gt;--private&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gitstub console &lt;span class="nt"&gt;-gsr&lt;/span&gt; &lt;span class="s2"&gt;"FirstKillerApp"&lt;/span&gt; &lt;span class="nt"&gt;-gss&lt;/span&gt; &lt;span class="s2"&gt;"KillerApps"&lt;/span&gt; &lt;span class="nt"&gt;-gsu&lt;/span&gt; myusername &lt;span class="nt"&gt;-gsp&lt;/span&gt; mypassword &lt;span class="nt"&gt;--private&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I can give the GitHub project a description and I can change the first commit message as well&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gitstub console &lt;span class="nt"&gt;--sln&lt;/span&gt; &lt;span class="nt"&gt;-gsu&lt;/span&gt; myusername &lt;span class="nt"&gt;-gsp&lt;/span&gt; mypassword &lt;span class="nt"&gt;-gsd&lt;/span&gt; &lt;span class="s2"&gt;"The best app yet"&lt;/span&gt; &lt;span class="nt"&gt;-gsc&lt;/span&gt; &lt;span class="s2"&gt;"Initialized with the console template"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If my template has additional parameters, I can pass those along - any parameter not reserved for &lt;code&gt;gitstub&lt;/code&gt; will be passed to the &lt;code&gt;dotnet new&lt;/code&gt; command in original order, so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gitstub webapp &lt;span class="nt"&gt;-au&lt;/span&gt; Individual &lt;span class="nt"&gt;--sln&lt;/span&gt; &lt;span class="nt"&gt;-gsu&lt;/span&gt; myusername &lt;span class="nt"&gt;-gsp&lt;/span&gt; mypassword &lt;span class="nt"&gt;-gsd&lt;/span&gt; &lt;span class="s2"&gt;"Authed web app example"&lt;/span&gt; &lt;span class="nt"&gt;-gsc&lt;/span&gt; &lt;span class="s2"&gt;"Initialized with webapp and individual authentication"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;will run &lt;code&gt;dotnet new webapp -au Individual&lt;/code&gt; at the project creation step.&lt;/p&gt;

&lt;p&gt;If I have an existing project, I can still use &lt;code&gt;gitstub&lt;/code&gt; to get things moving by including the &lt;code&gt;--existing&lt;/code&gt; switch.  With this, &lt;code&gt;gitstub&lt;/code&gt; will skip the project/solution creation step and just commit what's already in the folder.  It still adds the &lt;code&gt;.gitignore&lt;/code&gt;, so it won't pick up obj/bin/.vs and other stuff.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gitstub &lt;span class="nt"&gt;-gsu&lt;/span&gt; myusername &lt;span class="nt"&gt;-gsp&lt;/span&gt; mypassword &lt;span class="nt"&gt;--existing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;You can follow along, post issues, feature requests, tell me how to be better at this open source thing, etc. at the &lt;a href="https://github.com/erikest/gitstub"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In my sights for future features are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;getting rid of having to pass username and password each time by implementing GitHub OAuth and caching a token for the session.&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;devops&lt;/code&gt; switch that would create an Azure Devops project and connect it to the GitHub project&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;nuget&lt;/code&gt; switch that would search the template output for a .nuspec file and modify it with the appropriate project repository and project name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm very open to feedback and suggestions, so let me know what you think! &lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>globaltool</category>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>gRPC on dotnet core 3.1 on RaspberryPi 3 </title>
      <dc:creator>erikest</dc:creator>
      <pubDate>Tue, 09 Apr 2019 03:35:29 +0000</pubDate>
      <link>https://dev.to/erikest/grpc-on-dotnet-core-preview3-on-raspberrypi-3-4nf4</link>
      <guid>https://dev.to/erikest/grpc-on-dotnet-core-preview3-on-raspberrypi-3-4nf4</guid>
      <description>&lt;p&gt;gRPC on dotnet core 3.1 on RaspberryPi 3 (originally written for preview3, the nuget packages have been updated for the latest version)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;tl;dr&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;It's not officially supported, but by compiling the native &lt;strong&gt;libgrpc_csharp_ext&lt;/strong&gt; library for ARM, it is possible.  I've made it easier with a set of scripts to help you compile it on your own.  I've also created a nuget package too, so you don't &lt;em&gt;have&lt;/em&gt; to compile it and a template &lt;code&gt;dotnet new grpcpi&lt;/code&gt; to connect all the dots and supercharge your grpc pi life.  Also, if your goal is to put your code on github to share (please do!), try &lt;em&gt;gitstub&lt;/em&gt;, a dotnet cli global tool that encourages github-first development.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To compile libgrpc_csharp_ext on your own

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/erikest/libgrpc_csharp_ext"&gt;https://github.com/erikest/libgrpc_csharp_ext&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;To get an already compiled &lt;code&gt;libgrpc_csharp_ext.x86.so&lt;/code&gt; (compiled for arm) that you can add to your project right now

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nuget.org/packages/libgrpc_csharp_ext.arm7"&gt;https://www.nuget.org/packages/libgrpc_csharp_ext.arm7&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;To start a fresh grpc project ready to publish to linux-arm for the pi.

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/erikest/grpcpi"&gt;https://github.com/erikest/grpcpi&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nuget.org/packages/grpcpi/"&gt;https://www.nuget.org/packages/grpcpi/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dotnet new -i grpcpi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;note: as of .net core 3.1, there is an &lt;a href="https://github.com/dotnet/sdk/issues/4195"&gt;issue&lt;/a&gt; with the publish command selecting the wrong version of libgrpc_csharp_ext.x86.so when publishing for linux-arm.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;To get &lt;code&gt;gitstub&lt;/code&gt;, so you can get all your projects up to GitHub with minimal fuss, see my &lt;a href="https://dev.to/erikest/gitstub-a-github-first-development-boostrapper-for-dotnet-core-1i5f"&gt;other post about it&lt;/a&gt; or just install and discover on your own

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;dotnet tool install --global gitstub&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;It's a great day when you sit down to get something done with a new magic bauble, the excitement visible in your eyes, only to discover the coolness is not yet supported for 'your architecture/platform/environment'.  Thus was the case when I decided to start a new client/server project with RaspberryPis. Being eager to use dotnet core, but wanting something a little more terse than json over the wire, I discovered the efficient client/server protocol gRPC, was now available for my favorite cross-platform framework - &lt;strong&gt;dotnet core&lt;/strong&gt;.  The tooling is new and shiny, with a canonical 'hello world' template ready to go in Visual Studio 2019 and dotnet core 3 preview 6 from the command line (&lt;code&gt;dotnet new grpc&lt;/code&gt;).  Unfortunately, the officially supported processor architectures are x64 and x86 - arm has been left out for now.  However, we'll see that with a little elbow grease and hackery, we can get the new gRPC bits working with the RaspberryPi, then get the demo running and let out a satisfied chortle when the pi talks back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;We're going to look at a couple of aspects of getting this working:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First we'll discuss the set up - devices, development environments, tooling, etc. &lt;/li&gt;
&lt;li&gt;Then we'll walk through the process of compiling the native &lt;em&gt;libgrpc_csharp_ext&lt;/em&gt; for the &lt;em&gt;arm7&lt;/em&gt; processor on the &lt;strong&gt;RaspberryPi&lt;/strong&gt;.  We'll look at the automated build/test script and an experimental script in the repository that is used to compile the library for android as our inspiration.  Don't worry, it turns out to not be too complicated and I've got you covered with scripts to make it straight forward if you want to follow along.&lt;/li&gt;
&lt;li&gt;With a native library in hand, we'll examine the canned gRPC template and what we need to do to get it working on the pi&lt;/li&gt;
&lt;li&gt;After crawling through that, we'll bring in a nuget package that will save us some tedium&lt;/li&gt;
&lt;li&gt;Finally, we'll look at the new grpcpi template, install it and generate a new project that ties it all together.  We'll work through this example to send a message from the server to the pi via gRPC, which the pi will then use to generate a series of blinks on an led.  At the end we'll have all the pieces we need to start developing more meaningful applications on this platform.&lt;/li&gt;
&lt;li&gt;As a bonus, we'll install &lt;em&gt;gitstub&lt;/em&gt;, a dotnet cli global tool that connects up a new or existing project to a github repository to jump start your dev cycle and get your source &lt;em&gt;open&lt;/em&gt; in record time.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Let's Get Started!
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tools, devices, environments, oh my!
&lt;/h3&gt;

&lt;p&gt;We'll need some tools.  First let's talk about our main development machine.  In my case an old x64 based dell laptop.  On this box, be it physical or virtual, we'll need the dotnet preview6 sdk and runtime.  Those are available &lt;a href="https://dotnet.microsoft.com/download/dotnet-core/3.1"&gt;here&lt;/a&gt;.  Since we're going to examine the new templates in visual studio, we'll need &lt;a href="https://visualstudio.microsoft.com/downloads/"&gt;Visual Studio 2019&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, for the RaspberryPi, we'll be using raspbian as the linux distro, though others will likely work fine.  We'll also need a few other bits to compile the library.  You can step through these individually below or you can use the following commands to download a script that &lt;em&gt;should&lt;/em&gt; work to automate this and compile the library all in one step. &lt;/p&gt;

&lt;p&gt;As always, don't trust me and my script until you read it and verify that it isn't a nefarious evil doer masquerading as an innocent attempt to get you compiling this obscure library.&lt;/p&gt;

&lt;p&gt;On the pi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://github.com/erikest/libgrpc_csharp_ext/setupAndCompile.sh
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x ./setupAndCompile.sh
./setupAndCompile.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To compile this library, we'll need the build tools, the source code and as we'll discuss later, we'll need to determine &lt;em&gt;how&lt;/em&gt; to build just the library we're interested in, as the grpc source code contains lots of other bits that we don't need to recompile for this task.  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get git - if you're following along on raspbian, then you've already got git, good.&lt;/li&gt;
&lt;li&gt;Install the build tools (&lt;a href="https://github.com/erikest/libgrpc_csharp_ext/installToolchain.sh"&gt;script&lt;/a&gt;).

&lt;ul&gt;
&lt;li&gt;In the &lt;a href="https://github.com/grpc/grpc/tree/master/src/csharp"&gt;README.md&lt;/a&gt; for the csharp submodule, we're told to look at the &lt;a href="https://github.com/grpc/grpc/blob/master/BUILDING.md"&gt;BUILD.md&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;BUILD.md tells us for linux compilation, the tools we'll need are:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; apt-get &lt;span class="nb"&gt;install &lt;/span&gt;build-essential autoconf libtool pkg-config
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; apt-get &lt;span class="nb"&gt;install &lt;/span&gt;libgflags-dev libgtest-dev
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; apt-get &lt;span class="nb"&gt;install &lt;/span&gt;clang libc++-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;What they don't tell you, probably because it's not supported, is that we'll also need &lt;strong&gt;cmake&lt;/strong&gt;, which &lt;em&gt;is&lt;/em&gt; listed under Windows as a build dependency and we'll see why when we go over the build process.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; apt-get &lt;span class="nb"&gt;install &lt;/span&gt;cmake
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Git the source (&lt;a href="https://github.com/erikest/libgrpc_csharp_ext/gitgRPCsource.sh"&gt;script&lt;/a&gt;)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/libgrpc_csharp_ext/
 &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/libgrpc_cshar_ext/
 &lt;span class="nv"&gt;$ &lt;/span&gt;git clone &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://grpc.io/release&lt;span class="si"&gt;)&lt;/span&gt; https://github.com/grpc/grpc
 &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;grpc
 &lt;span class="nv"&gt;$ &lt;/span&gt;git submodule update &lt;span class="nt"&gt;--init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This is also from BUILD.md&lt;/li&gt;
&lt;li&gt;If you want to deploy your app to the pi as a framework-dependent deployment or a framework-dependent executable, you'll need the dotnet runtime.  Otherwise, publishing for a particular runtime will create a self-contained deployment), meaning all of the necessary libraries are published with the executable.  You can read more about the three styles &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli"&gt;here&lt;/a&gt;.  For this walkthrough, we'll being doing a framework-dependent executable, so we'll need the runtime.

&lt;ul&gt;
&lt;li&gt;As of this writing, the latest version, 3.1, can be had thus (&lt;a href="https://github.com/erikest/libgrpc_csharp_ext/installDotNet3.1.sh"&gt;script&lt;/a&gt;):
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#Dependencies&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;curl libunwind8 gettext

&lt;span class="c"&gt;#SDK needed to compile&lt;/span&gt;
wget https://download.visualstudio.microsoft.com/download/pr/d52fa156-1555-41d5-a5eb-234305fbd470/173cddb039d613c8f007c9f74371f8bb/dotnet-sdk-3.1.101-linux-arm.tar.gz

&lt;span class="c"&gt;#Runtime needed to run apps&lt;/span&gt;
wget https://download.visualstudio.microsoft.com/download/pr/da60c9fc-c329-42d6-afaf-b8ef2bbadcf3/14655b5928319349e78da3327874592a/aspnetcore-runtime-3.1.1-linux-arm.tar.gz

&lt;span class="c"&gt;#Make a home and extract the tars&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/dotnet
&lt;span class="nb"&gt;tar &lt;/span&gt;zxf dotnet-sdk-3.1.101-linux-arm.tar.gz &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/dotnet
&lt;span class="nb"&gt;tar &lt;/span&gt;zxf aspnetcore-runtime-3.1.1-linux-arm.tar.gz &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/dotnet

&lt;span class="c"&gt;#Set environment variables, including the path so the dotnet cli can be found&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DOTNET_ROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/dotnet
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:&lt;span class="nv"&gt;$HOME&lt;/span&gt;/dotnet

&lt;span class="c"&gt;#push the path to the profile so it 'sticks' after restarts&lt;/span&gt;
&lt;span class="nb"&gt;sudo echo&lt;/span&gt; &lt;span class="s2"&gt;"export DOTNET_ROOT=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/dotnet"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/profile
&lt;span class="nb"&gt;sudo echo&lt;/span&gt; &lt;span class="s2"&gt;"export PATH=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;:/&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/dotnet"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OK!  We've got tools, we've got source, now we just need to put them to work&lt;/p&gt;

&lt;h3&gt;
  
  
  Compiling libgrpc_csharp_ext
&lt;/h3&gt;

&lt;p&gt;If we again inspect the csharp submodule &lt;a href="https://github.com/grpc/grpc/tree/master/src/csharp"&gt;README&lt;/a&gt;, we'll see the recommended way to get compiling is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# from the gRPC repository root&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;python tools/run_tests/run_tests.py &lt;span class="nt"&gt;-l&lt;/span&gt; csharp &lt;span class="nt"&gt;-c&lt;/span&gt; dbg &lt;span class="nt"&gt;--build_only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you tried to run that now, you'd get a fair number of errors.  The problem is that this run_tests.py is trying to compile &lt;em&gt;all&lt;/em&gt; the stuff in the csharp submodule - we only want the native library.  What we need to do is examine run_tests.py to see what it is doing and if we can peel away the other build steps and just get the native library out.&lt;/p&gt;

&lt;p&gt;In run_tests.py, each language has a class which is switched using the &lt;code&gt;-l&lt;/code&gt; flag, as in the command above &lt;code&gt;-l csharp&lt;/code&gt;.  When we do a find for csharp, we see some &lt;a href="https://github.com/grpc/grpc/blob/31843787ccdb8446e3be3b62d6688dc1de22c7b4/tools/run_tests/run_tests.py#L923"&gt;goodies&lt;/a&gt;.  Specifically, let's note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a method called &lt;a href="https://github.com/grpc/grpc/blob/31843787ccdb8446e3be3b62d6688dc1de22c7b4/tools/run_tests/run_tests.py#L1000"&gt;&lt;code&gt;pre_build_steps&lt;/code&gt;&lt;/a&gt;.  Hmm, that sounds interesting and it's pointing to another &lt;a href="https://github.com/grpc/grpc/blob/master/tools/run_tests/helper_scripts/pre_build_csharp.sh"&gt;script&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;a method called &lt;a href="https://github.com/grpc/grpc/blob/31843787ccdb8446e3be3b62d6688dc1de22c7b4/tools/run_tests/run_tests.py#L1009"&gt;&lt;code&gt;make_targets&lt;/code&gt;&lt;/a&gt;.  Since &lt;code&gt;make&lt;/code&gt; is typically orchestrating gcc/g++ builds and we're trying to compile a native c++ library, this is also intriguing.  &lt;em&gt;And&lt;/em&gt; it references a target called 'grpc_csharp_ext' - that sounds like just what we need!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a bit of confirmation, let's look at the csharp/experimental folder, where there are scripts for compiling the native library for android, ios and unity.  In the android &lt;a href="https://github.com/grpc/grpc/blob/31843787ccdb8446e3be3b62d6688dc1de22c7b4/src/csharp/experimental/build_native_ext_for_android.sh#L52"&gt;script&lt;/a&gt; we see, after a call to cmake to set up the build environment: &lt;code&gt;make -j4 grpc_csharp_ext&lt;/code&gt;  AHA!  the &lt;code&gt;-j4&lt;/code&gt; switch tells the compiler how many threads to spawn and then we have our &lt;code&gt;grpc_csharp_ext&lt;/code&gt; target.  Okay, we're feeling good now that we're on the right track.  We don't actually have a makefile yet though, so we need to get that sorted.  &lt;/p&gt;

&lt;p&gt;Before we can make, we have to cmake a makefile, so let's make way back to that &lt;a href="https://github.com/grpc/grpc/blob/master/tools/run_tests/helper_scripts/pre_build_csharp.sh"&gt;pre_build_script&lt;/a&gt; and take a look under the hood.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-ex&lt;/span&gt;

&lt;span class="c"&gt;# cd to repository root&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/../../.."&lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; cmake/build
&lt;span class="nb"&gt;cd &lt;/span&gt;cmake/build

cmake &lt;span class="nt"&gt;-DgRPC_BUILD_TESTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;OFF &lt;span class="nt"&gt;-DCMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MSBUILD_CONFIG&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; ../..

&lt;span class="nb"&gt;cd&lt;/span&gt; ../../src/csharp

dotnet restore Grpc.sln
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks promising, we've got a little directory shuffling, then a call to cmake (which should now &lt;em&gt;make&lt;/em&gt; clear why we needed that tool installed as well), and finally a restore on the grpc solution, to get ready for the dotnet part of the build.  Well, we don't want the dotnet part though, we just want the cmake call to set up the build environment and then to build our native target.  &lt;/p&gt;

&lt;p&gt;By combining what we learned from the make target (&lt;code&gt;grpc_csharp_ext&lt;/code&gt;), with the prebuild step here, we can arrive at the commands to perform the compilation.  These are executed relative to the root of our work, which if you're following along should be at &lt;code&gt;~/libgrpc_csharp_ext/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;here's our script, also located &lt;a href="https://github.com/erikest/libgrpc_csharp_ext/compile_csharp_ext.sh"&gt;here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-ex&lt;/span&gt;

&lt;span class="c"&gt;#intended to be run from the repository root&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;grpc/

&lt;span class="c"&gt;#create location for build files&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; cmake/build
&lt;span class="nb"&gt;cd &lt;/span&gt;cmake/build

&lt;span class="c"&gt;#setup the build files&lt;/span&gt;
cmake &lt;span class="nt"&gt;-DgRPC_BUILD_TESTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;OFF &lt;span class="nt"&gt;-DCMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MSBUILD_CONFIG&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; ../..

&lt;span class="c"&gt;#compile libgrpc_csharp_ext.so&lt;/span&gt;
make &lt;span class="nt"&gt;-j4&lt;/span&gt; grpc_csharp_ext

&lt;span class="nb"&gt;cp &lt;/span&gt;libgrpc_csharp_ext.so ../../../libgrpc_csharp_ext.x86.so
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything there looks solid, but, why are we copying &lt;code&gt;libgrpc_csharp_ext.so&lt;/code&gt; to &lt;code&gt;libgrpc_csharp_ext.x86.so&lt;/code&gt;?  Well, that's a &lt;em&gt;perfect&lt;/em&gt; segue into the next topic!&lt;/p&gt;

&lt;h3&gt;
  
  
  gRPC template
&lt;/h3&gt;

&lt;p&gt;On our dev box, we can create a new grpc project using the included template&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;grpcDemo
&lt;span class="nb"&gt;cd &lt;/span&gt;grpcDemo
dotnet new grpc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we then publish the client for the linux-arm runtime identifier (RID)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet publish grpcDemo/grpcDemo.Client/grpcDemo.Client.csproj -r linux-arm --self-contained false&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If we don't include the &lt;code&gt;--self-contained false&lt;/code&gt;, then we'll get a whole bunch of framework libraries as well.  This could be good for portability, since you can just push the whole publish folder to any pi and get going, but for iterative development, doing the one time set up of the framework to avoid the extra file copy seems like the way to go.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;we'll find in the /bin/debug/netcoreapp3.0/linux-arm/publish folder two copies of the libgrpc_csharp_ext, one .x86.so and one .x64.so&lt;/p&gt;

&lt;p&gt;If we deploy this to an existing directory on the pi, for example by using scp&lt;/p&gt;

&lt;p&gt;&lt;code&gt;scp ./grpcDemo.Client/bin/debug/netcoreapp3.0/linux-arm/publish pi@&amp;lt;PI IP&amp;gt;:~/grpc.Client&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;as noted &lt;a href="https://superuser.com/questions/1403473/scp-error-unexpected-filename"&gt;here&lt;/a&gt;, the scp command no longer supports the handy &lt;code&gt;/.&lt;/code&gt; which would copy the files without including the directory they are in.  So we get a 'publish' folder on the pi when we don't want one. So it goes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;and run it from the pi&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/grpc.Client/publish
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x grpcDemo.Client
./grpcDemo.Client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we'll get an error like this &lt;a href="https://stackoverflow.com/questions/54568281/how-to-deploy-a-sample-grpc-client-server-solution-in-raspberri-pi-in-dotnet-c/55578459#55578459"&gt;person did on SO&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which basically says it can't load the &lt;code&gt;libgrpc_csharp_ext.x86.so&lt;/code&gt; library.  Here's where our problem and the beginning of all this work started - this library isn't compiled for the arm processor, but it is still being included in the publish output and is being referenced by the NativeExtension class.  When we dig into the repository and look at the source, specifically &lt;a href="https://github.com/grpc/grpc/blob/dc1089a6d1e5874d4560fe1744c51cc55bdf7d4a/src/csharp/Grpc.Core/Internal/NativeExtension.cs#L203"&gt;here&lt;/a&gt; we notice that the file name it looks for depends on the OS, linux in this case which needs a static library, .so, and the architecture.  Despite the pi having a 64 bit processor, the reality is that the OS is ARM32, thus the architecture string gets set as x86.  All that is to say, on a raspberrypi running raspbian, the file name it tries to load is &lt;strong&gt;libgrpc_csharp_ext.x86.so&lt;/strong&gt; - so, let us give it what it wants!&lt;/p&gt;

&lt;p&gt;On the pi&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; ~/libgrpc_csharp_ext/libgrpc_csharp_ext.x86.so ~/grpc.Client/publish
./grpcDemo.Client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time it should pause for about 15-20 seconds before we see&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Unhandled Exception: Grpc.Core.RpcException: Status(StatusCode=Unavailable, Detail="Connect Failed")
   at gRPCpi.Program.Main(String[] args) in C:\Users\Geocoder\Source\Repos\gRPC Template\content\gRPCpi\src\gRPCpi.Clien
t\Program.cs:line 26
&lt;/span&gt;&lt;span class="gp"&gt;   at gRPCpi.Program.&amp;lt;Main&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;String[] args&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;Aborted
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, hey, that means it is &lt;strong&gt;running!&lt;/strong&gt;  It just couldn't &lt;em&gt;connect&lt;/em&gt; to the server.  We're getting closer to shaving our yak!  Well, it turns out it's trying to connect to the server on the localhost by default.  So we need to make a couple of modifications, since our server will be running over a network on our dev machine.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the Client's program.cs, we need to aim the grpc client at the server's (dev box) ip address.  If you don't know yours, &lt;code&gt;ipconfig&lt;/code&gt; on windows or &lt;code&gt;ifconfig&lt;/code&gt; on linux will get you there.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="c1"&gt;//CHANGE THIS TO YOUR SERVER ADDRESS&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serverIpAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR IP"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;serverIpAddress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:"&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ChannelCredentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Insecure&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We also need the server to be listening on that ip address and port and by default it is not, it listens only on localhost.  To open this up to our network IP, we need to make a change to the kestrel server configuration:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDefaultBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureWebHostDefaults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webBuilder&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;webBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseStartup&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Startup&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;webBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseUrls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://*:50051"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we've said listen on all (*) IP addresses bound to the network interface. &lt;/p&gt;

&lt;p&gt;Now, let's republish the client to the pi.  So on the dev box again, at the project root&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;dotnet publish grpcDemo/grpcDemo.Client/grpcDemo.Client.csproj -r linux-arm
&lt;/span&gt;&lt;span class="gp"&gt;scp ./grpcDemo.Client/bin/debug/netcoreapp3.0/linux-arm/publish pi@&amp;lt;PI IP&amp;gt;&lt;/span&gt;:~/grpc.Client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we run the client again, let's get the server started and ready.  In Visual Studio you can just run a new debug instance, or from the command line&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet run --project grpcDemo/grpcDemo.Server/grpcDemo.Server.csproj&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then back on the pi, let's run the client, after we overwrite the &lt;code&gt;libgrpc_csharp_ext&lt;/code&gt; library again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; ~/libgrpc_csharp_ext/libgrpc_csharp_ext.x86.so ~/grpc.Client/publish
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/grpc.Client/publish
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x grpcDemo.Client
./grpcDemo.Client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all has gone to plan, we should get this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Greeting: Hello GreeterClient
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chortle! woo! we did it - time to hang up our hats, jobs done... Well not exactly, while this shows that we can 'get it working', what we really want is to have the correct library come across with all the other published artifacts, so we can continue development without so many steps.  Sure, we could write more scripts to make this less painful, but isn't there a better way?&lt;/p&gt;

&lt;h3&gt;
  
  
  Libgrpc_csharp_ext.arm7 Nuget Package
&lt;/h3&gt;

&lt;p&gt;So far, we've manually overwritten the 'wrong' native library with our arm compiled version.  What we really want is for the correct library to be brought in during publish - so whichever runtime we publish for, it will have the correct version.  If you publish for windows or linux or osx, you'll notice the publish command correctly copies over the version needed for each runtime.  &lt;/p&gt;

&lt;p&gt;What's going on here?  &lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;Grpc.Core&lt;/code&gt; nuget package, which is referenced in the template, are copies of that native library for each of win, linux, and osx runtimes.  You can verify this by examining the package cache at YourUserName.nuget\packages\grpc.tools&amp;lt;version&amp;gt;\runtimes folder.  The publish command uses this convention to find additional runtime specific components to copy to the build and publish output.  This same mechanism can be used to provide the library for the linux-arm runtime.  Let's go ahead and add a reference to this package&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet add grpcDemo\grpcDemo.Client package libgrpc_csharp_ext.arm7&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then publish again&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet publish grpcDemo/grpcDemo.Client/grpcDemo.Client.csproj -r linux-arm --self-contained false&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can verify (by file size) that our version of the library has been copied over and is ready for deployment.  Hey, now this project has legs and quick iterations are at hand!&lt;/p&gt;

&lt;h3&gt;
  
  
  Next up
&lt;/h3&gt;

&lt;p&gt;In the next post, we'll finish all this work up by making it even easier to get started by adding a new project template which puts it all together.  Then we'll use gitstub to jumpstart a new open source client/server blinking led project that &lt;em&gt;everybody&lt;/em&gt; will surely want!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
