Publish and subscribe

발행·구독

A publisher sends to a topic and each subscriber receives its own copy.

···
html
<div class="scene"><div class="title">TOPIC BROADCAST</div><div class="topicbar"><span id="topicA">orders</span><span id="topicB">payments</span></div><div class="row"><div class="tile">PUBLISHER</div><div class="hub" id="hub">TOPIC</div><div class="subs"><div class="tile" id="sub1">EMAIL</div><div class="tile" id="sub2">STATS</div><div class="tile" id="sub3">LEDGER</div></div></div><div class="muted" id="pubState">One event, independent copies</div></div>
css
.scene{width:min(94vw,760px);height:min(86vh,320px);padding:clamp(10px,2.5vmin,18px);border:1px solid var(--line);border-radius:14px;background:var(--surface);color:var(--fg);font:500 clamp(11px,1.3vw,16px)/1.25 "Pretendard Variable",Pretendard,-apple-system,sans-serif;display:flex;flex-direction:column;gap:clamp(7px,1.6vmin,12px);overflow:hidden}.scene *{box-sizing:border-box}.title{font-weight:750;color:var(--accent)}.muted{color:var(--muted)}.mono{font-family:ui-monospace,monospace}.row{display:flex;align-items:center;justify-content:center;gap:clamp(5px,1.4vmin,12px);flex:1;min-height:0}.tile{border:1px solid var(--line);border-radius:8px;background:var(--bg);padding:clamp(6px,1.6vmin,12px);text-align:center;min-width:0}.on{border-color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 12%,var(--surface))!important}.pulse{animation:pulse 1.6s infinite alternate}@keyframes pulse{to{border-color:var(--accent);transform:translateY(-3px)}}.topicbar{display:flex;gap:6px}.topicbar span{padding:3px 8px;border-radius:12px;border:1px solid var(--line)}.topicbar .selected{border-color:var(--accent);color:var(--accent)}.hub{border:2px solid var(--accent);border-radius:50%;width:24%;aspect-ratio:1;max-height:75px;display:grid;place-items:center;color:var(--accent);text-align:center}.row>.tile{flex:1}.subs{display:grid;gap:3px;flex:1}.subs .tile{padding:3px}.flash{color:var(--fg);animation:arrival .8s ease-out}@keyframes arrival{from{background:color-mix(in srgb,var(--accent) 34%,var(--surface))}to{background:var(--bg)}}
js
let phase=0;function tick(){const a=phase%2===0;document.getElementById('topicA').classList.toggle('selected',a);document.getElementById('topicB').classList.toggle('selected',!a);['sub1','sub2','sub3'].forEach((id,i)=>{const el=document.getElementById(id);el.classList.remove('flash');void el.offsetWidth;if((a&&i<2)||(!a&&i>0))el.classList.add('flash')});document.getElementById('hub').textContent=a?'ORDERS':'PAYMENTS';document.getElementById('pubState').textContent=a?'orders → email + stats':'payments → stats + ledger';phase++}tick();setInterval(tick,1600);document.querySelector('.scene').addEventListener('pointerdown',tick)

Publish and subscribe places a topic between producers and consumers. The publisher does not need to know its listeners, and several subscribers can receive the same event. Unlike a work queue that assigns one task to one worker, each subscriber reacts to the event.

Changing the topic in the demo changes the recipient set. Delivery guarantees, duplicates, and replay for late subscribers depend on the broker.

When to use

Use it when one event must reach independent capabilities such as notifications and analytics.

Open as page ↗