System Design: Hybrid WebApp using server sent event
Tags: systemdesign, realtime
Published: 2024-04-05 02:20:30

**What is a server sent event?**

A client subscribes to a “stream” from a server and the server will send messages (“event-stream”) to the client until the server or the client closes the stream

**Why such system design?**
I am required to design a system architecture that requires on-prem WebApp to be able to interact with Cloud Web App.

Cloud Web App will act as a SAAS service for on-prem WebApp. Each on-prem WebApp is unique for each building. I did the design using websocket and Apache Pulsar but realized that although these two were able to solve the problem, it took a lot more time and ended up dragging the deadline.

**Why do I choose a server sent event instead of websocket or publish subscribe mechanism like Apache Kafka or Apache Pulsar?**

1. Complexity on implementing
2. Complexity of hiring expertise
3. Complexity on distribution (Human Training)
4. Lack of team member (There only 2 of us)

**Diagram**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bcc1d45nkeyilvkxlly4.png)

**Laravel route code**
```
Route::get('/sse/{id}', function ($id) {
    $random_string = chr(rand(65, 90)) . chr(rand(65, 90)) . chr(rand(65, 90));
    $data = [
      'message' => $random_string,
      'name' => 'Sadhan Sarker',
      'time' => date('h:i:s'),
      'id' => $id,
    ];
    
    $response = new StreamedResponse();
    $response->setCallback(function () use ($data){
      echo 'data: ' . json_encode($data) . "\n\n";
      ob_flush();
      flush();
      usleep(200000);   
        
    });
    $response->headers->set('Content-Type', 'text/event-stream');
    $response->headers->set('X-Accel-Buffering', 'no');
    $response->headers->set('Cach-Control', 'no-cache');
    $response->headers->set('Access-Control-Allow-Origin', '*');
    $response->send();
});
```
**Nodejs EventSource client**
```
var ess = require('event-source-stream')
 
ess('http://mydomain.com/sse/1122')
  .on('data', function(data) {
    console.log('received event:', data)
  })
```

**NGINX Configuration**
```
server {
    listen 80;
    server_name mydomain.com;
    root /var/www/mydomain.com/wee/public;

    index index.html index.htm index.php;

    location / {
        ## try_files $uri $uri/ =404;
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
     }

    location ~ /\.ht {
        deny all;
    }
}
```
**Benefits on using server sent event**

1. Reduce complexity of entire system design. (Compared with websocket and pubsub)
2. Easier and faster to code.
3. Not require prior knowledge on websocket or pubsub.
4. Less changes on software distribution. (If you're in a desktop software business, even a slight changes will cause a lot of problems especially if you're dealing with non technical peoples)

Note that this blog post is meant to help you on designing your system better and give you a sense on where to start. The codes are merely just for education and demonstration purposes.Feel free to code based on your use case.

Peace out :)