발행·구독은 발행자와 구독자 사이에 토픽을 둡니다. 발행자는 누가 듣는지 몰라도 되고, 한 메시지를 여러 구독자에게 전달할 수 있습니다. 작업 한 건을 소비자 하나에게 주는 큐와 달리 각 구독자가 같은 사건에 반응합니다.
데모에서는 토픽을 바꾸면 수신자 집합이 달라집니다. 전달 보장, 중복, 늦게 합류한 구독자의 재생 가능 여부는 브로커 설정에 따라 다릅니다.
언제 쓰나
한 사건을 알림·분석 등 여러 기능에 동시에 전달할 때 사용합니다.
발행자가 토픽에 메시지를 보내면 각 구독자가 독립적으로 사본을 받습니다.
<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>.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)}}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)발행·구독은 발행자와 구독자 사이에 토픽을 둡니다. 발행자는 누가 듣는지 몰라도 되고, 한 메시지를 여러 구독자에게 전달할 수 있습니다. 작업 한 건을 소비자 하나에게 주는 큐와 달리 각 구독자가 같은 사건에 반응합니다.
데모에서는 토픽을 바꾸면 수신자 집합이 달라집니다. 전달 보장, 중복, 늦게 합류한 구독자의 재생 가능 여부는 브로커 설정에 따라 다릅니다.
한 사건을 알림·분석 등 여러 기능에 동시에 전달할 때 사용합니다.