home-assistant.github.io/blog/2015/02/24/streaming-updates/index.html
2016-12-06 08:23:42 +00:00

271 lines
No EOL
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Streaming updates - Home Assistant</title>
<meta name="author" content="Paulus Schoutsen">
<meta name="description" content="The frontend will now get the latest changes pushed while open.">
<meta name="viewport" content="width=device-width">
<link rel="canonical" href="https://home-assistant.io/blog/2015/02/24/streaming-updates/">
<meta property="fb:app_id" content="338291289691179">
<meta property="og:title" content="Streaming updates">
<meta property="og:site_name" content="Home Assistant">
<meta property="og:url" content="https://home-assistant.io/blog/2015/02/24/streaming-updates/">
<meta property="og:type" content="article">
<meta property="og:description" content="The frontend will now get the latest changes pushed while open.">
<meta property="og:image" content="https://home-assistant.io/images/default-social.png">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@home_assistant">
<meta name="twitter:creator" content="@balloob">
<meta name="twitter:title" content="Streaming updates">
<meta name="twitter:description" content="The frontend will now get the latest changes pushed while open.">
<meta name="twitter:image" content="https://home-assistant.io/images/default-social.png">
<link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet">
<link href="/atom.xml" rel="alternate" title="Home Assistant" type="application/atom+xml">
<link rel='shortcut icon' href='/images/favicon.ico' />
<link rel='icon' type='image/png' href='/images/favicon-192x192.png' sizes='192x192' />
</head>
<body >
<header>
<div class="grid-wrapper">
<div class="grid">
<div class="grid__item three-tenths lap-two-sixths palm-one-whole ha-title">
<a href="/" class="site-title">
<img width='40' src='/demo/favicon-192x192.png'>
<span>Home Assistant</span>
</a>
</div>
<div class="grid__item seven-tenths lap-four-sixths palm-one-whole">
<nav>
<input type="checkbox" id="toggle">
<label for="toggle" class="toggle" data-open="Main Menu" data-close="Close Menu"></label>
<ul class="menu pull-right">
<li><a href="/getting-started/">Getting started</a></li>
<li><a href="/components/">Components</a></li>
<li><a href="/ecosystem/">Ecosystem</a></li>
<li><a href="/cookbook/">Examples</a></li>
<li><a href="/developers/">Developers</a></li>
<li><a href="/blog/">Blog</a></li>
<li><a href="/help/">Need help?</a></li>
</ul>
</nav>
</div>
</div>
</div>
</header>
<div class="grid-wrapper">
<div class="grid grid-center">
<div class="grid__item two-thirds lap-one-whole palm-one-whole">
<article class="post">
<header>
<h1 class="title indent">Streaming updates</h1>
<div class="meta clearfix">
<time datetime="2015-02-24T22:41:27+00:00" pubdate data-updated="true"><i class="icon-calendar"></i> February 24, 2015</time>
<span class="byline author vcard"><i class='icon-user'></i> Paulus Schoutsen</span>
<span><i class='icon-time'></i> 1 minute reading time</span>
<span>
<i class="icon-tags"></i>
<ul class="tags unstyled">
<li>Release-Notes</li>
</ul>
</span>
<a class='comments'
href="#disqus_thread"
>Comments</a>
</div>
</header>
<p>Home Assistant has learned a new trick to get the latest information from the server: streaming updates. No longer will the frontend poll every 30 seconds for updates but instead it will keep a connection open and get the latest changes pushed as soon as they happen.</p>
<p>A new toggle has been added ot the sidebar to turn streaming updates on and off. This preference will be saved on a per-browser basis using local storage. The toggle will also indicate when there is an error setting up a stream after which it will fall back to use polling.</p>
<p class="img"><img src="/images/screenshots/streaming-updates.png" /></p>
<a name="read-more"></a>
<p>Streaming updates has been implemented using the HTML5 <code class="highlighter-rouge">EventSource</code> tag. Implementation is pretty straight forward as all the reconnection logic will be handled by the event source tag. The <a href="https://github.com/home-assistant/home-assistant/blob/master/homeassistant/components/api.py#L90">server-side code</a> is 50 lines and the <a href="https://github.com/home-assistant/home-assistant-js/blob/master/src/actions/stream.js">client-side code</a> is 80 lines of code.</p>
<p>All events that happen on the server will now also be sent to the browser. This turns any browser running the UI into a fully functioning <a href="https://home-assistant.io/developers/architecture/#multiple-connected-instances">slave instance</a> of Home Assistant. This opens up new possibilities for Home Assistant components that live completely client-side.</p>
<p>Implementing EventSource was not without challenges. Here are some of the issues that had to be solved:</p>
<p>A connection can go stale in Chrome without any event handler being called. This happens when a device goes into standby. For computers this is rare but for phones this occurs quite often. This has been solved by sending a regular ping from the server. The frontend will assume the connection has gone stale when it hasnt heard any communication for a while. Sending a ping will also help the server detect broken connections and clean them up.</p>
<p>Another issue that I encountered is that Safari and Firefox would not fire the <code class="highlighter-rouge">open</code> event when the connection has been opened but when the first message has been received. To work around this the server will now fire a ping when the connection gets opened.</p>
</article>
<section id="disqus">
<h3 class="indent title">Comments</h3>
<div id="disqus_thread" aria-live="polite"><noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript></div>
</section>
</div>
<aside id="sidebar" class="grid__item one-third lap-one-whole palm-one-whole">
<div class="grid">
<section class="aside-module grid__item one-whole lap-one-half">
<h1 class="title delta">About Home Assistant</h1>
<ul class="divided">
<li>
Home Assistant is an open-source home automation platform running on Python 3. Track and control all devices at home and automate control.
</li>
<li><a href='/getting-started/'>Get started with Home Assistant</a></li>
<li><a href='/demo/'>Try the online demo</a></li>
<li><a class="twitter-follow-button" href="https://twitter.com/Home_Assistant">Follow Home Assistant on Twitter</a></li>
<li><div class="fb-like" data-href="https://www.facebook.com/homeassistantio/" data-layout="standard" data-action="like" data-size="small" data-show-faces="true" data-share="false"></div></li>
</ul>
</section>
<div id="fb-root"></div>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.async=true;js.src='//platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<script>(function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(d.getElementById(id)){return;}js=d.createElement(s);js.id=id;js.async=true;js.src="//connect.facebook.net/en_US/all.js#appId=338291289691179&xfbml=1";fjs.parentNode.insertBefore(js,fjs);}(document,'script','facebook-jssdk'));</script>
<section class="sharing aside-module grid__item one-whole lap-one-half">
<h1 class="title delta">Share this post</h1>
<a href="//twitter.com/share"
class="twitter-share-button"
data-via="home_assistant"
data-related="home_assistant"
data-url="https://home-assistant.io/blog/2015/02/24/streaming-updates/"
data-counturl="https://home-assistant.io/blog/2015/02/24/streaming-updates/" >Tweet</a>
<div class="fb-share-button" style='top: -6px;'
data-href="https://home-assistant.io/blog/2015/02/24/streaming-updates/"
data-layout="button_count">
</div>
<div class="g-plusone" data-size="standard"></div>
</section>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<section id="recent-posts" class="aside-module grid__item one-whole lap-one-half">
<h1 class="title delta">Recent Posts</h1>
<ul class="divided">
<li class="post">
<a href="/blog/2016/12/03/remote-websockets-sonarr/">0.34: New Remote component, Websockets, Sonarr, GPSLogger</a>
</li>
<li class="post">
<a href="/blog/2016/11/20/calendar-wink-thermostats-cisco-ios/">0.33: New Calendar component, Wink thermostats and Cisco IOS</a>
</li>
<li class="post">
<a href="/blog/2016/11/05/hacktoberfest-influxdb-weather/">0.32: Hacktoberfest, InfluxDB sensor, Error reporting, and Weather</a>
</li>
<li class="post">
<a href="/blog/2016/10/25/explaining-the-updater/">Explaining the Updater</a>
</li>
<li class="post">
<a href="/blog/2016/10/22/flash-briefing-updater-hacktoberfest/">0.31: Reading you the news, some serious business, spooky hackery and a breaking Z-Wave change</a>
</li>
</ul>
</section>
</div>
</aside>
</div>
</div>
<footer>
<div class="grid-wrapper">
<div class="grid">
<div class="grid__item">
<div class="copyright">
<a rel="me" href='https://twitter.com/home_assistant'><i class="icon-twitter"></i></a>
<a rel="me" href='https://facebook.com/homeassistantio'><i class="icon-facebook"></i></a>
<a rel="me" href='https://plus.google.com/110560654828510104551'><i class="icon-google-plus"></i></a>
<a rel="me" href='https://github.com/home-assistant/home-assistant'><i class="icon-github"></i></a>
<div class="credit">
Contact us at <a href='mailto:hello@home-assistant.io'>hello@home-assistant.io</a>.<br>
Website powered by <a href='http://jekyllrb.com/'>Jekyll</a> and the <a href='https://github.com/coogie/oscailte'>Oscalite theme</a>.<br />
Hosted by <a href='https://pages.github.com/'>GitHub</a> and served by <a href='https://cloudflare.com'>CloudFlare</a>.
</div>
</div>
</div>
</div>
</div>
</footer>
<script>
var _gaq=[['_setAccount','UA-57927901-1'],['_trackPageview']];
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
s.parentNode.insertBefore(g,s)}(document,'script'));
</script>
<script>
var disqus_shortname = 'home-assistant';
// var disqus_developer = 1;
var disqus_identifier = 'https://home-assistant.io/blog/2015/02/24/streaming-updates/';
var disqus_url = 'https://home-assistant.io/blog/2015/02/24/streaming-updates/';
var disqus_script = 'embed.js';
(function () {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/' + disqus_script;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
}());
</script>
</body>
</html>