diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2023-10-31 18:02:35 +0100 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2023-10-31 18:02:35 +0100 |
| commit | cc492b31774be0f98ae9152d0f272324c415e4d8 (patch) | |
| tree | 54814afa8ce1f81785edfe95b62bac2c0e811b43 /public/simple-server-sent-events-based-pubsub-server.html | |
| parent | fd3a6a3730d4078f6be4239a9c24c9747ef9d555 (diff) | |
| download | mitjafelicijan.com-cc492b31774be0f98ae9152d0f272324c415e4d8.tar.gz | |
Theme update
Diffstat (limited to 'public/simple-server-sent-events-based-pubsub-server.html')
| -rwxr-xr-x | public/simple-server-sent-events-based-pubsub-server.html | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/public/simple-server-sent-events-based-pubsub-server.html b/public/simple-server-sent-events-based-pubsub-server.html index 9115ab1..93853b1 100755 --- a/public/simple-server-sent-events-based-pubsub-server.html +++ b/public/simple-server-sent-events-based-pubsub-server.html | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | <!doctype html><html lang=en-us><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=generator content="JBMAFP - github.com/mitjafelicijan/jbmafp"><link href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL69vf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv76+/8LBwQkAAAAAAAAAAAAAAAC+vb3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+9vf/Bv78JAAAAAAAAAAAAAAAAu7q6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7ubr/vr29CAAAAAAAAAAAy8nJAZ6foP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnqGj/6GipAoAAAAAHLjU/xcXHf/BwsL/I8XY/yPK3v8XGiD/IbjL/yPF2f8XGiD/Fxkf/yLF2f8gnK3/Fxog/62ztv8fwNf/FRcd/x271v8mz93/GRsi/xkXHf8p097/GiIp/xobIv8p0t3/KdPe/xocIv8fYmr/KNPe/xoZH/8aHCL/J87c/xy81/8VFxz/IsPZ/8zS0/8XGiD/Ir/R/yPH2/8XGiD/Fxkf/yPH2/8dd4T/GBog/yPJ3f8jyNr/uru9/xcUGv8cudb/EhITDKi5vRKlvMP/RUpOERwcHRAdOj4QHTk8EBwdHRAdNTgQHTo/EBwcHRAcHB0QSGduEKW4vf+koqQfHzg+EBqz0ewSFRv7EyMr/xq51vsTERb7ExUb+xq41fsau9j7ExUb+xiPp/sZudb7ExUb+xMVG/sZuNX/GKvI/BIUGfMdvdn/IrfL/xcaIP8n1eb/J9Dh/xkcIf8ZGR7/J8/f/xxCSv8ZGyH/J9Dg/ybQ4P8ZHCL/FSQs/yPK3/8UExj/GE1b/ybS5P8ZGB7/Ghwj/ynW5P8p2Ob/Ghwi/yWrtv8p1eH/Ghwi/xocIv8p1uT/J8XT/xkcIv8m1un/Hb7d/xUYH/8hzOr/HtHu/xcaIf8XGB//I8vi/xgxOv8XGSD/I8rg/yPK4P8XGiD/GUFL/yPP6f8SERj/Fhkh/x3A4f8AAAAAJ2f9/ydr//8mZPH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlYu38J2v//ydo/f8AAAAAAAAAAAd8/fkFqf//Iob8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMY39awWr//8FfP3/AAAAAAAAAAAFm/7/SfD//wR+/f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOB/f9B7v//BaX+/wAAAAAAAAAAQ878SAyZ/v9n1v4KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADu9v8DDJb+/z3N/XgAAAAA3/sAAN/7AADf+wAA3/sAAAAAAAAAAAAAAAAAAN/7AAAAAAAAAAAAAAAAAAAAAAAAj/EAAI/5AACP8QAA3/sAAA==" rel=icon type=image/x-icon><title>Simple Server-Sent Events based PubSub Server</title><meta name=description content="Before we continue ."><meta name=author content="Mitja Felicijan"><link rel=alternate type=application/rss+xml title="Mitja Felicijan's posts" href=https://mitjafelicijan.com/index.xml><link rel=alternate type=application/rss+xml title="Mitja Felicijan's notes" href=https://mitjafelicijan.com/notes.xml><style>:root{--border-color:gainsboro;--border-size:2px;--link-color:blue;--bg-color:#eee}*::selection{background:var(--link-color);color:#fff}*::-moz-selection{background:var(--link-color);color:#fff}*::-webkit-selection{background:var(--link-color);color:#fff}body{padding:2.5rem;max-width:1900px;background:#fff;font-family:sans-serif;line-height:1.35rem;font-size:16px}hr{border:0;border-bottom:var(--border-size)solid var(--border-color);margin-block-start:1.5rem}a{color:var(--link-color);text-decoration:none}h1,h2,h3{line-height:initial}h1{font-size:xx-large}footer{margin-block-start:2rem}cap{text-transform:capitalize}blockquote{font-style:italic}table{max-width:100%;border:var(--border-size)solid var(--border-color);border-collapse:separate;border-spacing:0}table thead tr th{border-bottom:var(--border-size)solid var(--border-color);text-align:left}table th,table td{padding:.5em .8em}ul.list li{padding:.2em 0}ul{line-height:1.35em}pre{text-wrap:nowrap;overflow-x:auto;padding:0 1em;border:var(--border-size)solid var(--border-color)}code{padding:0 3px;font-size:14px;border:0;background:var(--bg-color)}pre code{line-height:1.3em;background:#fff}pre,code,pre *,code *{font-family:monospace}figure{margin-inline-start:0;margin-inline-end:0}figcaption{width:800px;max-width:100%;text-align:center}figcaption p{margin:.3em 0 1.5em;font-style:italic}img,video,audio{width:800px;max-width:100%;border:var(--border-size)solid var(--border-color);padding:.5em}header nav{display:flex;gap:.9rem}article iframe{margin:0!important}audio::-webkit-media-controls-enclosure{border-radius:0}@media only screen and (max-width:600px){body{padding:.5em;word-wrap:break-word}header nav{gap:.7rem}header nav .hob{display:none}a{word-wrap:break-word}}</style><header><nav class=main itemscope itemtype=http://schema.org/SiteNavigationElement role=toolbar><a href=/>Home</a> | 1 | <!doctype html><html lang=en-us><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=generator content="JBMAFP - github.com/mitjafelicijan/jbmafp"><link href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL69vf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv76+/8LBwQkAAAAAAAAAAAAAAAC+vb3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+9vf/Bv78JAAAAAAAAAAAAAAAAu7q6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7ubr/vr29CAAAAAAAAAAAy8nJAZ6foP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnqGj/6GipAoAAAAAHLjU/xcXHf/BwsL/I8XY/yPK3v8XGiD/IbjL/yPF2f8XGiD/Fxkf/yLF2f8gnK3/Fxog/62ztv8fwNf/FRcd/x271v8mz93/GRsi/xkXHf8p097/GiIp/xobIv8p0t3/KdPe/xocIv8fYmr/KNPe/xoZH/8aHCL/J87c/xy81/8VFxz/IsPZ/8zS0/8XGiD/Ir/R/yPH2/8XGiD/Fxkf/yPH2/8dd4T/GBog/yPJ3f8jyNr/uru9/xcUGv8cudb/EhITDKi5vRKlvMP/RUpOERwcHRAdOj4QHTk8EBwdHRAdNTgQHTo/EBwcHRAcHB0QSGduEKW4vf+koqQfHzg+EBqz0ewSFRv7EyMr/xq51vsTERb7ExUb+xq41fsau9j7ExUb+xiPp/sZudb7ExUb+xMVG/sZuNX/GKvI/BIUGfMdvdn/IrfL/xcaIP8n1eb/J9Dh/xkcIf8ZGR7/J8/f/xxCSv8ZGyH/J9Dg/ybQ4P8ZHCL/FSQs/yPK3/8UExj/GE1b/ybS5P8ZGB7/Ghwj/ynW5P8p2Ob/Ghwi/yWrtv8p1eH/Ghwi/xocIv8p1uT/J8XT/xkcIv8m1un/Hb7d/xUYH/8hzOr/HtHu/xcaIf8XGB//I8vi/xgxOv8XGSD/I8rg/yPK4P8XGiD/GUFL/yPP6f8SERj/Fhkh/x3A4f8AAAAAJ2f9/ydr//8mZPH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlYu38J2v//ydo/f8AAAAAAAAAAAd8/fkFqf//Iob8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMY39awWr//8FfP3/AAAAAAAAAAAFm/7/SfD//wR+/f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOB/f9B7v//BaX+/wAAAAAAAAAAQ878SAyZ/v9n1v4KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADu9v8DDJb+/z3N/XgAAAAA3/sAAN/7AADf+wAA3/sAAAAAAAAAAAAAAAAAAN/7AAAAAAAAAAAAAAAAAAAAAAAAj/EAAI/5AACP8QAA3/sAAA==" rel=icon type=image/x-icon><title>Simple Server-Sent Events based PubSub Server</title><meta name=description content="Before we continue ."><meta name=author content="Mitja Felicijan"><link rel=alternate type=application/rss+xml title="Mitja Felicijan's posts" href=https://mitjafelicijan.com/index.xml><link rel=alternate type=application/rss+xml title="Mitja Felicijan's notes" href=https://mitjafelicijan.com/notes.xml><style>:root{--border-color:gainsboro;--border-size:2px;--link-color:blue;--bg-color:#eee}*::selection{background:var(--link-color);color:#fff}*::-moz-selection{background:var(--link-color);color:#fff}*::-webkit-selection{background:var(--link-color);color:#fff}body{padding:2.5rem;max-width:1900px;background:#fff;font-family:sans-serif;line-height:1.35rem;font-size:16px}hr{border:0;border-bottom:var(--border-size)solid var(--border-color);margin-block-start:1.5rem}a{color:var(--link-color);text-decoration:none}h1,h2,h3{line-height:initial}h1{font-size:xx-large}footer{margin-block-start:2rem}cap{text-transform:capitalize}blockquote{font-style:italic}table{max-width:100%;border:var(--border-size)solid var(--border-color);border-collapse:separate;border-spacing:0}table thead tr th{border-bottom:var(--border-size)solid var(--border-color);text-align:left}table th,table td{padding:.5em .8em}ul.list li{padding:.2em 0}ul{line-height:1.35em}pre{text-wrap:nowrap;overflow-x:auto;padding:0 1em;border:var(--border-size)solid var(--border-color)}code{padding:0 3px;font-size:14px;border:0;background:var(--bg-color)}pre code{line-height:1.3em;background:#fff}pre,code,pre *,code *{font-family:monospace}figure{margin-inline-start:0;margin-inline-end:0}figcaption{width:800px;max-width:100%;text-align:center}figcaption p{margin:.3em 0 1.5em;font-style:italic}img,video,audio{width:800px;max-width:100%;border:var(--border-size)solid var(--border-color);padding:.5em}header nav{display:flex;gap:.9rem}article iframe{margin:0!important}audio::-webkit-media-controls-enclosure{border-radius:0}@media only screen and (max-width:600px){body{padding:.5em;word-wrap:break-word}header nav{gap:.7rem}header nav .hob{display:none}a{word-wrap:break-word}}</style><header><nav class=main itemscope itemtype=http://schema.org/SiteNavigationElement role=navigation aria-label="Main navigation"><a href=/>Home</a> |
| 2 | <a href=/#posts>Posts</a> | 2 | <a href=/#posts>Posts</a> |
| 3 | <a href=/#notes>Notes</a> | 3 | <a href=/#notes>Notes</a> |
| 4 | <a href=/#sideprojects class=hob>Side Projects</a> | 4 | <a href=/#sideprojects class=hob>Side Projects</a> |
| @@ -22,7 +22,7 @@ Events</a> | |||
| 22 | to all the subscribers.</ul><h2 id=how-exactly-does-the-pubsub-model-work>How exactly does the pub/sub model work?</h2><p>The easiest way to explain this is with diagram bellow. Basic function is | 22 | to all the subscribers.</ul><h2 id=how-exactly-does-the-pubsub-model-work>How exactly does the pub/sub model work?</h2><p>The easiest way to explain this is with diagram bellow. Basic function is |
| 23 | simple. We have subscribers that receive messages, and we have publishers that | 23 | simple. We have subscribers that receive messages, and we have publishers that |
| 24 | create and post messages. Similar model is also well know pattern that works on | 24 | create and post messages. Similar model is also well know pattern that works on |
| 25 | a premise of consumers and producers, and they take similar roles.<figure><img loading="lazy" src=/posts/simple-pubsub-server/pubsub-overview.png alt="How PubSub works"></figure><p><strong>These are some naive characteristics we want to achieve:</strong><ul><li>producer is publishing messages to subscribe topic,<li>consumer is receiving messages from subscribed topic,<li>servers is also known as Broker,<li>broker does not store messages or tracks success,<li>broker uses | 25 | a premise of consumers and producers, and they take similar roles.<figure><img src=/posts/simple-pubsub-server/pubsub-overview.png alt="How PubSub works"></figure><p><strong>These are some naive characteristics we want to achieve:</strong><ul><li>producer is publishing messages to subscribe topic,<li>consumer is receiving messages from subscribed topic,<li>servers is also known as Broker,<li>broker does not store messages or tracks success,<li>broker uses |
| 26 | <a href=https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)>FIFO</a> method | 26 | <a href=https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)>FIFO</a> method |
| 27 | for delivering messages,<li>if consumer wants to receive messages from a topic, producer and consumer | 27 | for delivering messages,<li>if consumer wants to receive messages from a topic, producer and consumer |
| 28 | topics must match,<li>consumer can subscribe to multiple topics,<li>producer can publish to multiple topics,<li>each message has a messageId.</ul><p><strong>Known drawbacks:</strong><ul><li>messages will not be stored in a persistent queue or unreceived messages like | 28 | topics must match,<li>consumer can subscribe to multiple topics,<li>producer can publish to multiple topics,<li>each message has a messageId.</ul><p><strong>Known drawbacks:</strong><ul><li>messages will not be stored in a persistent queue or unreceived messages like |
| @@ -32,7 +32,7 @@ Events</a> | |||
| 32 | opens a long-running connection between the client and the server so make sure | 32 | opens a long-running connection between the client and the server so make sure |
| 33 | if your setup is load balanced that the load balancer in this case can have | 33 | if your setup is load balanced that the load balancer in this case can have |
| 34 | long opened connection,<li>no system moderation due to the dynamic nature of creating queues.</ul><h2 id=server-sent-events>Server-Sent Events</h2><p>Read more about it on <a href=https://html.spec.whatwg.org/multipage/server-sent-events.html>official specification | 34 | long opened connection,<li>no system moderation due to the dynamic nature of creating queues.</ul><h2 id=server-sent-events>Server-Sent Events</h2><p>Read more about it on <a href=https://html.spec.whatwg.org/multipage/server-sent-events.html>official specification |
| 35 | page</a>.<h3 id=current-browser-support>Current browser support</h3><figure><img loading="lazy" src=/posts/simple-pubsub-server/caniuse.png alt="Browser support"></figure><p>Check | 35 | page</a>.<h3 id=current-browser-support>Current browser support</h3><figure><img src=/posts/simple-pubsub-server/caniuse.png alt="Browser support"></figure><p>Check |
| 36 | <a href="https://caniuse.com/#feat=eventsource">https://caniuse.com/#feat=eventsource</a> | 36 | <a href="https://caniuse.com/#feat=eventsource">https://caniuse.com/#feat=eventsource</a> |
| 37 | for latest information about browser support.<h3 id=known-issues>Known issues</h3><ul><li>Firefox 52 and below do not support EventSource in web/shared workers<li>In Firefox prior to version 36 server-sent events do not reconnect | 37 | for latest information about browser support.<h3 id=known-issues>Known issues</h3><ul><li>Firefox 52 and below do not support EventSource in web/shared workers<li>In Firefox prior to version 36 server-sent events do not reconnect |
| 38 | automatically in case of a connection interrupt (bug)<li>Reportedly, CORS in EventSource is currently supported in Firefox 10+, Opera | 38 | automatically in case of a connection interrupt (bug)<li>Reportedly, CORS in EventSource is currently supported in Firefox 10+, Opera |
| @@ -55,7 +55,7 @@ server that triggers browser to threat response as a EventStream.<p>Headers resp | |||
| 55 | Events</a> | 55 | Events</a> |
| 56 | which is quite nice and available from Developer Tools under Network tab.<blockquote><p>You can debug only client side events that get received and not the server | 56 | which is quite nice and available from Developer Tools under Network tab.<blockquote><p>You can debug only client side events that get received and not the server |
| 57 | ones. For debugging server events add <code>console.log</code> to <code>server.js</code> code and | 57 | ones. For debugging server events add <code>console.log</code> to <code>server.js</code> code and |
| 58 | print out events.</blockquote><figure><img loading="lazy" src=/posts/simple-pubsub-server/chrome-debugging.png alt="Google Chrome Developer Tools EventStream"></figure><h2 id=server-implementation>Server implementation</h2><p>For the sake of this example we will use <a href=https://nodejs.org/en/>Node.js</a> with | 58 | print out events.</blockquote><figure><img src=/posts/simple-pubsub-server/chrome-debugging.png alt="Google Chrome Developer Tools EventStream"></figure><h2 id=server-implementation>Server implementation</h2><p>For the sake of this example we will use <a href=https://nodejs.org/en/>Node.js</a> with |
| 59 | <a href=https://expressjs.com>Express</a> as our router since this is the easiest way to | 59 | <a href=https://expressjs.com>Express</a> as our router since this is the easiest way to |
| 60 | get started and we will use already written SSE library for node | 60 | get started and we will use already written SSE library for node |
| 61 | <a href=https://www.npmjs.com/package/sse-pubsub>sse-pubsub</a> so we don't reinvent the | 61 | <a href=https://www.npmjs.com/package/sse-pubsub>sse-pubsub</a> so we don't reinvent the |
