添加链接
注册
登录
link管理
链接快照平台
输入网页链接,自动生成快照
标签化管理网页链接
相关文章推荐
独立的树叶
·
2023年河南省南阳市教育局所属学校教师招聘 ...
·
2 周前
·
痴情的机器猫
·
一对多关联 · ...
·
2 月前
·
爽快的盒饭
·
四川省人民检察院发布2019年公益诉讼典型案例
·
2 月前
·
深情的伤疤
·
教育部办公厅关于进一步做好普通高校毕业生就业 ...
·
3 月前
·
帅气的夕阳
·
Ajax Payment and ...
·
4 月前
·
link管理
›
Server-Sent Events: A WebSockets alternative ready for another look
https://ably.com/topic/server-sent-events
发呆的石榴
2 月前
</noscript><noscript/><nav class="ui-meganav-wrapper bg-white shadow-subtle" data-id="meganav" aria-label="Main"><div class="ui-meganav ui-grid-px"><div class="mr-24"><a href="/" data-id="meganav-logo" class="block" style="height:2.125rem"><img src="https://voltaire.ably.com/static/ably-logo-46433d9937b94509fc62ef6dd6d94ff1.png" width="108px" alt="Ably logo"/></a></div><ul class="hidden md:flex" data-id="meganav-items-desktop"><li class="ui-meganav-item"><button type="button" data-id="meganav-control" class="ui-meganav-link h-64 flex items-center group undefined text-cool-black" aria-expanded="false" aria-controls="products-panel" aria-label="Show Products panel"><span class="hidden lg:inline">Products</span><span class="lg:hidden">Products</span><svg class="text-cool-black transform rotate-90 group-hover:text-gui-hover group-focus:text-gui-focus" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg></button><div class="ui-meganav-panel invisible ui-meganav-panel-split-bg" id="products-panel" data-id="meganav-panel"><div class="flex max-w-screen-xl mx-auto"><div class="ui-meganav-content-spacer bg-extra-light-grey"/><section class="grid grid-cols-12 ui-grid-gap-x w-full"><div class="col-span-full md:col-span-4 py-24 lg:py-32 px-24 sm:px-32 md:pl-0 md:pr-24 bg-extra-light-grey"><div class="flex mb-20"><img src="https://voltaire.ably.com/static/ably-stack-05764a90f33eddbf5e18138b6574f282.svg" alt="Ably homepage"/><h3 class="ui-meganav-overline ml-24">The Ably Platform</h3></div><p class="ui-text-p2 font-bold mb-24" style="max-width:330px">Easily power any realtime experience in your application. No complex infrastructure to manage or provision. Just a simple API that handles everything realtime, and lets you focus on your code.</p><a href="/platform" class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group ui-text-p2 py-8 " style="--featured-link-icon-size:var(--fs-p2)">Explore how it works<svg class="text-cool-black align-middle ml-8 relative -top-1 -left-4 transition-all group-hover:left-0" style="width:calc(var(--featured-link-icon-size) * 1.25);height:calc(var(--featured-link-icon-size) * 1.25)"><use xlink:href="#sprite-icon-gui-link-arrow"/></svg></a></div><div class="col-span-full md:col-span-4 pt-24 pb-8 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0 bg-white"><h3 class="ui-meganav-overline" id="meganav-products-panel-list-examples">Products</h3><ul class="mb-16" aria-labelledby="meganav-products-panel-list-examples"><li><a href="/pubsub" class="group ui-meganav-media"><p class="ui-meganav-media-heading">Pub/Sub Channels</p><p class="ui-meganav-media-copy">Build infinitely scalable realtime applications.</p></a></li><li><a href="/spaces" class="group ui-meganav-media"><p class="ui-meganav-media-heading">Spaces (Beta)</p><p class="ui-meganav-media-copy">Create multi-user collaborative environments.</p></a></li><li><a href="/livesync" class="group ui-meganav-media"><p class="ui-meganav-media-heading">LiveSync (Alpha)</p><p class="ui-meganav-media-copy">Seamlessly sync database changes with frontend clients at scale.</p></a></li><li><a href="/chat" class="group ui-meganav-media"><p class="ui-meganav-media-heading">Chat (Beta)</p><p class="ui-meganav-media-copy">Deliver highly reliable chat experiences at scale.</p></a></li></ul></div><div class="col-span-full md:col-span-4 pt-8 pb-24 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0 bg-white"><h3 class="ui-meganav-overline" id="meganav-products-panel-list-our-technology">Technology</h3><ul class="mb-16" aria-labelledby="meganav-products-panel-list-our-technology"><li><a href="/four-pillars-of-dependability#performance" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Predictable performance</p><p class="ui-meganav-media-copy">A low-latency and high-throughput global network.</p></a></li><li><a href="/four-pillars-of-dependability#integrity" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Guaranteed ordering & delivery</p><p class="ui-meganav-media-copy">Data is delivered - in order - even after disconnections.</p></a></li><li><a href="/four-pillars-of-dependability#reliability" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Fault tolerant infrastructure</p><p class="ui-meganav-media-copy">Redundancy is built in at global and regional levels.</p></a></li><li><a href="/four-pillars-of-dependability#availability" class="ui-meganav-media group"><p class="ui-meganav-media-heading">High scalability & availability</p><p class="ui-meganav-media-copy">Built for scale with legitimate 99.999% uptime SLAs.</p></a></li><li><a href="/network" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Global edge network</p><p class="ui-meganav-media-copy">An edge network of 15 core routing datacenters and 205+ PoPs.</p></a></li></ul><a href="/four-pillars-of-dependability" class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group ui-text-p3 py-8 " style="--featured-link-icon-size:var(--fs-p3)">Explore Four Pillars of Dependability<svg class="text-cool-black align-middle ml-8 relative -top-1 -left-4 transition-all group-hover:left-0" style="width:calc(var(--featured-link-icon-size) * 1.25);height:calc(var(--featured-link-icon-size) * 1.25)"><use xlink:href="#sprite-icon-gui-link-arrow"/></svg></a></div></section><div class="ui-meganav-content-spacer"/></div></div></li><li class="ui-meganav-item"><button type="button" data-id="meganav-control" class="ui-meganav-link h-64 flex items-center group undefined text-cool-black" aria-expanded="false" aria-controls="use-cases-panel" aria-label="Show Solutions panel"><span class="hidden lg:inline">Solutions</span><span class="lg:hidden">Solutions</span><svg class="text-cool-black transform rotate-90 group-hover:text-gui-hover group-focus:text-gui-focus" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg></button><div class="ui-meganav-panel invisible ui-meganav-panel-split-bg" id="use-cases-panel" data-id="meganav-panel"><div class="flex max-w-screen-xl mx-auto"><div class="ui-meganav-content-spacer bg-extra-light-grey"/><section class="grid grid-cols-12 ui-grid-gap-x w-full"><div class="col-span-full md:col-span-4 py-24 lg:py-32 px-24 sm:px-32 md:pl-0 md:pr-24 bg-extra-light-grey"><h3 class="ui-meganav-overline" id="meganav-use-cases-panel-use-cases">Solutions</h3><ul aria-labelledby="meganav-use-cases-panel-industry-use-cases"><li><a href="/chat" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-chat-stack-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Live Chat</p><p class="ui-meganav-media-copy">Deliver highly reliable chat experiences at scale.</p></div></a></li><li><a href="/solutions/multiplayer-collaboration" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-multi-user-spaces-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Multiplayer Collaboration</p><p class="ui-meganav-media-copy">Bring collaborative multiplayer experiences to your users.</p></div></a></li><li><a href="/solutions/data-broadcast" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-data-broadcast-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Data Broadcast</p><p class="ui-meganav-media-copy">Broadcast realtime event data to millions of devices around the globe.</p></div></a></li><li><a href="/solutions/data-synchronization" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-data-synchronization-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Data Synchronization</p><p class="ui-meganav-media-copy">Keep your frontend and backend in realtime sync, at global scale.</p></div></a></li><li><a href="/push-notifications" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-push-notifications-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Notifications</p><p class="ui-meganav-media-copy">Deliver cross-platform push notifications with a simple unified API.</p></div></a></li><li><a href="/solutions/asset-tracking" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-asset-tracking-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Asset Tracking (Beta)</p><p class="ui-meganav-media-copy">Track assets in realtime with a solution optimised for last mile logistics.</p></div></a></li></ul></div><div class="col-span-full md:col-span-4 pt-24 pb-0 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0 bg-white"><h3 class="ui-meganav-overline" id="meganav-use-cases-panel-industry">Industry</h3><ul aria-labelledby="meganav-use-cases-panel-industry"><li><a href="/solutions/edtech" class="ui-meganav-media group"><p class="ui-meganav-media-heading">EdTech</p><p class="ui-meganav-media-copy">Deliver interactive learning experiences.</p></a></li><li><a href="/solutions/fintech" class="ui-meganav-media group"><p class="ui-meganav-media-heading">FinTech</p><p class="ui-meganav-media-copy">Deliver personalised financial data in realtime.</p></a></li><li><a href="/solutions/automotive-logistics-and-mobility" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Automotive, Logistics, & Mobility</p><p class="ui-meganav-media-copy">Power diagnostics, order tracking and more.</p></a></li><li><a href="/solutions/b2b-platforms" class="ui-meganav-media group"><p class="ui-meganav-media-heading">B2B Platforms</p><p class="ui-meganav-media-copy">Empower your customers with realtime solutions.</p></a></li><li><a href="/solutions/healthcare" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Healthcare (HIPAA)</p><p class="ui-meganav-media-copy">Provide trustworthy, HIPAA-compliant realtime apps.</p></a></li></ul></div><div class="col-span-full md:col-span-4 pt-0 pb-24 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0 bg-white"><ul aria-labelledby="meganav-use-cases-panel-solutions" class="mt-0 md:mt-40"><li><a href="/solutions/ecommerce-and-retail" class="ui-meganav-media group"><p class="ui-meganav-media-heading">eCommerce & Retail</p><p class="ui-meganav-media-copy">Enrich customer experiences with realtime updates.</p></a></li><li><a href="/solutions/sports-and-media" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Sports, Media & Fan Engagement</p><p class="ui-meganav-media-copy">Deliver engaging global realtime experiences.</p></a></li><li><a href="/solutions/gaming" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Gaming</p><p class="ui-meganav-media-copy">Power ultra fast and reliable gaming experiences.</p></a></li><li><a href="/solutions/iot-and-connected-devices" class="ui-meganav-media group"><p class="ui-meganav-media-heading">IoT & Connected Devices</p><p class="ui-meganav-media-copy">Monitor and control global IoT deployments in realtime.</p></a></li></ul></div></section><div class="ui-meganav-content-spacer"/></div></div></li><li class="ui-meganav-item"><button type="button" data-id="meganav-control" class="ui-meganav-link h-64 flex items-center group undefined text-cool-black" aria-expanded="false" aria-controls="company-panel" aria-label="Show Company panel"><span class="hidden lg:inline">Company</span><span class="lg:hidden">Company</span><svg class="text-cool-black transform rotate-90 group-hover:text-gui-hover group-focus:text-gui-focus" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg></button><div class="ui-meganav-panel invisible " id="company-panel" data-id="meganav-panel"><div class="flex max-w-screen-xl mx-auto"><div class="ui-meganav-content-spacer"/><section class="grid grid-cols-12 ui-grid-gap-x w-full"><div class="col-span-full md:col-span-4 pt-24 md:py-24 lg:py-32 px-24 sm:px-32 md:pl-0 md:pr-24"><h3 class="ui-meganav-overline" id="meganav-company-panel-list-why-companies">Why companies choose Ably</h3><ul aria-labelledby="meganav-company-panel-list-why-companies"><li><a href="/customers" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-customers-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Customers</p><p class="ui-meganav-media-copy">Ably supports customers across multiple industries.</p></div></a></li><li><a href="/case-studies" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-case-studies-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Case studies</p><p class="ui-meganav-media-copy">Discover how customers are benefiting from Ably.</p></div></a></li><li><a href="/compare" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-compare-tech-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Compare our tech</p><p class="ui-meganav-media-copy">Choose the right realtime service.</p></div></a></li><li><a href="/aws" class="ui-meganav-media-with-image group"><img src="https://voltaire.ably.com/static/icon-tech-aws-67903302dc52e1e54dbfad688aa57c2f.svg" alt="AWS logo"/><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Partners</p><p class="ui-meganav-media-copy">Ably collaborates and integrates with AWS.</p></div></a></li></ul></div><div class="col-span-full md:col-span-4 pb-8 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0"><ul class="md:mt-40" aria-labelledby="meganav-company-panel-list-why-companies"><li><a href="/resources" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-resources-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Resources</p><p class="ui-meganav-media-copy">Learn more about realtime with our handy resources.</p></div></a></li><li><a href="/about" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-about-ably-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">About Ably</p><p class="ui-meganav-media-copy">Find out more about Ably’s mission.</p></div></a></li><li><a href="/careers" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-careers-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Careers</p><p class="ui-meganav-media-copy">Discover our open roles and core Ably values.</p></div></a></li><li><a href="/events" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-events-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Events</p><p class="ui-meganav-media-copy">Join Ably at upcoming events.</p></div></a></li></ul></div></section><div class="ui-meganav-content-spacer"/></div></div></li><li class="ui-meganav-item"><button type="button" data-id="meganav-control" class="ui-meganav-link h-64 flex items-center group undefined text-cool-black" aria-expanded="false" aria-controls="developers-panel" aria-label="Show Developers panel"><span class="hidden lg:inline">Developers</span><span class="lg:hidden">Developers</span><svg class="text-cool-black transform rotate-90 group-hover:text-gui-hover group-focus:text-gui-focus" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg></button><div class="ui-meganav-panel invisible " id="developers-panel" data-id="meganav-panel"><div class="flex max-w-screen-xl mx-auto"><div class="ui-meganav-content-spacer"/><section class="grid grid-cols-12 ui-grid-gap-x w-full"><div class="col-span-full md:col-span-4 pt-24 md:py-24 lg:py-32 px-24 sm:px-32 md:pl-0 md:pr-24"><h3 class="ui-meganav-overline uppercase" id="meganav-developers-panel-explore">Explore</h3><ul aria-labelledby="meganav-developers-panel-explore"><li><a href="/docs" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-docs-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Documentation</p><p class="ui-meganav-media-copy">Technical guides to help you build with Ably.</p></div></a></li><li><a href="/docs/quick-start-guide" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-quickstart-guides-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Quickstart guides</p><p class="ui-meganav-media-copy">Documentation to help you get started quickly.</p></div></a></li><li><a href="/integrations" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-integrations-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Integrations</p><p class="ui-meganav-media-copy">Find out more about Ably integrations.<!-- --> </p></div></a></li><li><a href="/examples" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-examples-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Live examples</p><p class="ui-meganav-media-copy">Discover our features and their use cases.</p></div></a></li></ul></div><div class="col-span-full md:col-span-4 pb-8 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0"><ul class="md:mt-40" aria-labelledby="meganav-developers-panel-explore"><li><a href="/docs/sdks" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-sdks-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">SDKs</p><p class="ui-meganav-media-copy">Download an SDK to help you build realtime apps faster.</p></div></a></li><li><a href="/tutorials" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-tutorials-demos-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Tutorials & Demos</p><p class="ui-meganav-media-copy">Get stuck in with our hands-on resources.</p></div></a></li><li><a href="/reference-guide-chat" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-chat-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Chat apps reference guide</p><p class="ui-meganav-media-copy">Learn how to build chat apps with Ably.</p></div></a></li><li><a href="/reference-guide-multiplayer" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-multi-user-spaces-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Multiplayer reference guide</p><p class="ui-meganav-media-copy">Learn how to build collaborative features with Ably.</p></div></a></li></ul></div><div class="col-span-full md:col-span-4 pt-8 pb-24 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0"><h3 class="ui-meganav-overline uppercase" id="meganav-developers-panel-quick-links">Quick links</h3><ul aria-labelledby="meganav-developers-panel-quick-links"><li><a href="https://discord.gg/jwBPhEZ9g5" class="group ui-meganav-media py-12"><p class="ui-meganav-media-heading">Discord</p></a></li><li><a href="https://github.com/ably" class="group ui-meganav-media py-12"><p class="ui-meganav-media-heading">GitHub</p></a></li><li><a href="https://changelog.ably.com/" class="group ui-meganav-media py-12"><p class="ui-meganav-media-heading">Changelog</p></a></li><li><a href="https://status.ably.com/" class="group ui-meganav-media py-12"><p class="ui-meganav-media-heading">Status<a href="https://status.ably.com" class="inline-block ml-4 align-middle" target="_blank" rel="noreferrer"><span class="flex items-center h-[1.5rem] p-[0.25rem]"><span class="w-[1rem] h-[1rem] leading-[1rem] rounded-full animate-pulse bg-neutral-500"/></span></a></p></a></li><li><a href="/support" class="group ui-meganav-media py-12"><p class="ui-meganav-media-heading">Support & FAQs</p></a></li></ul></div></section><div class="ui-meganav-content-spacer"/></div></div></li><li class="ui-meganav-item"><a href="/pricing" data-id="meganav-link" class="ui-meganav-link h-64 items-center flex text-cool-black">Pricing</a></li></ul><div/><ul class="flex md:hidden items-center" data-id="meganav-items-mobile"><li><a href="/login" class="ui-meganav-link text-cool-black" data-id="meganav-link">Login</a></li><li class="ui-meganav-item"><button type="button" class="block ml-24 mr-0 px-0 py-16 hover:text-gui-hover focus:text-gui-focus focus:outline-none" data-id="meganav-control-mobile-dropdown" aria-expanded="false" aria-controls="meganav-mobile-dropdown"><svg class="text-cool-black transition-colors" style="width:1.5rem;height:1.5rem" data-id="meganav-control-mobile-dropdown-menu"><use xlink:href="#sprite-icon-gui-burger-menu"/></svg><svg class="text-cool-black transition-colors hidden" style="width:1.5rem;height:1.5rem" data-id="meganav-control-mobile-dropdown-close"><use xlink:href="#sprite-icon-gui-close"/></svg></button><div class="ui-meganav-mobile-dropdown invisible" id="meganav-mobile-dropdown" data-id="meganav-mobile-dropdown"><div class="pt-24 pb-16 ui-grid-px bg-white"><form class="mb-16" action="/search" method="get"><div class="relative w-full"><svg class="text-cool-black absolute top-12 left-16 hover:text-gui-hover" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-search"/></svg><button type="button" class="absolute top-12 right-16 p-0 focus:outline-gui-focus m-0 md:hidden invisible" data-id="meganav-search-input-clear"><svg class="text-dark-grey " style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-cross-circled-fill"/></svg></button><input type="search" name="q" class="ui-input px-48 h-48" style="max-width:none" placeholder="Search" autocomplete="off" data-id="meganav-mobile-search-input"/><div class="absolute w-full mt-8 z-10 hidden shadow-container rounded-lg bg-white border border-mid-grey" data-id="meganav-search-autocomplete-container"><ol class="m-16" data-id="meganav-search-autocomplete-list"/></div></div></form><div class="max-h-0 overflow-hidden transition-all" data-id="meganav-mobile-search-suggestions"><p class="ui-text-overline2 text-cool-black py-12">Popular pages</p><div class="flex justify-between items-center overflow-hidden"><ul class="flex transition-transform"><li class="py-12 pr-8 flex-shrink-0"><a href="/docs/how-ably-works" class="ui-text-p2 hover:text-gui-hover active:text-gui-active focus:text-gui-focus">How does Ably work?</a></li><li class="py-12 px-8 flex-shrink-0"><a href="/docs/quick-start-guide" class="ui-text-p2 hover:text-gui-hover active:text-gui-active focus:text-gui-focus">Quickstart guide</a></li><li class="py-12 px-8 flex-shrink-0"><a href="/docs/core-features/pubsub" class="ui-text-p2 hover:text-gui-hover active:text-gui-active focus:text-gui-focus">Publish/Subscribe Messaging</a></li><li class="py-12 pl-8 flex-shrink-0"><a href="/platform" class="ui-text-p2 hover:text-gui-hover active:text-gui-active focus:text-gui-focus">Platform</a></li></ul></div></div><ul class="mb-16" data-id="meganav-mobile-panel-controls"><li class="ui-meganav-mobile-item"><button type="button" class="ui-meganav-mobile-link" data-id="meganav-control-mobile-panel-open" aria-expanded="false" aria-controls="products-panel-mobile" aria-label="Show Products">Products<svg class="text-cool-black relative -top-1 ml-auto float-right" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg></button><div class="ui-meganav-panel-mobile hidden" id="products-panel-mobile" data-scroll-lock-scrollable="true"><div class="mx-24 md:mx-32"><button type="button" class="ui-meganav-mobile-link text-gui-default mb-16" data-id="meganav-control-mobile-panel-close" aria-expanded="false" aria-controls="products-panel-mobile" aria-label="Hide panel"><svg class="text-cool-black relative -top-1 transform rotate-180" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg>Back</button></div><div class="flex max-w-screen-xl mx-auto"><div class="ui-meganav-content-spacer bg-extra-light-grey"/><section class="grid grid-cols-12 ui-grid-gap-x w-full"><div class="col-span-full md:col-span-4 py-24 lg:py-32 px-24 sm:px-32 md:pl-0 md:pr-24 bg-extra-light-grey"><div class="flex mb-20"><img src="https://voltaire.ably.com/static/ably-stack-05764a90f33eddbf5e18138b6574f282.svg" alt="Ably homepage"/><h3 class="ui-meganav-overline ml-24">The Ably Platform</h3></div><p class="ui-text-p2 font-bold mb-24" style="max-width:330px">Easily power any realtime experience in your application. No complex infrastructure to manage or provision. Just a simple API that handles everything realtime, and lets you focus on your code.</p><a href="/platform" class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group ui-text-p2 py-8 " style="--featured-link-icon-size:var(--fs-p2)">Explore how it works<svg class="text-cool-black align-middle ml-8 relative -top-1 -left-4 transition-all group-hover:left-0" style="width:calc(var(--featured-link-icon-size) * 1.25);height:calc(var(--featured-link-icon-size) * 1.25)"><use xlink:href="#sprite-icon-gui-link-arrow"/></svg></a></div><div class="col-span-full md:col-span-4 pt-24 pb-8 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0 bg-white"><h3 class="ui-meganav-overline" id="meganav-products-panel-list-examples">Products</h3><ul class="mb-16" aria-labelledby="meganav-products-panel-list-examples"><li><a href="/pubsub" class="group ui-meganav-media"><p class="ui-meganav-media-heading">Pub/Sub Channels</p><p class="ui-meganav-media-copy">Build infinitely scalable realtime applications.</p></a></li><li><a href="/spaces" class="group ui-meganav-media"><p class="ui-meganav-media-heading">Spaces (Beta)</p><p class="ui-meganav-media-copy">Create multi-user collaborative environments.</p></a></li><li><a href="/livesync" class="group ui-meganav-media"><p class="ui-meganav-media-heading">LiveSync (Alpha)</p><p class="ui-meganav-media-copy">Seamlessly sync database changes with frontend clients at scale.</p></a></li><li><a href="/chat" class="group ui-meganav-media"><p class="ui-meganav-media-heading">Chat (Beta)</p><p class="ui-meganav-media-copy">Deliver highly reliable chat experiences at scale.</p></a></li></ul></div><div class="col-span-full md:col-span-4 pt-8 pb-24 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0 bg-white"><h3 class="ui-meganav-overline" id="meganav-products-panel-list-our-technology">Technology</h3><ul class="mb-16" aria-labelledby="meganav-products-panel-list-our-technology"><li><a href="/four-pillars-of-dependability#performance" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Predictable performance</p><p class="ui-meganav-media-copy">A low-latency and high-throughput global network.</p></a></li><li><a href="/four-pillars-of-dependability#integrity" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Guaranteed ordering & delivery</p><p class="ui-meganav-media-copy">Data is delivered - in order - even after disconnections.</p></a></li><li><a href="/four-pillars-of-dependability#reliability" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Fault tolerant infrastructure</p><p class="ui-meganav-media-copy">Redundancy is built in at global and regional levels.</p></a></li><li><a href="/four-pillars-of-dependability#availability" class="ui-meganav-media group"><p class="ui-meganav-media-heading">High scalability & availability</p><p class="ui-meganav-media-copy">Built for scale with legitimate 99.999% uptime SLAs.</p></a></li><li><a href="/network" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Global edge network</p><p class="ui-meganav-media-copy">An edge network of 15 core routing datacenters and 205+ PoPs.</p></a></li></ul><a href="/four-pillars-of-dependability" class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group ui-text-p3 py-8 " style="--featured-link-icon-size:var(--fs-p3)">Explore Four Pillars of Dependability<svg class="text-cool-black align-middle ml-8 relative -top-1 -left-4 transition-all group-hover:left-0" style="width:calc(var(--featured-link-icon-size) * 1.25);height:calc(var(--featured-link-icon-size) * 1.25)"><use xlink:href="#sprite-icon-gui-link-arrow"/></svg></a></div></section><div class="ui-meganav-content-spacer"/></div></div></li><li class="ui-meganav-mobile-item"><button type="button" class="ui-meganav-mobile-link" data-id="meganav-control-mobile-panel-open" aria-expanded="false" aria-controls="use-cases-panel-mobile" aria-label="Show Solutions">Solutions<svg class="text-cool-black relative -top-1 ml-auto float-right" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg></button><div class="ui-meganav-panel-mobile hidden" id="use-cases-panel-mobile" data-scroll-lock-scrollable="true"><div class="mx-24 md:mx-32"><button type="button" class="ui-meganav-mobile-link text-gui-default mb-16" data-id="meganav-control-mobile-panel-close" aria-expanded="false" aria-controls="use-cases-panel-mobile" aria-label="Hide panel"><svg class="text-cool-black relative -top-1 transform rotate-180" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg>Back</button></div><div class="flex max-w-screen-xl mx-auto"><div class="ui-meganav-content-spacer bg-extra-light-grey"/><section class="grid grid-cols-12 ui-grid-gap-x w-full"><div class="col-span-full md:col-span-4 py-24 lg:py-32 px-24 sm:px-32 md:pl-0 md:pr-24 bg-extra-light-grey"><h3 class="ui-meganav-overline" id="meganav-use-cases-panel-use-cases">Solutions</h3><ul aria-labelledby="meganav-use-cases-panel-industry-use-cases"><li><a href="/chat" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-chat-stack-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Live Chat</p><p class="ui-meganav-media-copy">Deliver highly reliable chat experiences at scale.</p></div></a></li><li><a href="/solutions/multiplayer-collaboration" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-multi-user-spaces-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Multiplayer Collaboration</p><p class="ui-meganav-media-copy">Bring collaborative multiplayer experiences to your users.</p></div></a></li><li><a href="/solutions/data-broadcast" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-data-broadcast-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Data Broadcast</p><p class="ui-meganav-media-copy">Broadcast realtime event data to millions of devices around the globe.</p></div></a></li><li><a href="/solutions/data-synchronization" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-data-synchronization-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Data Synchronization</p><p class="ui-meganav-media-copy">Keep your frontend and backend in realtime sync, at global scale.</p></div></a></li><li><a href="/push-notifications" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-push-notifications-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Notifications</p><p class="ui-meganav-media-copy">Deliver cross-platform push notifications with a simple unified API.</p></div></a></li><li><a href="/solutions/asset-tracking" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-asset-tracking-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Asset Tracking (Beta)</p><p class="ui-meganav-media-copy">Track assets in realtime with a solution optimised for last mile logistics.</p></div></a></li></ul></div><div class="col-span-full md:col-span-4 pt-24 pb-0 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0 bg-white"><h3 class="ui-meganav-overline" id="meganav-use-cases-panel-industry">Industry</h3><ul aria-labelledby="meganav-use-cases-panel-industry"><li><a href="/solutions/edtech" class="ui-meganav-media group"><p class="ui-meganav-media-heading">EdTech</p><p class="ui-meganav-media-copy">Deliver interactive learning experiences.</p></a></li><li><a href="/solutions/fintech" class="ui-meganav-media group"><p class="ui-meganav-media-heading">FinTech</p><p class="ui-meganav-media-copy">Deliver personalised financial data in realtime.</p></a></li><li><a href="/solutions/automotive-logistics-and-mobility" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Automotive, Logistics, & Mobility</p><p class="ui-meganav-media-copy">Power diagnostics, order tracking and more.</p></a></li><li><a href="/solutions/b2b-platforms" class="ui-meganav-media group"><p class="ui-meganav-media-heading">B2B Platforms</p><p class="ui-meganav-media-copy">Empower your customers with realtime solutions.</p></a></li><li><a href="/solutions/healthcare" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Healthcare (HIPAA)</p><p class="ui-meganav-media-copy">Provide trustworthy, HIPAA-compliant realtime apps.</p></a></li></ul></div><div class="col-span-full md:col-span-4 pt-0 pb-24 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0 bg-white"><ul aria-labelledby="meganav-use-cases-panel-solutions" class="mt-0 md:mt-40"><li><a href="/solutions/ecommerce-and-retail" class="ui-meganav-media group"><p class="ui-meganav-media-heading">eCommerce & Retail</p><p class="ui-meganav-media-copy">Enrich customer experiences with realtime updates.</p></a></li><li><a href="/solutions/sports-and-media" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Sports, Media & Fan Engagement</p><p class="ui-meganav-media-copy">Deliver engaging global realtime experiences.</p></a></li><li><a href="/solutions/gaming" class="ui-meganav-media group"><p class="ui-meganav-media-heading">Gaming</p><p class="ui-meganav-media-copy">Power ultra fast and reliable gaming experiences.</p></a></li><li><a href="/solutions/iot-and-connected-devices" class="ui-meganav-media group"><p class="ui-meganav-media-heading">IoT & Connected Devices</p><p class="ui-meganav-media-copy">Monitor and control global IoT deployments in realtime.</p></a></li></ul></div></section><div class="ui-meganav-content-spacer"/></div></div></li><li class="ui-meganav-mobile-item"><button type="button" class="ui-meganav-mobile-link" data-id="meganav-control-mobile-panel-open" aria-expanded="false" aria-controls="company-panel-mobile" aria-label="Show Company">Company<svg class="text-cool-black relative -top-1 ml-auto float-right" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg></button><div class="ui-meganav-panel-mobile hidden" id="company-panel-mobile" data-scroll-lock-scrollable="true"><div class="mx-24 md:mx-32"><button type="button" class="ui-meganav-mobile-link text-gui-default mb-16" data-id="meganav-control-mobile-panel-close" aria-expanded="false" aria-controls="company-panel-mobile" aria-label="Hide panel"><svg class="text-cool-black relative -top-1 transform rotate-180" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg>Back</button><hr class="ui-meganav-hr"/></div><div class="flex max-w-screen-xl mx-auto"><div class="ui-meganav-content-spacer"/><section class="grid grid-cols-12 ui-grid-gap-x w-full"><div class="col-span-full md:col-span-4 pt-24 md:py-24 lg:py-32 px-24 sm:px-32 md:pl-0 md:pr-24"><h3 class="ui-meganav-overline" id="meganav-company-panel-list-why-companies">Why companies choose Ably</h3><ul aria-labelledby="meganav-company-panel-list-why-companies"><li><a href="/customers" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-customers-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Customers</p><p class="ui-meganav-media-copy">Ably supports customers across multiple industries.</p></div></a></li><li><a href="/case-studies" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-case-studies-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Case studies</p><p class="ui-meganav-media-copy">Discover how customers are benefiting from Ably.</p></div></a></li><li><a href="/compare" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-compare-tech-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Compare our tech</p><p class="ui-meganav-media-copy">Choose the right realtime service.</p></div></a></li><li><a href="/aws" class="ui-meganav-media-with-image group"><img src="https://voltaire.ably.com/static/icon-tech-aws-67903302dc52e1e54dbfad688aa57c2f.svg" alt="AWS logo"/><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Partners</p><p class="ui-meganav-media-copy">Ably collaborates and integrates with AWS.</p></div></a></li></ul></div><div class="col-span-full md:col-span-4 pb-8 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0"><ul class="md:mt-40" aria-labelledby="meganav-company-panel-list-why-companies"><li><a href="/resources" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-resources-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Resources</p><p class="ui-meganav-media-copy">Learn more about realtime with our handy resources.</p></div></a></li><li><a href="/about" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-about-ably-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">About Ably</p><p class="ui-meganav-media-copy">Find out more about Ably’s mission.</p></div></a></li><li><a href="/careers" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-careers-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Careers</p><p class="ui-meganav-media-copy">Discover our open roles and core Ably values.</p></div></a></li><li><a href="/events" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-events-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Events</p><p class="ui-meganav-media-copy">Join Ably at upcoming events.</p></div></a></li></ul></div></section><div class="ui-meganav-content-spacer"/></div></div></li><li class="ui-meganav-mobile-item"><button type="button" class="ui-meganav-mobile-link" data-id="meganav-control-mobile-panel-open" aria-expanded="false" aria-controls="developers-panel-mobile" aria-label="Show Developers">Developers<svg class="text-cool-black relative -top-1 ml-auto float-right" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg></button><div class="ui-meganav-panel-mobile hidden" id="developers-panel-mobile" data-scroll-lock-scrollable="true"><div class="mx-24 md:mx-32"><button type="button" class="ui-meganav-mobile-link text-gui-default mb-16" data-id="meganav-control-mobile-panel-close" aria-expanded="false" aria-controls="developers-panel-mobile" aria-label="Hide panel"><svg class="text-cool-black relative -top-1 transform rotate-180" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg>Back</button><hr class="ui-meganav-hr"/></div><div class="flex max-w-screen-xl mx-auto"><div class="ui-meganav-content-spacer"/><section class="grid grid-cols-12 ui-grid-gap-x w-full"><div class="col-span-full md:col-span-4 pt-24 md:py-24 lg:py-32 px-24 sm:px-32 md:pl-0 md:pr-24"><h3 class="ui-meganav-overline uppercase" id="meganav-developers-panel-explore">Explore</h3><ul aria-labelledby="meganav-developers-panel-explore"><li><a href="/docs" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-docs-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Documentation</p><p class="ui-meganav-media-copy">Technical guides to help you build with Ably.</p></div></a></li><li><a href="/docs/quick-start-guide" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-quickstart-guides-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Quickstart guides</p><p class="ui-meganav-media-copy">Documentation to help you get started quickly.</p></div></a></li><li><a href="/integrations" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-integrations-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Integrations</p><p class="ui-meganav-media-copy">Find out more about Ably integrations.<!-- --> </p></div></a></li><li><a href="/examples" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-examples-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Live examples</p><p class="ui-meganav-media-copy">Discover our features and their use cases.</p></div></a></li></ul></div><div class="col-span-full md:col-span-4 pb-8 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0"><ul class="md:mt-40" aria-labelledby="meganav-developers-panel-explore"><li><a href="/docs/sdks" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-sdks-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">SDKs</p><p class="ui-meganav-media-copy">Download an SDK to help you build realtime apps faster.</p></div></a></li><li><a href="/tutorials" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-tutorials-demos-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Tutorials & Demos</p><p class="ui-meganav-media-copy">Get stuck in with our hands-on resources.</p></div></a></li><li><a href="/reference-guide-chat" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-display-chat-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Chat apps reference guide</p><p class="ui-meganav-media-copy">Learn how to build chat apps with Ably.</p></div></a></li><li><a href="/reference-guide-multiplayer" class="ui-meganav-media-with-image group"><svg class=" " style="width:2.5rem;height:2.5rem"><use xlink:href="#sprite-icon-multi-user-spaces-col"/></svg><div class="flex flex-col justify-center"><p class="ui-meganav-media-heading">Multiplayer reference guide</p><p class="ui-meganav-media-copy">Learn how to build collaborative features with Ably.</p></div></a></li></ul></div><div class="col-span-full md:col-span-4 pt-8 pb-24 md:py-24 lg:py-32 px-24 sm:px-32 md:px-0"><h3 class="ui-meganav-overline uppercase" id="meganav-developers-panel-quick-links">Quick links</h3><ul aria-labelledby="meganav-developers-panel-quick-links"><li><a href="https://discord.gg/jwBPhEZ9g5" class="group ui-meganav-media py-12"><p class="ui-meganav-media-heading">Discord</p></a></li><li><a href="https://github.com/ably" class="group ui-meganav-media py-12"><p class="ui-meganav-media-heading">GitHub</p></a></li><li><a href="https://changelog.ably.com/" class="group ui-meganav-media py-12"><p class="ui-meganav-media-heading">Changelog</p></a></li><li><a href="https://status.ably.com/" class="group ui-meganav-media py-12"><p class="ui-meganav-media-heading">Status<a href="https://status.ably.com" class="inline-block ml-4 align-middle" target="_blank" rel="noreferrer"><span class="flex items-center h-[1.5rem] p-[0.25rem]"><span class="w-[1rem] h-[1rem] leading-[1rem] rounded-full animate-pulse bg-neutral-500"/></span></a></p></a></li><li><a href="/support" class="group ui-meganav-media py-12"><p class="ui-meganav-media-heading">Support & FAQs</p></a></li></ul></div></section><div class="ui-meganav-content-spacer"/></div></div></li><li><a href="/pricing" class="ui-meganav-mobile-link">Pricing</a></li></ul><hr class="ui-meganav-hr mb-20"/><div class="flex justify-between items-center mb-16"><a href="/contact" class="text-menu2 font-medium block ml-0 mr-8 lg:mx-12 p-0 hover:text-gui-hover focus:text-gui-focus focus:outline-none">Contact us</a><a href="/sign-up" class="ui-btn">Sign up free</a></div></div></div></li></ul></div></nav><div class="ui-flash" data-id="ui-flashes"/><main class="layout__Main-sc-17rhhsn-0 hrjGga"><aside data-sidebar-sticking="false" class="sticky-sidebar-mobile__Sidebar-sc-gqtcvm-0 kBIIRq md:hidden w-full z-20"><div class="relative"><div class="font-sans ui-grid-px bg-white border-mid-grey border-b flex items-center py-16 relative z-10"><div class="ui-text-overline2 text-dark-grey font-medium">On this page</div><svg class=" ml-auto transform absolute right-0 mr-24 sm:mr-32 rotate-90" style="width:1.5rem;height:1.5rem"><use xlink:href="#sprite-icon-gui-disclosure-arrow"/></svg></div><div class="table-of-contents-mobile__Container-sc-1g3ebrb-0 cxCPgY border-b border-color-mid-grey absolute bg-white overflow-y-auto w-full"/><div class="overlay__Overlay-sc-j0b6or-0 GWjZX"/></div></aside><section class="bg-cool-black relative z-10 pt-96 pb-128 hero-motif-section relative overflow-hidden"><div class="z-10 relative"><div class="ui-standard-container ui-grid-gap grid grid-cols-12"><div class="col-span-full mb-16 md:mb-32"><ol class="ui-text-p3 subpixel-antialiased"><li class="inline-block mb-8"><a href="https://ably.com/topics" class="vt-breadcrumb-link text-light-grey">Topics</a></li><li class="text-dark-grey mx-8 inline-block mb-8">/</li><li class="inline-block mb-8"><a href="https://ably.com/topics/protocols" class="vt-breadcrumb-link text-light-grey">Protocols</a></li><li class="text-dark-grey mx-8 inline-block mb-8">/</li><li class="text-dark-grey inline-block mb-8">Server-Sent Events: A WebSockets alternative ready for another look</li></ol></div><div class="col-span-full md:col-span-8 md:col-start-2 flex flex-col sm:flex-row items-start lg:items-center"><div class="flex h-full items-center mb-24 md:mb-0"><svg class="text-white " style="width:1rem;height:1rem"><use xlink:href="#sprite-icon-gui-clock"/></svg><span class="ml-8 font-sans font-light text-p3 text-white">13 min read</span><span class="mx-8 sm:mx-16 ui-text-p3 text-light-grey">•</span><span class="font-sans font-light text-p3 text-white"><span class="hidden md:inline-block">Last updated</span><span class="inline-block md:hidden">Updated</span> <!-- -->Jun 28, 2023</span></div></div><h1 class="col-span-full md:col-span-8 md:col-start-2 ui-text-title mb-24 sm:mb-40 !text-white">Server-Sent Events: A WebSockets alternative ready for another look</h1><div class="col-span-full md:col-span-8 md:col-start-2 flex flex-col sm:flex-row"/></div></div><div class="hidden z-0 absolute vt-xxl-motif"><div class="motif-shared__MotifHolder-sc-zktbfb-0 kVPVZC vt-motif-container vt-xxl-motif "><svg class="vt-motif-part vt-motif-part-main vt-circle-layer-0 vt-xxl-motif" width="1176" height="1176" viewbox="0 0 1176 1176" fill-opacity="0" xmlns="http://www.w3.org/2000/svg"><path d="M588 711C655.931 711 711 655.931 711 588C711 520.069 655.931 465 588 465C520.069 465 465 520.069 465 588C465 655.931 520.069 711 588 711Z" stroke="url(#paint0_linear_155:451)" stroke-width="8" stroke-miterlimit="10"/><defs><lineargradient id="paint0_linear_155:451" x1="457.503" y1="588.064" x2="718.624" y2="588.064" gradientunits="userSpaceOnUse"><stop stop-color="#FF5416"/><stop offset="0.1871" stop-color="#FF4C14"/><stop offset="0.4706" stop-color="#FF380F"/><stop offset="0.8136" stop-color="#FF1606"/><stop offset="1" stop-color="#FF0000"/></lineargradient></defs></svg><svg class="vt-motif-part vt-motif-part-main vt-circle-layer-1 vt-xxl-motif" width="1176" height="1176" viewbox="0 0 1176 1176" fill-opacity="0" xmlns="http://www.w3.org/2000/svg"><path d="M588 803C706.741 803 803 706.741 803 588C803 469.259 706.741 373 588 373C469.259 373 373 469.259 373 588C373 706.741 469.259 803 588 803Z" stroke="url(#paint1_linear_155:451)" stroke-width="8" stroke-miterlimit="10"/><defs><lineargradient id="paint1_linear_155:451" x1="364.998" y1="588.067" x2="811.136" y2="588.067" gradientunits="userSpaceOnUse"><stop stop-color="#FF5416"/><stop offset="0.1871" stop-color="#FF4C14"/><stop offset="0.4706" stop-color="#FF380F"/><stop offset="0.8136" stop-color="#FF1606"/><stop offset="1" stop-color="#FF0000"/></lineargradient></defs></svg><svg class="vt-motif-part vt-motif-part-main vt-circle-layer-2 vt-xxl-motif" width="1176" height="1176" viewbox="0 0 1176 1176" fill-opacity="0" xmlns="http://www.w3.org/2000/svg"><path d="M588 895C757.551 895 895 757.551 895 588C895 418.449 757.551 281 588 281C418.449 281 281 418.449 281 588C281 757.551 418.449 895 588 895Z" stroke="url(#paint2_linear_155:451)" stroke-width="8" stroke-miterlimit="10"/><defs><lineargradient id="paint2_linear_155:451" x1="272.978" y1="588.069" x2="903.158" y2="588.069" gradientunits="userSpaceOnUse"><stop stop-color="#FF5416"/><stop offset="0.1871" stop-color="#FF4C14"/><stop offset="0.4706" stop-color="#FF380F"/><stop offset="0.8136" stop-color="#FF1606"/><stop offset="1" stop-color="#FF0000"/></lineargradient></defs></svg><svg class="vt-motif-part vt-motif-part-main vt-circle-layer-3 vt-xxl-motif" width="1176" height="1176" viewbox="0 0 1176 1176" fill-opacity="0" xmlns="http://www.w3.org/2000/svg"><path d="M588 988C808.914 988 988 808.914 988 588C988 367.086 808.914 188 588 188C367.086 188 188 367.086 188 588C188 808.914 367.086 988 588 988Z" stroke="url(#paint3_linear_155:451)" stroke-width="8" stroke-miterlimit="10"/><defs><lineargradient id="paint3_linear_155:451" x1="179.73" y1="588.069" x2="996.409" y2="588.069" gradientunits="userSpaceOnUse"><stop stop-color="#FF5416"/><stop offset="0.1871" stop-color="#FF4C14"/><stop offset="0.4706" stop-color="#FF380F"/><stop offset="0.8136" stop-color="#FF1606"/><stop offset="1" stop-color="#FF0000"/></lineargradient></defs></svg></div></div></section><section class="ui-standard-container grid grid-cols-12 ui-grid-gap relative mt-40 md:mt-80 mb-96"><div class="col-span-full md:col-span-8"><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Instead of the browser continuously <a class="ui-link [&>u]:no-underline" href="https://ably.com/topic/long-polling"><u>polling</u></a> the server on the off chance there’s new information, Server-Sent Events (SSEs) enable the server to push data to the browser as soon as there’s new information available. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">For example, breaking news updates, the latest Bitcoin price, or your food delivery driver’s location on the map.</p><div class="my-40 sm:my-48 md:my-64 flex flex-col items-center"><div data-gatsby-image-wrapper="" class="gatsby-image-wrapper gatsby-image-wrapper-constrained max-w-full rounded"><div style="max-width:1840px;display:block"><img alt="" role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg%20height='800.0000000000001'%20width='1840'%20xmlns='http://www.w3.org/2000/svg'%20version='1.1'%3E%3C/svg%3E" style="max-width:100%;display:block;position:static"/></div><div aria-hidden="true" data-placeholder-image="" style="opacity:1;transition:opacity 500ms linear;background-color:#f8f8f8;top:0;left:0;bottom:0;right:0"/><picture><source type="image/webp" data-srcset="https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=460&h=200&q=80&fm=webp 460w,https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=920&h=400&q=80&fm=webp 920w,https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=1840&h=800&q=80&fm=webp 1840w" sizes="(min-width: 1840px) 1840px, 100vw"/><img data-gatsby-image-ssr="" data-main-image="" style="opacity:0" sizes="(min-width: 1840px) 1840px, 100vw" decoding="async" loading="lazy" data-src="https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=1840&h=800&q=80&fm=png" data-srcset="https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=460&h=200&q=80&fm=png 460w,https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=920&h=400&q=80&fm=png 920w,https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=1840&h=800&q=80&fm=png 1840w" alt=""/></picture><noscript><picture><source type="image/webp" srcset="https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=460&h=200&q=80&fm=webp 460w,https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=920&h=400&q=80&fm=webp 920w,https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=1840&h=800&q=80&fm=webp 1840w" sizes="(min-width: 1840px) 1840px, 100vw"/><img data-gatsby-image-ssr="" data-main-image="" style="opacity:0" sizes="(min-width: 1840px) 1840px, 100vw" decoding="async" loading="lazy" src="https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=1840&h=800&q=80&fm=png" srcset="https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=460&h=200&q=80&fm=png 460w,https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=920&h=400&q=80&fm=png 920w,https://images.ctfassets.net/ee3ypdtck0rk/282EqFKxI3bukpIF8mU8Db/0343c6984cf58e9f1f9bc6fa5de75cee/data-push-use-cases__2_.png?w=1840&h=800&q=80&fm=png 1840w" alt=""/></picture></noscript></div><p class="mt-8 ui-text-p2 text-dark-grey text-center">Breaking news, tickers, and location tracking - Sever-Sent Events are ideal for these types of use-cases </p></div><section class="scroll-mt-16" id="why-not-use-web-sockets"><div class="vt-section-wrapper"><span class="vt-link-copy mb-32 mt-40 md:mt-64"><a href="#why-not-use-web-sockets" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h2 class="ui-text-h2 mb-32 mt-40 md:mt-64"> <!-- -->Why not use WebSockets? <!-- --> </h2></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Another way you might have achieved realtime updates like this in the past is with <a class="ui-link [&>u]:no-underline" href="https://ably.com/topic/websockets"><u>WebSockets</u></a>. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">WebSockets are great because they enable full-duplex bidirectional communication with low latency.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">This makes them ideal for scenarios where information needs to flow simultaneously in both directions like a multiplayer game, <a class="ui-link [&>u]:no-underline" href="https://ably.com/solutions/multiplayer-collaboration"><u>multiplayer collaboration</u></a>, or <a class="ui-link [&>u]:no-underline" href="https://ably.com/blog/live-chat-features"><u>rich chat experience</u></a>.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">However, the work required to implement, manage, and <a class="ui-link [&>u]:no-underline" href="https://ably.com/topic/the-challenge-of-scaling-websockets"><u>scale</u></a> the custom WebSocket protocol is non-trivial.<b class="font-bold"> </b></p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">It’s helpful to remember that while some apps need bidirectional, many do not - most apps out there are mainly read apps. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Said another way, the server sends the majority of messages while the client listens and once in a while sends updates.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">For situations like the ones above where you mostly need to send updates <b class="font-bold">one-way</b> from the server to the client only, SSEs provide a much more convenient (equally efficient) way to push updates based on HTTP.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">For those times when the client needs to send data to the server, you can use a separate HTTP channel to POST data from the client (maybe using the <a class="ui-link [&>u]:no-underline" href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API" rel="noopener noreferrer" target="_blank"><u>fetch</u></a> API):</p><div class="my-40 sm:my-48 md:my-64 flex flex-col items-center"><div data-gatsby-image-wrapper="" class="gatsby-image-wrapper gatsby-image-wrapper-constrained max-w-full rounded"><div style="max-width:2000px;display:block"><img alt="" role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg%20height='945'%20width='2000'%20xmlns='http://www.w3.org/2000/svg'%20version='1.1'%3E%3C/svg%3E" style="max-width:100%;display:block;position:static"/></div><div aria-hidden="true" data-placeholder-image="" style="opacity:1;transition:opacity 500ms linear;background-color:#f8f8f8;top:0;left:0;bottom:0;right:0"/><picture><source type="image/webp" data-srcset="https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=500&h=236&q=80&fm=webp 500w,https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=1000&h=473&q=80&fm=webp 1000w,https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=2000&h=945&q=80&fm=webp 2000w"/><source type="image/gif" data-srcset="https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=500&h=236&q=80&fm=gif 500w,https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=1000&h=473&q=80&fm=gif 1000w,https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=2000&h=945&q=80&fm=gif 2000w"/><img data-gatsby-image-ssr="" data-main-image="" style="opacity:0" decoding="async" loading="lazy" alt=""/></picture><noscript><picture><source type="image/webp" srcset="https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=500&h=236&q=80&fm=webp 500w,https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=1000&h=473&q=80&fm=webp 1000w,https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=2000&h=945&q=80&fm=webp 2000w"/><source type="image/gif" srcset="https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=500&h=236&q=80&fm=gif 500w,https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=1000&h=473&q=80&fm=gif 1000w,https://images.ctfassets.net/ee3ypdtck0rk/1rHxI8RvYNW8t1dH4ZIsU7/58b6b4889d0c2889643e4a32aab1591c/bidirectional-with-data-push-animated__1_.gif?w=2000&h=945&q=80&fm=gif 2000w"/><img data-gatsby-image-ssr="" data-main-image="" style="opacity:0" decoding="async" loading="lazy" alt=""/></picture></noscript></div><p class="mt-8 ui-text-p2 text-dark-grey text-center">While SSE opens a continuous connection so the server can send new data without the client needing to request it, a separate short-lived HTTP connection can be opened to occasionally POST data to the server without the need for WebSockets </p></div></section><section class="scroll-mt-16" id="server-sent-events-why-they-re-ready-for-prime-time"><div class="vt-section-wrapper"><span class="vt-link-copy mb-32 mt-40 md:mt-64"><a href="#server-sent-events-why-they-re-ready-for-prime-time" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h2 class="ui-text-h2 mb-32 mt-40 md:mt-64"> <!-- -->Server-Sent events: Why they’re ready for prime time<!-- --> </h2></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Introduced in 2011, SSEs never really made it out from under WebSocket’s shadow and into the mainstream.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Why?</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Historically, SSEs had some limitations holding them back. However, recent advancements to the web platform means it’s time to take another look:</p><ul class="contentful__UL-sc-t8qyu2-1 jqcoAv ui-unordered-list mt-24 first:mt-0"><li><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1"><b class="font-bold">Browser support:</b> Microsoft Edge lacked SSE support until January 2020. A few years later, SSEs are now available in <a class="ui-link [&>u]:no-underline" href="https://caniuse.com/?search=eventsource" rel="noopener noreferrer" target="_blank">ninety-eight percent</a> of browsers. </p></li><li><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1"><b class="font-bold">Connection limit:</b> HTTP/1 limited the number of concurrent HTTP connections per domain to six. HTTP/2 eliminates this connection limit and is available in more than <a class="ui-link [&>u]:no-underline" href="https://caniuse.com/?search=http2" rel="noopener noreferrer" target="_blank">ninety-six percent</a> of browsers and all modern HTTP servers.</p></li></ul><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">SSEs always had potential, but these limitations nudged developers to alternatives like WebSockets, even though they’re more work to implement when you only need one-way updates. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">In light of the advancements above, enthusiasm for the technology is at an all-time high.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Companies like <a class="ui-link [&>u]:no-underline" href="https://shopify.engineering/server-sent-events-data-streaming" rel="noopener noreferrer" target="_blank"><u>Shopify</u></a> and <a class="ui-link [&>u]:no-underline" href="https://help.split.io/hc/en-us/articles/360025335031-Step-3-Send-event-data" rel="noopener noreferrer" target="_blank"><u>Split</u></a> use them in production to send millions of events.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">And every time we see someone write about SSE, developers race to the comments to sing their praises, often elaborate to explain they wish they knew about it sooner.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Maybe this is the first time you’re hearing about SSE and want to learn more, or perhaps you’ve encountered it before and are ready to give it another look. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">No matter where you’re starting from, this page will teach you all about SSEs - what they are, where they excel, and the practical considerations you should be aware of around security, performance, and how smoothly they scale. </p></section><section class="scroll-mt-16" id="what-are-server-sent-events-exactly"><div class="vt-section-wrapper"><span class="vt-link-copy mb-32 mt-40 md:mt-64"><a href="#what-are-server-sent-events-exactly" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h2 class="ui-text-h2 mb-32 mt-40 md:mt-64"> <!-- -->What are Server-Sent Events, exactly?<!-- --> </h2></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Server-Sent Events is a standard composed of two components: </p><ol class="contentful__OL-sc-t8qyu2-2 dIfrnE ui-ordered-list mt-24 first:mt-0"><li><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">An EventSource interface in the browser, which allows the client to subscribe to events; and, </p></li><li><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">the “event stream” data format, which is used to deliver the individual updates. </p></li></ol><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">In the upcoming sections, let’s take a closer look at each. </p></section><section class="scroll-mt-16" id="event-source-interface"><div class="vt-section-wrapper"><span class="vt-link-copy mb-24 mt-24 md:mt-32"><a href="#event-source-interface" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h3 class="ui-text-h3 mb-24 mt-24 md:mt-32"> <!-- -->EventSource interface<!-- --> </h3></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">The EventSource interface is described by the <a class="ui-link [&>u]:no-underline" href="https://html.spec.whatwg.org/multipage/server-sent-events.html" rel="noopener noreferrer" target="_blank"><u>WHATWG specification</u></a> and implemented by all modern browsers. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">It provides a convenient way to subscribe to a stream of events by abstracting the lower-level connection and message handling.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Here’s a Server-Sent events example:</p><div class="w-full bg-cool-black relative rounded my-32"><div class="hljs overflow-auto p-16 rounded" data-id="code"><pre lang="Javascript"><code class="language-Javascript ui-text-code"><span class="hljs-keyword">const</span> eventSource = <span class="hljs-keyword">new</span> <span class="hljs-title class_">EventSource</span>(<span class="hljs-string">"/event-stream"</span>) eventSource.<span class="hljs-property">onmessage</span> = <span class="hljs-function"><span class="hljs-params">event</span> =></span> { <span class="hljs-keyword">const</span> li = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">createElement</span>(<span class="hljs-string">"li"</span>) <span class="hljs-keyword">const</span> ul = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">"list"</span>) li.<span class="hljs-property">textContent</span> = <span class="hljs-string">`message: <span class="hljs-subst">${event.data}</span>`</span> ul.<span class="hljs-title function_">appendChild</span>(li) };</code></pre></div></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Above, we call the EventSource constructor with a URL to the SSE endpoint before wiring up the event handlers. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">There’s no need to worry about negotiating the connection, parsing the event stream, or deciding how to propagate the events. All the implementation logic is handled for us.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Apart from tucking away the underlying logic, EventSouce has a couple other handy features:</p><ul class="contentful__UL-sc-t8qyu2-1 jqcoAv ui-unordered-list mt-24 first:mt-0"><li><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1"><b class="font-bold">Automatic reconnection: </b>Should the client disconnect unexpectedly (maybe the user went through a tunnel), EventSource will periodically try to reconnect.</p></li><li><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1"><b class="font-bold">Automatic stream resume:</b> EventSouce automatically remembers the last received message ID and will automatically send a Last-Event-ID header when trying to reconnect.</p></li></ul></section><section class="scroll-mt-16" id="event-stream-protocol"><div class="vt-section-wrapper"><span class="vt-link-copy mb-24 mt-24 md:mt-32"><a href="#event-stream-protocol" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h3 class="ui-text-h3 mb-24 mt-24 md:mt-32"> <!-- -->Event stream protocol <!-- --> </h3></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">The event stream protocol describes the standard plain-text format that events sent by the server must follow in order for the EventSource client to understand and propagate them.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">According to the specification, events can carry arbitrary text data, an optional ID, and are delimited by newlines. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Here’s an example event that contains information about Bitcoin’s price:<br/></p><div class="w-full bg-cool-black relative rounded my-32"><div class="hljs overflow-auto p-16 rounded" data-id="code"><pre lang="Javascript"><code class="language-Javascript ui-text-code"><span class="hljs-attr">id</span>: <span class="hljs-number">42</span> <span class="hljs-attr">event</span>: btcTicker <span class="hljs-attr">data</span>: btc <span class="hljs-number">2002867</span></code></pre></div></div></section><section class="scroll-mt-16" id="how-do-they-work"><div class="vt-section-wrapper"><span class="vt-link-copy mb-32 mt-40 md:mt-64"><a href="#how-do-they-work" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h2 class="ui-text-h2 mb-32 mt-40 md:mt-64"> <!-- -->How do they work?<!-- --> </h2></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Every SSE connection begins by initiating the EventSource instance with a URL to the SSE stream.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Under the hood, EventSource initiates a regular HTTP request, to which the server responds with the official SSE "text/event-stream" Content Type and a stream of event data.</p><div class="my-40 sm:my-48 md:my-64 flex flex-col items-center"><div data-gatsby-image-wrapper="" class="gatsby-image-wrapper gatsby-image-wrapper-constrained max-w-full rounded"><div style="max-width:1840px;display:block"><img alt="" role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg%20height='872.0000000000001'%20width='1840'%20xmlns='http://www.w3.org/2000/svg'%20version='1.1'%3E%3C/svg%3E" style="max-width:100%;display:block;position:static"/></div><div aria-hidden="true" data-placeholder-image="" style="opacity:1;transition:opacity 500ms linear;background-color:#080808;top:0;left:0;bottom:0;right:0"/><picture><source type="image/webp" data-srcset="https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=460&h=218&q=80&fm=webp 460w,https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=920&h=436&q=80&fm=webp 920w,https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=1840&h=872&q=80&fm=webp 1840w" sizes="(min-width: 1840px) 1840px, 100vw"/><img data-gatsby-image-ssr="" data-main-image="" style="opacity:0" sizes="(min-width: 1840px) 1840px, 100vw" decoding="async" loading="lazy" data-src="https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=1840&h=872&q=80&fm=png" data-srcset="https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=460&h=218&q=80&fm=png 460w,https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=920&h=436&q=80&fm=png 920w,https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=1840&h=872&q=80&fm=png 1840w" alt=""/></picture><noscript><picture><source type="image/webp" srcset="https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=460&h=218&q=80&fm=webp 460w,https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=920&h=436&q=80&fm=webp 920w,https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=1840&h=872&q=80&fm=webp 1840w" sizes="(min-width: 1840px) 1840px, 100vw"/><img data-gatsby-image-ssr="" data-main-image="" style="opacity:0" sizes="(min-width: 1840px) 1840px, 100vw" decoding="async" loading="lazy" src="https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=1840&h=872&q=80&fm=png" srcset="https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=460&h=218&q=80&fm=png 460w,https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=920&h=436&q=80&fm=png 920w,https://images.ctfassets.net/ee3ypdtck0rk/5EGr0dYKI0QvIrKJT5yurZ/69d73a97e3eaf967a4021f5b32c04dc8/server_sent_events_how_it_works.png?w=1840&h=872&q=80&fm=png 1840w" alt=""/></picture></noscript></div></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">This connection remains open until the server decides it has no more data to send, the client explicitly closes the connection by calling the <code class="ui-text-code-inline">EventSource.close</code> method, or the connection becomes idle. To circumvent a timeout, you can send a keep-alive message every minute or so.</p></section><section class="scroll-mt-16" id="server-sent-events-use-cases"><div class="vt-section-wrapper"><span class="vt-link-copy mb-32 mt-40 md:mt-64"><a href="#server-sent-events-use-cases" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h2 class="ui-text-h2 mb-32 mt-40 md:mt-64"> <!-- -->Server-Sent Events use cases<!-- --> </h2></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">SSE are particularly useful when you need to subscribe to (often frequent) updates generated by the server. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Here are some scenarios where you might use SSE:</p><ul class="contentful__UL-sc-t8qyu2-1 jqcoAv ui-unordered-list mt-24 first:mt-0"><li><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1"><b class="font-bold">Realtime notifications:</b> SSE allows the server to broadcast notifications as soon as they occur. This is handy for news and social feeds, live event broadcasting, or any app where users need to receive immediate notifications. </p></li><li><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1"><b class="font-bold">Live data updates:</b> Whether we’re talking about stock and crypto tickers, sports scoreboards, realtime analytics, or your Instacart driver’s location on the map, SSE is well-suited for scenarios where users need to see the latest data as it becomes available.</p></li><li><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1"><b class="font-bold">Progress updates:</b> SSE can be used to send periodic updates to the client about the status of a long-running process, allowing the user to monitor the state of the operation.</p></li><li><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1"><b class="font-bold">IoT:</b> SSE can be used in IoT scenarios where devices need to receive realtime updates from the server. For example, in a home automation system, SSE can be employed to push updates about the status of sensors, alarms, or other IoT devices.</p></li></ul></section><section class="scroll-mt-16" id="browser-and-mobile-compatibility"><div class="vt-section-wrapper"><span class="vt-link-copy mb-32 mt-40 md:mt-64"><a href="#browser-and-mobile-compatibility" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h2 class="ui-text-h2 mb-32 mt-40 md:mt-64"> <!-- -->Browser and mobile compatibility<!-- --> </h2></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">EventSource is available in more than <a class="ui-link [&>u]:no-underline" href="https://caniuse.com/?search=server%20sent%20events" rel="noopener noreferrer" target="_blank"><u>ninety-six percent</u></a> of web browsers. Chrome, FireFox, and Safari have had support since 2012, while Edge only caught up in January 2020. Internet Explorer never supported SSE so a polyfill must be used.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Although EventSource is a browser API, because SSE is based on HTTP, it’s possible to consume a SSE stream on any device that can make a HTTP request - that includes Android and iOS, for which there are even open source libraries available that make consuming an event stream just as easy as EventSource.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">For the icing on the cake, SSE supports a technology called connectionless push which allows clients connected on a mobile network to offload the management of the connection to the network carrier to conserve battery life. This makes SSE an all-around attractive option for mobile devices where battery life is a key concern. We wrote a bit more about this in <a class="ui-link [&>u]:no-underline" href="https://ably.com/blog/websockets-vs-http-streaming-vs-sse"><u>our post comparing SSE, WebSockets, and HTTP streaming</u></a> if you’d like to learn more.</p></section><section class="scroll-mt-16" id="authentication-and-security"><div class="vt-section-wrapper"><span class="vt-link-copy mb-32 mt-40 md:mt-64"><a href="#authentication-and-security" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h2 class="ui-text-h2 mb-32 mt-40 md:mt-64"> <!-- -->Authentication and security<!-- --> </h2></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Like any web resource, an event stream might be private or tailored for a specific user. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Since EventSource initiates the connection with a HTTP request, the browser automatically sends the session cookies along with the request, making it possible for the server to authenticate and authorise the user.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">A common problem developers run into with EventSource is that their apps use tokens instead of cookies and there isn’t an obvious way to pass this token along with the initial request.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">One option would be to pass the token in the query string but sending sensitive data in a query string is not generally recommended due to security concerns. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">The only accepted practices are to use a third-party library like <a class="ui-link [&>u]:no-underline" href="https://github.com/Yaffle/EventSource" rel="noopener noreferrer" target="_blank"><u>EventSource by Yaffle</u></a> or implement your own EventSource client. According to a developer from the Chrome team, unfortunately, EventSource is <a class="ui-link [&>u]:no-underline" href="https://github.com/whatwg/html/issues/2177#issuecomment-332071504" rel="noopener noreferrer" target="_blank"><u>unlikely</u></a> to ever support tokens natively.</p></section><section class="scroll-mt-16" id="server-sent-events-performance"><div class="vt-section-wrapper"><span class="vt-link-copy mb-32 mt-40 md:mt-64"><a href="#server-sent-events-performance" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h2 class="ui-text-h2 mb-32 mt-40 md:mt-64"> <!-- -->Server-Sent Events performance <!-- --> </h2></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">If high throughput and low latency are your primary performance considerations, SSE holds their own against any option out there.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">To give you some idea, Shopify uses SSE to power their realtime data visualisation product. While they don’t reveal the specific throughput, they <a class="ui-link [&>u]:no-underline" href="https://shopify.engineering/server-sent-events-data-streaming" rel="noopener noreferrer" target="_blank"><u>explain</u></a> they ingested 323 billion rows of data in a four day window.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Our customer <a class="ui-link [&>u]:no-underline" href="https://ably.com/case-studies/split"><u>Split</u></a> use SSEs with our realtime platform to send more than one trillion events per month with an average global latency of less than 300 milliseconds.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">We mention this only to give you an idea of what’s possible with the right platform.</p></section><section class="scroll-mt-16" id="scaling-server-sent-events"><div class="vt-section-wrapper"><span class="vt-link-copy mb-32 mt-40 md:mt-64"><a href="#scaling-server-sent-events" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h2 class="ui-text-h2 mb-32 mt-40 md:mt-64"> <!-- -->Scaling Server-Sent Events<!-- --> </h2></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">SSE can <i class="font-italic">theoretically</i> scale to an infinite number of connections. However, the scalability of SSE in practice depends on several factors including the hardware resources available, efficiency of your server implementation, and the wider system design and architecture.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">A Principal Staff Software Engineer at LinkedIn <a class="ui-link [&>u]:no-underline" href="https://engineering.linkedin.com/blog/2016/10/instant-messaging-at-linkedin--scaling-to-hundreds-of-thousands-#:~:text=Server%2Dsent%20events%20(SSE),client%20to%20make%20subsequent%20requests." rel="noopener noreferrer" target="_blank"><u>wrote about their team’s experience scaling SSE</u></a>. After seriously beefing up their server hardware and tinkering with kernel parameters, they managed to support hundreds of thousands of persistent connections on one machine. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Regardless of the extent to which you optimise your code, eventually you ’ll reach the limit of any one server and arrive at the need to scale out horizontally.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Using load balancing techniques with a proxy like Nginx, you can add more servers and distribute the load across them to ensure new connections are handled efficiently.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Scaling SSEs through load balancing is a more manageable option compared to <a class="ui-link [&>u]:no-underline" href="https://ably.com/topic/the-challenge-of-scaling-websockets#:~:text=Are%20WebSockets%20scalable%3F,instant%20messaging%20between%20chat%20users."><u>scaling WebSockets</u></a>, however, it’s important to note that this still requires careful planning.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">In particular, maintaining data consistency will always become more complex when multiple server instances are involved. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1"><a class="ui-link [&>u]:no-underline" href="https://www.tpeczek.com/2017/09/server-sent-events-or-websockets.html" rel="noopener noreferrer" target="_blank"><u>Tomasz Pęczek</u></a> gives a good example.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Imagine, for instance, an event resulting from an operation on instance 1 needs to be broadcasted to all clients (so also client B):</p><div class="my-40 sm:my-48 md:my-64 flex flex-col items-center"><div data-gatsby-image-wrapper="" class="gatsby-image-wrapper gatsby-image-wrapper-constrained max-w-full rounded"><div style="max-width:521px;display:block"><img alt="" role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg%20height='334'%20width='521'%20xmlns='http://www.w3.org/2000/svg'%20version='1.1'%3E%3C/svg%3E" style="max-width:100%;display:block;position:static"/></div><div aria-hidden="true" data-placeholder-image="" style="opacity:1;transition:opacity 500ms linear;background-color:#f8f8f8;top:0;left:0;bottom:0;right:0"/><picture><source type="image/webp" data-srcset="https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=130&h=83&q=80&fm=webp 130w,https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=261&h=167&q=80&fm=webp 261w,https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=521&h=334&q=80&fm=webp 521w" sizes="(min-width: 521px) 521px, 100vw"/><img data-gatsby-image-ssr="" data-main-image="" style="opacity:0" sizes="(min-width: 521px) 521px, 100vw" decoding="async" loading="lazy" data-src="https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=521&h=334&q=80&fm=png" data-srcset="https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=130&h=83&q=80&fm=png 130w,https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=261&h=167&q=80&fm=png 261w,https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=521&h=334&q=80&fm=png 521w" alt=""/></picture><noscript><picture><source type="image/webp" srcset="https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=130&h=83&q=80&fm=webp 130w,https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=261&h=167&q=80&fm=webp 261w,https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=521&h=334&q=80&fm=webp 521w" sizes="(min-width: 521px) 521px, 100vw"/><img data-gatsby-image-ssr="" data-main-image="" style="opacity:0" sizes="(min-width: 521px) 521px, 100vw" decoding="async" loading="lazy" src="https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=521&h=334&q=80&fm=png" srcset="https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=130&h=83&q=80&fm=png 130w,https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=261&h=167&q=80&fm=png 261w,https://images.ctfassets.net/ee3ypdtck0rk/6DNkLYv84Xary6GHRK61QF/30691a3df1be79b2691325e9ff0df413/1.png?w=521&h=334&q=80&fm=png 521w" alt=""/></picture></noscript></div><p class="mt-8 ui-text-p2 text-dark-grey text-center">Illustration by Tomasz Pęczek</p></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">To solve this problem, you need to introduce an additional component: A shared resource like a message broker to send the message to all subscribers. <br/></p><div class="my-40 sm:my-48 md:my-64 flex flex-col items-center"><div data-gatsby-image-wrapper="" class="gatsby-image-wrapper gatsby-image-wrapper-constrained max-w-full rounded"><div style="max-width:757px;display:block"><img alt="" role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg%20height='334'%20width='757'%20xmlns='http://www.w3.org/2000/svg'%20version='1.1'%3E%3C/svg%3E" style="max-width:100%;display:block;position:static"/></div><div aria-hidden="true" data-placeholder-image="" style="opacity:1;transition:opacity 500ms linear;background-color:#f8f8f8;top:0;left:0;bottom:0;right:0"/><picture><source type="image/webp" data-srcset="https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=189&h=83&q=80&fm=webp 189w,https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=379&h=167&q=80&fm=webp 379w,https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=757&h=334&q=80&fm=webp 757w" sizes="(min-width: 757px) 757px, 100vw"/><img data-gatsby-image-ssr="" data-main-image="" style="opacity:0" sizes="(min-width: 757px) 757px, 100vw" decoding="async" loading="lazy" data-src="https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=757&h=334&q=80&fm=png" data-srcset="https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=189&h=83&q=80&fm=png 189w,https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=379&h=167&q=80&fm=png 379w,https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=757&h=334&q=80&fm=png 757w" alt=""/></picture><noscript><picture><source type="image/webp" srcset="https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=189&h=83&q=80&fm=webp 189w,https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=379&h=167&q=80&fm=webp 379w,https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=757&h=334&q=80&fm=webp 757w" sizes="(min-width: 757px) 757px, 100vw"/><img data-gatsby-image-ssr="" data-main-image="" style="opacity:0" sizes="(min-width: 757px) 757px, 100vw" decoding="async" loading="lazy" src="https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=757&h=334&q=80&fm=png" srcset="https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=189&h=83&q=80&fm=png 189w,https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=379&h=167&q=80&fm=png 379w,https://images.ctfassets.net/ee3ypdtck0rk/4M3PCpQ5BdrK5mf5VCgFv9/bc9c76675a262f9523ec1fde7b8ff4c3/3.png?w=757&h=334&q=80&fm=png 757w" alt=""/></picture></noscript></div><p class="mt-8 ui-text-p2 text-dark-grey text-center">Illustration by Tomasz Pęczek</p></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Using a broker like Redis, each instance can subscribe to the broker. The broker sends the message to all subscribers and they send it to one, some, or all clients. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">What started as a simple one-way stream has now evolved into a more complicated overall system architecture that requires careful design and documentation to ensure scalability without compromising on availability, latency, or maintainability. And that is yet to speak of the challenges achieving message durability while scaling out. </p></section><section class="scroll-mt-16" id="server-sent-events-and-ably"><div class="vt-section-wrapper"><span class="vt-link-copy mb-32 mt-40 md:mt-64"><a href="#server-sent-events-and-ably" class="link-copy__IconLink-sc-18nnrum-2 fqthmq"><svg aria-hidden="true" focusable="false" class="icon__IconWrapper-sc-1heqhn4-0 blsGgY"><use xlink:href="#ai-link"/></svg><span class="link-copy__Label-sc-18nnrum-0 fiHeTn">Copy link to clipboard<span class="link-copy__LabelTriangle-sc-18nnrum-1 jyEenk"/></span></a></span><h2 class="ui-text-h2 mb-32 mt-40 md:mt-64"> <!-- -->Server-Sent Events and Ably<!-- --> </h2></div><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1"><a class="ui-link [&>u]:no-underline" href="https://ably.com/"><u>Ably</u></a> (hello!) is a platform used by companies like HubSpot and Split to reliably deliver realtime updates with the minimum possible latency.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">While many of our customers use the official Ably SDK based on WebSockets, we built an <a class="ui-link [&>u]:no-underline" href="https://ably.com/protocols/server-sent-events"><u>SSE adapter</u></a> for anyone seeking a lightweight method of streaming events using the open SSE standard.</p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">Our experience building the adapter inspired this post, and since you’re interested in efficient realtime updates as well, we thought you might like to know a bit more about it in just a few lines. </p><p class="contentful__P-sc-t8qyu2-0 lbdBQg ui-text-p1">All you need to do is plug the Ably adapter into the EventSource client like so:</p><div class="w-full bg-cool-black relative rounded my-32"><div class="hljs overflow-auto p-16 rounded" data-id="code"><pre lang="Javascript"><code class="language-Javascript ui-text-code"><span class="hljs-keyword">const</span> apiKey =<span class="hljs-string">'xVLyHw.U_-pxQ:iPETgh3Vm16oUms5JgYXCYgPV8naidwIWwdhwBfI3zM'</span> <span class="hljs-keyword">const</span> url =<span class="hljs-string">'https://realtime.ably.io/event-stream?channels=myChannel&v=1.2&key='</span> + apiKey <span class="hljs-keyword">const</span> eventSource = <span class="hljs-keyword">new</span> <span class="hljs-title class_">EventSource</span>(url)
推荐文章
独立的树叶
·
2023年河南省南阳市教育局所属学校教师招聘公告(49名)-南阳教师招聘网.
2 周前
痴情的机器猫
·
一对多关联 · ThinkPHP5.0完全开发手册 · 看云
2 月前
爽快的盒饭
·
四川省人民检察院发布2019年公益诉讼典型案例
2 月前
深情的伤疤
·
教育部办公厅关于进一步做好普通高校毕业生就业统计与核查工作的通知 - 湖南省教育厅
3 月前
帅气的夕阳
·
Ajax Payment and redirect for 3D Secure · craftcms/commerce-stripe · Discussion #175 · GitHub
4 月前