<?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>Forem: Rohit Dhas ⚡</title>
    <description>The latest articles on Forem by Rohit Dhas ⚡ (@rohitdhas).</description>
    <link>https://forem.com/rohitdhas</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%2F1109728%2F461edad6-b35f-479a-b2b7-eed08c2c55db.png</url>
      <title>Forem: Rohit Dhas ⚡</title>
      <link>https://forem.com/rohitdhas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rohitdhas"/>
    <language>en</language>
    <item>
      <title>How ChatGPT Uses Server-Sent Events to Stream Real-Time Conversation</title>
      <dc:creator>Rohit Dhas ⚡</dc:creator>
      <pubDate>Wed, 28 Jun 2023 07:21:49 +0000</pubDate>
      <link>https://forem.com/rohitdhas/how-chatgpt-uses-server-sent-events-to-stream-real-time-conversation-3976</link>
      <guid>https://forem.com/rohitdhas/how-chatgpt-uses-server-sent-events-to-stream-real-time-conversation-3976</guid>
      <description>&lt;p&gt;Whether you're a developer or not, you're probably using ChatGPT in your daily work. But have you ever wondered how ChatGPT manages to deliver real-time conversations that feel so incredibly human?&lt;/p&gt;

&lt;p&gt;In this article, I'll show you how the ChatGPT API uses SSE (Server-Sent Events) to stream responses in real time as they're being generated. Additionally, I'll guide you through the process of creating your own basic SSE endpoint using Node.js and Express.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  So what is SSE?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;In simple words, It's one request and a very long response.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;SSE is one of my favorite backend communication patterns. It allows a server to push data to a client as soon as it becomes available, without the client having to continuously ask or &lt;a href="https://www.geeksforgeeks.org/what-is-long-polling-and-short-polling/" rel="noopener noreferrer"&gt;poll&lt;/a&gt; the server for new data. This allows for real-time updates to be delivered to the client without the need for constant requests.&lt;/p&gt;

&lt;p&gt;In the case of ChatGPT, when you send a message, the server may immediately start generating a response using machine learning algorithms. As soon as the server generates a new piece of text, it can send it to the client using SSE, which allows the client to render the response as soon as it arrives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's worth noting that SSE is a unidirectional protocol, meaning that the client cannot send data back to the server using the same connection.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;Now that you're familiar with SSE, Let's try to implement a basic SSE endpoint using Node. JS &amp;amp; Express. JS.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To get started, Set up your Node.js project and install the necessary dependenciess&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="nb"&gt;mkdir &lt;/span&gt;sse-example
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;sse-example
&lt;span class="nv"&gt;$ &lt;/span&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;express


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Now, create a &lt;code&gt;index.js&lt;/code&gt; file and initialize an express app. Then define a route to handle SSE connection.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`  
    &amp;lt;!DOCTYPE html&amp;gt;  
    &amp;lt;html&amp;gt;  
        &amp;lt;body&amp;gt;  
            &amp;lt;h1&amp;gt;SSE Example:&amp;lt;/h1&amp;gt;  
            &amp;lt;div id="result"&amp;gt;&amp;lt;/div&amp;gt;  
            &amp;lt;script&amp;gt;  
                var source = new EventSource("/stream");  
                source.onmessage = function(event) {  
                document.getElementById("result").innerHTML += event.data + "&amp;lt;br&amp;gt;";  
                };  
            &amp;lt;/script&amp;gt;  
        &amp;lt;/body&amp;gt;  
    &amp;lt;/html&amp;gt;  
`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/stream&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Required header: It tells client that the response will be an event stream&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/event-stream&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;sendCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`data: Count: [&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]\n\n`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&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 me break down the code for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First there's a GET endpoint &lt;code&gt;("/")&lt;/code&gt;, that serves an HTML page.

&lt;ul&gt;
&lt;li&gt;The HTML page includes some markup and a script tag.&lt;/li&gt;
&lt;li&gt;Within the script tag, an &lt;code&gt;EventSource&lt;/code&gt; object is created with the URL &lt;code&gt;/stream&lt;/code&gt; to establish a connection between the client and the SSE endpoint.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;onmessage&lt;/code&gt; event listener is set on the &lt;code&gt;source&lt;/code&gt; object, for capturing events received from server.&lt;/li&gt;
&lt;li&gt;Inside the callback, we insert the data to the &lt;code&gt;div&lt;/code&gt; to display received message in HTML page.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Then there's GET endpoint &lt;code&gt;("/stream")&lt;/code&gt;, which will be used to stream real-time data.

&lt;ul&gt;
&lt;li&gt;I have created a function called &lt;code&gt;sendData&lt;/code&gt; that takes the response object and sends data every 1 second using &lt;code&gt;res.write&lt;/code&gt;. This mimics a real-world scenario where GPT generates responses through its machine learning algorithms.&lt;/li&gt;
&lt;li&gt;It is worth mentioning that you have to send the word &lt;code&gt;data:&lt;/code&gt; in every event because it determines the boundary of an event. By starting event data with word &lt;code&gt;data:&lt;/code&gt; and ending with &lt;code&gt;\n\n&lt;/code&gt;, allows clients to capture and parse the events correctly.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;After setting up these two endpoints, start the server and listen on port &lt;code&gt;8080&lt;/code&gt;.&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Server is listening on port 8080!&lt;/span&gt;&lt;span class="dl"&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;Now, Open your browser, and head over to &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You should see some text being rendered on the page every 1 second, representing the events received from the server.&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zobl2mxaxketdpvt0gh.gif" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zobl2mxaxketdpvt0gh.gif" alt="Screenshot"&gt;&lt;/a&gt;    &lt;/p&gt;

&lt;p&gt;This is just a basic implementation to get you started. You can build upon this foundation to create more complex SSE applications tailored to your specific needs.&lt;/p&gt;




&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>chatgpt</category>
      <category>sse</category>
      <category>firstpost</category>
    </item>
  </channel>
</rss>
