<?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: GGL Tech</title>
    <description>The latest articles on DEV Community by GGL Tech (@ggl-tech).</description>
    <link>https://dev.to/ggl-tech</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%2Forganization%2Fprofile_image%2F6430%2F586cccf5-df73-4f1b-8e13-98db28aa4f50.png</url>
      <title>DEV Community: GGL Tech</title>
      <link>https://dev.to/ggl-tech</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ggl-tech"/>
    <language>en</language>
    <item>
      <title>Getting Started with Tinode: An Open-Source Messaging Platform</title>
      <dc:creator>Fahmi Mahmud Maliki</dc:creator>
      <pubDate>Fri, 15 Mar 2024 01:25:07 +0000</pubDate>
      <link>https://dev.to/ggl-tech/getting-started-with-tinode-an-open-source-messaging-server-4f16</link>
      <guid>https://dev.to/ggl-tech/getting-started-with-tinode-an-open-source-messaging-server-4f16</guid>
      <description>&lt;p&gt;Do you need to build a chat service and have no time to develop the service from scratch? Calm down! There is an open-source solution to answer your problem.&lt;br&gt;
In this post, we will explore &lt;a href="https://tinode.co/" rel="noopener noreferrer"&gt;tinode&lt;/a&gt; to solve our problem&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Tinode?
&lt;/h2&gt;

&lt;p&gt;Tinode is an open-source messaging platform written in Go. It can be used to build real-time messaging applications.&lt;/p&gt;

&lt;p&gt;From their official site&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tinode is a free, unlimited, and flexible open source messaging platform that’s been built mobile-first.&lt;/p&gt;

&lt;p&gt;Instant, free, global communication should be a fundamental feature of today's internet. Our aim is to enable everyone to create a high-quality chat experience outside of the walled gardens that exist today.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;In this section, we will only explain running a tinode server with binary and docker using Linux.&lt;/p&gt;
&lt;h3&gt;
  
  
  Install from binaries
&lt;/h3&gt;

&lt;p&gt;Before following below step, make sure our database is already running&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the Tinode binary on their &lt;a href="https://github.com/tinode/chat/releases/" rel="noopener noreferrer"&gt;release page&lt;/a&gt;
. We will use &lt;a href="https://github.com/tinode/chat/releases/download/v0.22.12/tinode-alldbs.linux-amd64.tar.gz" rel="noopener noreferrer"&gt;v0.22.12&lt;/a&gt; alldbs for Linux in this example
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://github.com/tinode/chat/releases/download/v0.22.12/tinode-alldbs.linux-amd64.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Create a new directory and extract the binary to the new directory
&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="nb"&gt;mkdir &lt;/span&gt;tinode-chat
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xvf&lt;/span&gt; tinode-alldbs.linux-amd64.tar.gz &lt;span class="nt"&gt;-C&lt;/span&gt; tinode-chat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Set the Tinode configuration by editing a configuration file named &lt;code&gt;tinode.conf&lt;/code&gt; in the same directory as the Tinode binary.
&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="nb"&gt;cd &lt;/span&gt;tinode-chat
vim tinode.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Change the &lt;code&gt;use_adapter&lt;/code&gt;, &lt;code&gt;User&lt;/code&gt;, &lt;code&gt;Addr&lt;/code&gt;, &lt;code&gt;Passwd&lt;/code&gt;, and &lt;code&gt;DBName&lt;/code&gt; values on the DB connection configuration section. In this example, we will use the MySQL database.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;                // &lt;span class="n"&gt;Must&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;adapters&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="n"&gt;below&lt;/span&gt;.
                &lt;span class="s2"&gt;"use_adapter"&lt;/span&gt;: &lt;span class="s2"&gt;"mysql"&lt;/span&gt;,

                // &lt;span class="n"&gt;Configurations&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;individual&lt;/span&gt; &lt;span class="n"&gt;adapters&lt;/span&gt;.
                &lt;span class="s2"&gt;"adapters"&lt;/span&gt;: {
                        // &lt;span class="n"&gt;MySQL&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;. &lt;span class="n"&gt;See&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;://&lt;span class="n"&gt;godoc&lt;/span&gt;.&lt;span class="n"&gt;org&lt;/span&gt;/&lt;span class="n"&gt;github&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;/&lt;span class="n"&gt;go&lt;/span&gt;-&lt;span class="n"&gt;sql&lt;/span&gt;-&lt;span class="n"&gt;driver&lt;/span&gt;/&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="c"&gt;#Config
&lt;/span&gt;                        // &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;possible&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;.
                        &lt;span class="s2"&gt;"mysql"&lt;/span&gt;: {
                                // &lt;span class="n"&gt;MySQL&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;.
                                // &lt;span class="n"&gt;See&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;://&lt;span class="n"&gt;pkg&lt;/span&gt;.&lt;span class="n"&gt;go&lt;/span&gt;.&lt;span class="n"&gt;dev&lt;/span&gt;/&lt;span class="n"&gt;github&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;/&lt;span class="n"&gt;go&lt;/span&gt;-&lt;span class="n"&gt;sql&lt;/span&gt;-&lt;span class="n"&gt;driver&lt;/span&gt;/&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="c"&gt;#Config for more info
&lt;/span&gt;                                // &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;.
                                &lt;span class="s2"&gt;"User"&lt;/span&gt;: &lt;span class="s2"&gt;"db_username"&lt;/span&gt;,
                                &lt;span class="s2"&gt;"Net"&lt;/span&gt;: &lt;span class="s2"&gt;"tcp"&lt;/span&gt;,
                                &lt;span class="s2"&gt;"Addr"&lt;/span&gt;: &lt;span class="s2"&gt;"db_host"&lt;/span&gt;,
                                &lt;span class="s2"&gt;"Passwd"&lt;/span&gt;: &lt;span class="s2"&gt;"db_password"&lt;/span&gt;,
                                &lt;span class="s2"&gt;"DBName"&lt;/span&gt;: &lt;span class="s2"&gt;"db_name"&lt;/span&gt;,
                                // &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="s1"&gt;'collation=utf8mb4_unicode_ci'&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;optional&lt;/span&gt; &lt;span class="n"&gt;but&lt;/span&gt; &lt;span class="n"&gt;highly&lt;/span&gt; &lt;span class="n"&gt;recommended&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt;
                                // &lt;span class="n"&gt;emoji&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;certain&lt;/span&gt; &lt;span class="n"&gt;CJK&lt;/span&gt; &lt;span class="n"&gt;characters&lt;/span&gt;.
                                &lt;span class="s2"&gt;"Collation"&lt;/span&gt;: &lt;span class="s2"&gt;"utf8mb4_unicode_ci"&lt;/span&gt;,
                                // &lt;span class="n"&gt;Parse&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;.&lt;span class="n"&gt;Time&lt;/span&gt;. &lt;span class="n"&gt;Required&lt;/span&gt;.
                                &lt;span class="s2"&gt;"ParseTime"&lt;/span&gt;: &lt;span class="n"&gt;true&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Run the database initializer &lt;code&gt;init-db&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;./init-db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2024/03/14 04:23:49 Database adapter: 'mysql'; version: 113
2024/03/14 04:23:49 Database not found. Creating.
2024/03/14 04:23:59 Database successfully created.
2024/03/14 04:23:59 No data provided, stopping
2024/03/14 04:23:59 All done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to generate user data when initializing the database, we can use json file to generate the data for the database. The json format example from official docs &lt;a href="https://github.com/tinode/chat/blob/master/tinode-db/data.json" rel="noopener noreferrer"&gt;data.json&lt;/a&gt;. To init the database by generating data from the json file execute the below 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="c"&gt;# This command will initialize the database and generate example users like Bob or Alice&lt;/span&gt;
./init-db &lt;span class="nt"&gt;-data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;data.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output example while init-db with generating data from json file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2024/03/14 04:27:11 Database adapter: 'mysql'; version: 113
2024/03/14 04:27:11 Database not found. Creating.
2024/03/14 04:27:16 Database successfully created.
2024/03/14 04:27:16 Generating users...
usr;alice;usrDUuFy6DahqY;alice123
usr;bob;usr8jmNzPuC2Hk;bob123
2024/03/14 04:27:17 Generating group topics...
grp;*ABC;grpNjtGeGveyEs
grp;*ABCDEF;grp7tR9jTaFl00
grp;*BACDF;grptKswCQFaZdY
2024/03/14 04:27:17 Generating P2P subscriptions...
p2p;alice:bob;p2p8jmNzPuC2HkNS4XLoNqGpg
2024/03/14 04:27:17 Generating group subscriptions...
2024/03/14 04:27:17 Inserting messages...
2024/03/14 04:27:18 Inserting forms as  tino IFHqLxWfylQ
2024/03/14 04:27:19 Sample data processing completed.
2024/03/14 04:27:19 All done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;After the database is initialized, run the tinode server
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./tinode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the Tinode server is started, you can access the Tinode web interface by opening a web browser and navigating to the following URL: &lt;a href="http://localhost:6060" rel="noopener noreferrer"&gt;http://localhost:6060&lt;/a&gt;&lt;br&gt;
Login Interface&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc16djjjs3nyb4nvy565p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc16djjjs3nyb4nvy565p.png" alt="Tinode login interface" width="800" height="386"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Example User | user:password
alice:alice123
bob:bob123
eve:eve123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logged in Interface&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhi367ezk6mgf802f73ep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhi367ezk6mgf802f73ep.png" alt="Tinode logged-in interface" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You have successfully installed the Tinode binary on your system. You can now start using Tinode as a standalone messaging server or integrate it with other applications for real-time communication. For more information on how to use Tinode, you can refer to the &lt;a href="https://github.com/tinode/chat/blob/master/INSTALL.md" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Run with docker
&lt;/h3&gt;

&lt;p&gt;To save time, we will use docker compose to run the tinode server&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create &lt;code&gt;tinode-docker&lt;/code&gt; directory and create docker-compose.yml inside it
&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="nb"&gt;mkdir &lt;/span&gt;tinode-docker
&lt;span class="nb"&gt;cd &lt;/span&gt;tinode-docker
vim docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Copy the below code to our &lt;code&gt;docker-compose.yml&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mysql&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mysql:8"&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_ALLOW_EMPTY_PASSWORD=yes&lt;/span&gt; &lt;span class="c1"&gt;# Not recommended in prod&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db-data:/var/lib/mysql&lt;/span&gt;

  &lt;span class="na"&gt;tinode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tinode/tinode-mysql:0.22.12"&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tinode&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;on-failure&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;6060:6060"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;16060:16060"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mysql&lt;/span&gt;
    &lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mysql&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run the tinode server
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Taraa!! Our messaging server is ready to use&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F339a84ix6gnl7oge60lq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F339a84ix6gnl7oge60lq.png" alt="Tinode running by docker compose" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>chat</category>
      <category>tinode</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
