<?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: CodeFuture</title>
    <description>The latest articles on DEV Community by CodeFuture (@codefuture).</description>
    <link>https://dev.to/codefuture</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%2F583517%2Fd1d76be2-4e72-4547-b2ca-77bed0ba55a5.png</url>
      <title>DEV Community: CodeFuture</title>
      <link>https://dev.to/codefuture</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codefuture"/>
    <language>en</language>
    <item>
      <title>A simple configmanager program for assigning values to variables from a custom config file | Golang</title>
      <dc:creator>CodeFuture</dc:creator>
      <pubDate>Mon, 29 Mar 2021 15:10:35 +0000</pubDate>
      <link>https://dev.to/codefuture/a-simple-configmanager-program-for-assigning-values-to-variables-from-a-custom-config-file-golang-5ep6</link>
      <guid>https://dev.to/codefuture/a-simple-configmanager-program-for-assigning-values-to-variables-from-a-custom-config-file-golang-5ep6</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/rrrcode9-golang-util/configmanager.git"&gt;GitHub Repo - configmanager&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This program &lt;code&gt;configmanager&lt;/code&gt; reads a configuration file (&lt;em&gt;.conf) and assigns values to a struct defined by the user. This comes in handy when you want to assign some variables in golang program from a custom configuration file. The process is simple: import &lt;code&gt;configmanager&lt;/code&gt;, create your struct with **exported&lt;/em&gt;* fields, create a &lt;code&gt;*.conf&lt;/code&gt; file or a &lt;code&gt;default.conf&lt;/code&gt; file in PWD, define the variables in the config file, pass the struct reference to &lt;code&gt;AssignConfiguration&lt;/code&gt; method in &lt;code&gt;configmanager&lt;/code&gt;; you are good to go.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration File Format
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Comments shall start with &lt;code&gt;#&lt;/code&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;# this is a comment&lt;/span&gt;
  Val &lt;span class="o"&gt;=&lt;/span&gt; 5 &lt;span class="c"&gt;# this is a comment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All variables in the configuration file must start with &lt;code&gt;Caps Letter&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Variable must be defined with a &lt;code&gt;field name&lt;/code&gt; and a &lt;code&gt;value&lt;/code&gt; separated with &lt;code&gt;=&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a variable is defined multiple times in a single configuration file, the bottom-most value of the corresponding variable is assigned&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Struct Definition
&lt;/h3&gt;

&lt;p&gt;Each field of the user-defined struct shall be exported (First letter must be in caps), so that the same can be accessed by &lt;code&gt;configmanager&lt;/code&gt; program to assign values to struct fields from config file.&lt;/p&gt;

&lt;p&gt;Following types are supported for struct fields:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;int64&lt;/li&gt;
&lt;li&gt;float64&lt;/li&gt;
&lt;li&gt;string&lt;/li&gt;
&lt;li&gt;bool
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Val1&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;
    &lt;span class="n"&gt;Val2&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Val3&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="n"&gt;Val4&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  configmanager usage
&lt;/h3&gt;

&lt;p&gt;let's first create a file &lt;code&gt;main.go&lt;/code&gt; .  Import &lt;code&gt;configmanager&lt;/code&gt; from GitHub. We define a struct config with four fields: &lt;code&gt;Val1, Val2, Val3, Val4&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/rrrcode9-golang-util/configmanager"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Val1&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;
    &lt;span class="n"&gt;Val2&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Val3&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="n"&gt;val4&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;configmanager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssignConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%+v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&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;&lt;code&gt;AssignConfiguration&lt;/code&gt; method takes the reference of struct variable, and then the fields will be assigned with the values from the config file.&lt;/p&gt;

&lt;p&gt;Now create a config file &lt;code&gt;default.conf&lt;/code&gt; in the present directory. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Alternatively, &lt;code&gt;*.conf&lt;/code&gt; file can be created anywhere in the system and the same can be specified while running your program passing arguments as mentioned in &lt;code&gt;Notes&lt;/code&gt; below.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# file: ./default.conf
&lt;/span&gt;
&lt;span class="n"&gt;Val1&lt;/span&gt; = &lt;span class="m"&gt;40&lt;/span&gt;
&lt;span class="n"&gt;Val2&lt;/span&gt; = &lt;span class="n"&gt;hello&lt;/span&gt;
&lt;span class="n"&gt;Val3&lt;/span&gt; = &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;Val4&lt;/span&gt; = &lt;span class="m"&gt;80&lt;/span&gt;.&lt;span class="m"&gt;7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, run the following command:&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="nv"&gt;$ &lt;/span&gt;go run main.go 

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

&lt;/div&gt;



&lt;p&gt;Output: &lt;code&gt;{Val1:40 Val2:hello Val3:true Val4:80.7}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Notes: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Alternatively, the config file location can be specified using arguments with "--config-file-path" or "-f" and with path of config file.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&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;go run main.go &lt;span class="nt"&gt;--config-file-path&lt;/span&gt; &amp;lt;path of config file&amp;gt;
or
&lt;span class="nv"&gt;$ &lt;/span&gt;go run main.go &lt;span class="nt"&gt;-f&lt;/span&gt; &amp;lt;path of config file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In case no config-file is specified, the &lt;code&gt;configmanager&lt;/code&gt; program will search for &lt;code&gt;default.conf&lt;/code&gt; file in the present working directory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks. I would appreciate your feedback/suggestions/comments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Follow Me :
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UCMat0Hlx67xwLrhIKRWMjEw"&gt;YouTube CodeFuture&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  golang
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>Flutter+Dart Frontend &lt;--&gt;Golang Backend API</title>
      <dc:creator>CodeFuture</dc:creator>
      <pubDate>Wed, 24 Feb 2021 19:10:45 +0000</pubDate>
      <link>https://dev.to/codefuture/flutter-dart-frontend-golang-backend-api-4320</link>
      <guid>https://dev.to/codefuture/flutter-dart-frontend-golang-backend-api-4320</guid>
      <description>&lt;p&gt;In Part-1/2 of this series, we are going to implement a Golang API server that caters to HTTP GET requests from clients. We will create a hypothetical store with products carrying attributes: Name, Price, and Count. A valid HTTP GET request gets a response with a list of products.&lt;/p&gt;

&lt;p&gt;In Part-2/2 of this series, we are going to develop a Flutter App that will execute API calls to the server. The fetched data in JSON format from the server will be displayed using ListView. &lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/PCoF1a2cugs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ezl4w4xDXAo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this post. I would appreciate your feedback/suggestions/comments in the comment section below.&lt;/p&gt;

&lt;p&gt;Thanks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Follow Me :
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UCMat0Hlx67xwLrhIKRWMjEw"&gt;YouTube CodeFuture&lt;/a&gt; , &lt;a href="https://twitter.com/Code9Rrr"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Link to GitHub :
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/rrrCode9/FlutterGolangAPI"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>go</category>
      <category>api</category>
      <category>dart</category>
    </item>
    <item>
      <title>A step-by-step guide to set up an SFTP file transfer server in Linux</title>
      <dc:creator>CodeFuture</dc:creator>
      <pubDate>Wed, 24 Feb 2021 19:05:51 +0000</pubDate>
      <link>https://dev.to/codefuture/a-step-by-step-guide-to-set-up-an-sftp-file-transfer-server-in-linux-13cb</link>
      <guid>https://dev.to/codefuture/a-step-by-step-guide-to-set-up-an-sftp-file-transfer-server-in-linux-13cb</guid>
      <description>&lt;p&gt;In this tutorial, we are going to learn how to set up a remote server for secure file transfer between the user's local machine and remote server over SFTP. SFTP is known as Secure File Transfer Protocol or SSH File Transfer Protocol. &lt;/p&gt;

&lt;p&gt;Before we start, please ensure the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You have access to a Linux remote machine (this tutorial used Ubuntu server distro 20.xx)&lt;/li&gt;
&lt;li&gt;You have login access to a remote machine through SSH&lt;/li&gt;
&lt;li&gt;The User access you have is listed under sudo group&lt;/li&gt;
&lt;li&gt;The local machine can be of any OS - Mac, Linux, Windows, etc. - on which you can have access to a remote machine through SSH.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's first set up a user account typing the following commands in a terminal of the remote machine.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create a user group
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo groupadd sftpgroup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Create user
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo useradd -m vyndour 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Assign a password to the user
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo passwd vyndour
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Add user to our &lt;em&gt;sftpgroup&lt;/em&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo usermod -a -G sftpgroup vyndour
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6. Make user the owner of it's own directory
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chown vyndour /home/vyndour
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Give read(r),write(w) and execute(x) access of user's directory to only user
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chmod 700 /home/vyndour
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In case we need to add more users, we can repeat steps 2-6.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, let's install the openssh server and set up SFTP settings.&lt;/p&gt;

&lt;h4&gt;
  
  
  7. First, let's update the existing packages
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  8. Install openssh-sever
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install openssh-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  9. Open SSHD_config file
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  10. Copy the following lines at the end of the _sshd_config_file
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# FOR SSH key authentication

PubkeyAuthentication yes
AuthorizedKeysFile    .ssh/authorized_keys

# FOR password authentication

PasswordAuthentication yes

#  SFTP configuration

Match group sftpgroup
ChrootDirectory /home
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  ctrl+s : save the &lt;em&gt;sshd_config&lt;/em&gt; file and ctr+x: exit from &lt;em&gt;sshd_config&lt;/em&gt; file
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;If we want SSH key authentication for SFTP file transfer, we need to set  &lt;code&gt;PubkeyAuthentication yes&lt;/code&gt; and also we need to specify the file name holding SSH public key &lt;code&gt;AuthorizedKeysFile .ssh/authorized_keys&lt;/code&gt;. We will create SSH key in step - 12 below.&lt;/p&gt;

&lt;p&gt;Similarly, if we want password authentication for SFTP file transfer, we need to set &lt;code&gt;PasswordAuthentication yes&lt;/code&gt;. The password is the user's password that we have set earlier in step-3. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  11. For SSH public key authetication , follow the following steps to create and install SSH keys
&lt;/h4&gt;

&lt;p&gt;Open a terminal in our local machine, and create a pair of SSH private and public keys by running the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -f sftp_rsa -t rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we run the above command, two files will be generated - one private key &lt;code&gt;sftp_rsa&lt;/code&gt; and the public key &lt;code&gt;sftp_rsa.pub&lt;/code&gt;. Let's Keep the private key securely with read(r) access to only the user in the user's local system. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We can always change the type of key. Let's stick to the default RSA type key in this tutorial.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# On  user's local machine
sudo chmod 400 &amp;lt;path to the private key in user's local machine&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, in our remote PC create a file in &lt;code&gt;/home/vyndour/.ssh&lt;/code&gt; and name it as &lt;code&gt;authorized_keys&lt;/code&gt;. Copy the content of public key &lt;code&gt;sftp_rsa.pub&lt;/code&gt; from local machine to &lt;code&gt;authorized_keys&lt;/code&gt; file in a remote machine.&lt;/p&gt;

&lt;p&gt;create a .ssh directory in the user's directory in the remote machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir /home/vyndour/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open  a new file with the name &lt;code&gt;authorized_keys&lt;/code&gt; in the remote machine&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    sudo nano /home/vyndour/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Manual task: copy and paste the content manually from &lt;code&gt;sftp_rsa.pub&lt;/code&gt; (local machine) key to the &lt;code&gt;authorized_keys&lt;/code&gt; (remote machine)&lt;/p&gt;

&lt;p&gt;Deny write(w) and execute(x) of &lt;code&gt;authorized_keys&lt;/code&gt; by the user with the following command in the remote machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chmod 644 /home/vyndour/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As an alternative to the above method, you can transfer the public-key file &lt;code&gt;sftp_rsa&lt;/code&gt; to the remote server using SCP. In our local machine, use SCP to transfer &lt;code&gt;sftp_rsa.pub&lt;/code&gt; file to root directory of remote machine with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo scp -i &amp;lt;ssh key that gives access to remote machine&amp;gt; &amp;lt;path to public key in user's local machine&amp;gt; &amp;lt;sudo user&amp;gt;@&amp;lt;ip address of remote machine&amp;gt;:/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create a .ssh directory in the user's directory in the remote machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir /home/vyndour/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the remote machine, create a file in &lt;code&gt;/home/vyndour/.ssh&lt;/code&gt;  and name it as &lt;code&gt;authorized_keys&lt;/code&gt;, and append the key from &lt;code&gt;sftp_rsa.pub&lt;/code&gt; file located in root directory&lt;code&gt;/&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo touch /home/vyndour/authorized_keys
sudo cat /sftp_rsa.pub &amp;gt;&amp;gt; /home/vyndour/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deny delete of authorized_keys by the user with the following command in the remote machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chmod 644 /home/vyndour/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to remove the public key from the root directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo rm /sftp_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  12. Restart SSH
&lt;/h4&gt;

&lt;p&gt;Let's now restart the ssh server with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart sshd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  13. Monitor the logs (Optional for debugging)
&lt;/h4&gt;

&lt;p&gt;In case we need to debug the login through SSH, we can open the &lt;code&gt;/var/log/auth.log&lt;/code&gt; file to live monitor the logs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo tail -f /var/log/auth.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  14. Browse User's directory from the local machine
&lt;/h4&gt;

&lt;p&gt;We can now use software like FileZilla, Cyberduck, or similar to browse the user directory in the remote machine over SFTP with the following typical entries in our local machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Host: sftp://vyndour@&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port : 22  # Default SSH port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Password: User's password  # if &lt;code&gt;PasswordAuthentication yes&lt;/code&gt; in sshd_config file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Private key path:   # if &lt;code&gt;PubkeyAuthentication yes&lt;/code&gt; in &lt;code&gt;sshd_config&lt;/code&gt; file&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are done! :)&lt;br&gt;
I hope you enjoyed this post. I would appreciate your feedback/suggestions/comments in the comment section below.&lt;/p&gt;

&lt;p&gt;Thanks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Follow Me :
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UCMat0Hlx67xwLrhIKRWMjEw"&gt;YouTube CodeFuture&lt;/a&gt; , &lt;a href="https://twitter.com/Code9Rrr"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#SFTP&lt;/code&gt;  &lt;code&gt;#Linux&lt;/code&gt;  &lt;code&gt;#Ubuntu&lt;/code&gt;  &lt;code&gt;#SSH&lt;/code&gt;  &lt;code&gt;#File Transfer&lt;/code&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>ubuntu</category>
      <category>sftp</category>
    </item>
    <item>
      <title>CHAT-SERVER using gRPC Bidirectional Streaming</title>
      <dc:creator>CodeFuture</dc:creator>
      <pubDate>Wed, 24 Feb 2021 18:22:53 +0000</pubDate>
      <link>https://dev.to/codefuture/chat-server-using-grpc-bidirectional-streaming-4e5l</link>
      <guid>https://dev.to/codefuture/chat-server-using-grpc-bidirectional-streaming-4e5l</guid>
      <description>&lt;p&gt;In this post, we will cover how to create a basic chat server for one-to-one chatting using gRPC bidirectional streaming. We are going to use &lt;strong&gt;Go&lt;/strong&gt; language for both gRPC server and gRPC client programs. &lt;/p&gt;

&lt;p&gt;Protocol-buffer or protobuf is an efficient format of data transfer that is preferably used with gRPC. First, we will create a protobuf file with messages that define the format of communication between gRPC server and client and, we also define Remote Procedure Call (RPC) services in the same protobuf file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a protobuf file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Let's first create a **chat.proto** file in the project root directory and copy the following lines.



```protobuf
// path: ./chat.proto

syntax = "proto3";

package chatserver;

message FromClient {
    string name = 1;
    string body = 2;
}

message FromServer {
    string name = 1;
    string body = 2;
}

service Services {

    rpc ChatService(stream FromClient) returns (stream FromServer){};

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;syntax = 'proto3'&lt;/code&gt; specifies that we are using &lt;code&gt;proto3&lt;/code&gt; version syntax (the default version while writing this post is &lt;code&gt;proto2&lt;/code&gt;). We have also specified a package name as &lt;code&gt;chatserver&lt;/code&gt;. Then, we have defined two messages, one for clients to server communication&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 and one for the server to client communication

 ```FromServer```

.  The fields in the message are identical in this case though; the `name` is for the user's name and the body is for the user's message.

To generate the service interface, we need to define **RPC** methods in the `chat.proto` file. In this example, we have defined only one RPC method i.e.`ChatService`. The `ChatService` method will be called by clients to set up bidirectional gRPC streams between client and server.

### Compile protobuf file `chat.proto` 

Now that we have our `chat.proto` file is ready. Next step is to compile the `chat.proto` file to generate the compiled `*.pb.go` file with **Interfaces** that we will be using to send and receive messages.

Before you proceed, please ensure that you have installed the following in your system, and both **protoc** and **protoc-gen-go** are in system $PATH:

&amp;gt; - [protobuf compiler](https://github.com/protocolbuffers/protobuf/releases) 
&amp;gt; - Golang Protobuf plugin:

 ```go install google.golang.org/protobuf/cmd/protoc-gen-go```



Now, run the command below in your preferred shell with PWD as your project root directory to generate golang code referring to `chat.proto` file.



```bash
$ protoc --go_out=plugins=grpc:chatserver chat.proto
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will generate a file &lt;code&gt;chatserver.pb.go&lt;/code&gt; inside a directory &lt;code&gt;./chatserver/&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 under `package main`

Let's create our project as a **Go module** for dependency management by executing the following command in our project root directory. This will create a `go.mod` file that would identify our project as a module.



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

&lt;/div&gt;

&lt;p&gt;$ go mod init grpcChatServer&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Now, create a file named as `server.go` in our project root directory. We define a listener associated with a port which can be referred from environment variables. In case `PORT` is not set as a system environment, then let's assign 5000 (some port) as the default Port for our gRPC server.



```go
func main() {
  // assign port
  Port := os.Getenv("PORT")
    if Port == "" {
        Port = "5000"// port default : 5000 if in env port is not set
    } 

  // initiate listener
    listen, err := net.Listen("tcp", Port)
    if err != nil {
        log.Fatalf("Could not listen @ %v :: %v", Port, err)
    }
  log.Println("Listening @ "+Port)  

    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a gRPC server instance that would listen and server through assigned &lt;code&gt;Port&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;grpcServer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewServer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;grpcServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to start gRPC server :: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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;Though we have created and also can run the gRPC server, it will not do anything impressive. Let's create a &lt;code&gt;chatserver.go&lt;/code&gt; file that invokes interfaces defined in  &lt;code&gt;chatserver.pb.go&lt;/code&gt; file which will help to establish &lt;strong&gt;bidirectional stream&lt;/strong&gt; between server and client. &lt;/p&gt;

&lt;h3&gt;
  
  
  Create chatserver.go file under
&lt;/h3&gt;

&lt;p&gt;&lt;br&gt;
 &lt;code&gt;package chatserver&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Let's create a new file named as&lt;code&gt;chatserver.go&lt;/code&gt; inside &lt;strong&gt;chatserver&lt;/strong&gt; directory (this is the same directory that has &lt;code&gt;chatserver.pb.go&lt;/code&gt; file generated earlier through the proto compiler). &lt;/p&gt;

&lt;p&gt;Now, define a &lt;em&gt;struct&lt;/em&gt; &lt;code&gt;messageUnit&lt;/code&gt; for handling the message in the server. We also create another &lt;em&gt;struct&lt;/em&gt; &lt;code&gt;messageQue&lt;/code&gt; that basically  a slice &lt;code&gt;MQue&lt;/code&gt; of type &lt;code&gt;messageUnit&lt;/code&gt; and variable &lt;code&gt;mu&lt;/code&gt; of type &lt;code&gt;sync.Muex&lt;/code&gt; . Go &lt;code&gt;sync.Mutex&lt;/code&gt; implements memory &lt;code&gt;Lock()&lt;/code&gt; and &lt;code&gt;UnLock()&lt;/code&gt; which are used to avoid race conditions while accessing global variables asynchronously through multiple threads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;messageUnit&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ClientName&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;MessageBody&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;MessageUniqueCode&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;ClientUniqueCode&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;messageQue&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MQue&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;messageUnit&lt;/span&gt;
    &lt;span class="n"&gt;mu&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;messageQueObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messageQue&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In addition to the above, lets define a type &lt;em&gt;struct&lt;/em&gt; with name &lt;code&gt;ChatServer&lt;/code&gt; which implemets a method &lt;code&gt;ChatService&lt;/code&gt; as defined in &lt;strong&gt;chat.proto&lt;/strong&gt; file. &lt;code&gt;ChatService&lt;/code&gt; method takes an argument of type &lt;code&gt;Services_ChatServiceServer&lt;/code&gt; (defined in &lt;strong&gt;chatserver.pb.go&lt;/strong&gt; file) and returns &lt;code&gt;error&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type ChatServer struct {
}

//ChatService 
func (is *ChatServer) ChatService(csi Services_ChatServiceServer) error {

// ...

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, inside our &lt;code&gt;chatservice&lt;/code&gt; method we need to call two methods - one for receiving messages from stream and one for sending messages to stream. With &lt;code&gt;recieveFromStream&lt;/code&gt; method, we parse the message from the client and append it to our &lt;code&gt;messageQue&lt;/code&gt; object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// recieve from stream&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;recieveFromStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csi_&lt;/span&gt; &lt;span class="n"&gt;Services_ChatServiceServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clientUniqueCode_&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;csi_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Recv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error reciving request from client :: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;messageUnit&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ClientName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MessageBody&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MessageUniqueCode&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Intn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1e8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;ClientUniqueCode&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clientUniqueCode_&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unlock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="p"&gt;}&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;With &lt;code&gt;sendToStream&lt;/code&gt; method, we serialize the message from &lt;code&gt;messageQue&lt;/code&gt; and send it to the designated client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//send to stream&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;sendToStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csi_&lt;/span&gt; &lt;span class="n"&gt;Services_ChatServiceServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clientUniqueCode_&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errch_&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;500&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Millisecond&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unlock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;senderUniqueCode&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClientUniqueCode&lt;/span&gt;
            &lt;span class="n"&gt;senderName4client&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClientName&lt;/span&gt;
            &lt;span class="n"&gt;message4client&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MessageBody&lt;/span&gt;
            &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unlock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;senderUniqueCode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;clientUniqueCode_&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;csi_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;FromServer&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;senderName4client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message4client&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;errch_&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c"&gt;// if send success &amp;gt; delete message&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MQue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;messageUnit&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;messageQueObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unlock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

            &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&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;Let's call both &lt;code&gt;recieveFromStream&lt;/code&gt; and &lt;code&gt;sendToStream&lt;/code&gt; method from &lt;code&gt;ChatService&lt;/code&gt; method through &lt;code&gt;go&lt;/code&gt; routines. We have created one channel of type &lt;code&gt;error&lt;/code&gt; which is used to pass error, if any, to the client during sending message to stream; the same error also would lead to termination of the connection from server-side. Every time a client connects to the server, two &lt;code&gt;go&lt;/code&gt; routines would be spawned for recieving and sending messages. Whenever multiple Go-routines asynchronously access a variable (memory location), mutex blocking is used above to avoid &lt;strong&gt;Race condition&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// ChatService  &lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ChatServer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ChatService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csi&lt;/span&gt; &lt;span class="n"&gt;Services_ChatServiceServer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;clientUniqueCode&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Intn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1e3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// recieve request &amp;lt;&amp;lt;&amp;lt; client&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;recieveFromStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clientUniqueCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;//stream &amp;gt;&amp;gt;&amp;gt; client&lt;/span&gt;
    &lt;span class="n"&gt;errch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;sendToStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clientUniqueCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;errch&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we need to register &lt;code&gt;ChatService&lt;/code&gt; by adding the following two lines in &lt;strong&gt;server.go&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// register ChatService&lt;/span&gt;
    &lt;span class="n"&gt;cs&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;chatserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ChatServer&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;chatserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterServicesServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;grpcServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with this, we have finished our serverside code for gRPC bidirectional streaming. We can choose any language that supports gRPC for creating client stub. For simplicity, in this post let's create our client-side program in &lt;strong&gt;Golang&lt;/strong&gt;. The &lt;code&gt;chatserver.pb.go&lt;/code&gt; file also includes interfaces for the client. &lt;/p&gt;

&lt;h3&gt;
  
  
  Create &lt;code&gt;client.go&lt;/code&gt; for client side stubs
&lt;/h3&gt;

&lt;p&gt;let's create a &lt;strong&gt;client.go&lt;/strong&gt; file in our project root directory. The main intention now is to have two clients that would first establish bidirectional streaming connections with the server and then chat with each other. In this post, we will be using the &lt;strong&gt;console&lt;/strong&gt; in the terminal for posting and receiving messages.&lt;/p&gt;

&lt;p&gt;For the sake of simplicity, in this post, we have two clients who communicate through one-to-one message. Clients shall have a name and would be able to send and receive messages. Let's define a struct &lt;code&gt;clientHandle&lt;/code&gt; which basically has two fields one is &lt;code&gt;clientName&lt;/code&gt; and the second one is the &lt;code&gt;stream&lt;/code&gt;. &lt;code&gt;clientHandle&lt;/code&gt; implements two methods one for sending message &lt;code&gt;sendMessage&lt;/code&gt; and one for receiving message &lt;code&gt;receiveMessage&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;clientHandle&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;stream&lt;/span&gt;     &lt;span class="n"&gt;chatserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services_ChatServiceClient&lt;/span&gt;
    &lt;span class="n"&gt;clientName&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Assign name&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;clientHandle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;clientConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bufio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stdin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Your Name : "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'\n'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to read from console :: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clientName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TrimRight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// send Message&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;clientHandle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bufio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stdin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;clientMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'\n'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;clientMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TrimRight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clientMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to read from console :: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;clientMessageBox&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;chatserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromClient&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clientName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clientMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clientMessageBox&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error while sending to server :: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// receive message&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;clientHandle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;receiveMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Recv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"can not receive %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s : %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&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;In the main function, the client dial gRPC server addressing the port that the server is listening to. The &lt;code&gt;client.ChatService&lt;/code&gt; method is called with a &lt;code&gt;context&lt;/code&gt; to initiate a bidirectional stream between the client and the gRPC server.  Next, we are running &lt;code&gt;sendMessage&lt;/code&gt; and &lt;code&gt;receiveMessage&lt;/code&gt; loops in separate go-routines. The main method is blocked by a dummy &lt;code&gt;chan&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;serverID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"localhost:5000"&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connecting : "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;serverID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serverID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithInsecure&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to connect gRPC server :: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;chatserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewServicesClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ChatService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to get response from gRPC server :: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;clientHandle&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clientConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;receiveMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// block main&lt;/span&gt;
    &lt;span class="n"&gt;bl&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;bl&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are done!  Let's type the following commands on the terminal to run our gRPC chatserver and clients.&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;# run server (Termina-1)&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;env &lt;/span&gt;&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5000 go run server.go

&lt;span class="c"&gt;# Run client.go file in two separate terminals (Terminal -2 and Terminal -3)&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;go run server.go

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1613825447861%2FqO2fd65g4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1613825447861%2FqO2fd65g4.png" alt="server.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1613825464399%2F5JPsIAc3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1613825464399%2F5JPsIAc3s.png" alt="clients.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope, you enjoyed this post. I would appreciate your feedback/suggestions/comments in the comment section below.&lt;/p&gt;

&lt;p&gt;Thanks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Follow Me :
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UCMat0Hlx67xwLrhIKRWMjEw" rel="noopener noreferrer"&gt;YouTube CodeFuture&lt;/a&gt; , &lt;a href="https://twitter.com/Code9Rrr" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Link to GitHub :
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/rrrCode9/gRPC-Bidirectional-Streaming-ChatServer.git" rel="noopener noreferrer"&gt;https://github.com/rrrCode9/gRPC-Bidirectional-Streaming-ChatServer.git&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Useful Links :
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/protocolbuffers/protobuf/releases" rel="noopener noreferrer"&gt;protobuf compiler&lt;/a&gt;, &lt;a href="https://grpc.io/" rel="noopener noreferrer"&gt;grpc.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;** #gRPC #BidirectionalStreaming #Golang #chatServer **&lt;/p&gt;

</description>
      <category>grpc</category>
      <category>go</category>
      <category>chatserver</category>
      <category>bidirectionalstreaming</category>
    </item>
  </channel>
</rss>
