{"id":3626,"date":"2017-10-27T21:48:57","date_gmt":"2017-10-27T21:48:57","guid":{"rendered":"http:\/\/disenoweb.mx\/?p=3626"},"modified":"2017-10-27T21:48:57","modified_gmt":"2017-10-27T21:48:57","slug":"eventsource","status":"publish","type":"post","link":"https:\/\/disenoweb.mx\/blog\/eventsource\/","title":{"rendered":"Eventsource"},"content":{"rendered":"\n<h1>Eventsource<\/h1>\n<p><img data-opt-id=1986949973  fetchpriority=\"high\" decoding=\"async\" class=\"alignnone size-medium wp-image-4040\" src=\"https:\/\/mlniuewdmffl.i.optimole.com\/w:300\/h:287\/q:mauto\/f:best\/http:\/\/disenoweb.mx\/diseno\/wp-content\/uploads\/web_design-300x287.jpg\" alt=\"dise\u00f1o web tlaquepaque Eventsource Eventsource web design 300x287\" width=\"300\" height=\"287\" title=\"web_design-300x287 web_design-300x287\"><\/p>\n<p>\u00a0<\/p>\n<p>Los\u00a0<em><strong>EventSource<\/strong><\/em>\u00a0(<a href=\"http:\/\/disenoweb.mx\">tambi\u00e9n conocidos como Server-Sent Events<\/a>), son eventos en tiempo real transmitidos por el servidor y recibidos en el navegador. Son similares a los WebSockets en que suceden el tiempo real, pero son principalmente un m\u00e9todo de comunicaci\u00f3n unidireccional desde el servidor. Al igual que en los WebSocket, creamos una nueva conexi\u00f3n indicando la URL, y el navegador intentar\u00e1 conectarse inmediatamente. El objeto\u00a0<em><strong>EventSource<\/strong><\/em>\u00a0dispone de los siguientes eventos: open: se dispara cuando la conexi\u00f3n se ha establecido. message: evento que indica la llegada de un mensaje nuevo. error: se dispara cuando algo ha ido mal. Lo que hace a\u00a0<em><strong>EventSource<\/strong><\/em>e diferente es la manera en que controla las p\u00e9rdidas de conexi\u00f3n y la gesti\u00f3n de los mensajes.<br>\nSi la conexi\u00f3n se pierde por alguna raz\u00f3n, el API autom\u00e1ticamente trata de volver a conectarse. Adem\u00e1s, al restablecer la conexi\u00f3n, el cliente env\u00eda al servidor la ID del \u00faltimo mensaje que recibi\u00f3. Esto permite al servidor, enviar al cliente todos los mensajes que no ha podido recibir. No es necesario realizar ninguna configuraci\u00f3n especial en nuestro c\u00f3digo, simplemente el servidor nos enviar\u00e1 los mensajes que no hemos recibido.<br>\nUn sencillo ejemplo:<br>\nvar es = new EventSource(\u2018\/bidding\u2019);<\/p>\n<p>es.onopen = function () { initialiseData(); };<\/p>\n<p>es.onmessage = function (event) { var data = JSON.parse(event.data); updateData(data.time, data.bid); };<br>\nEVENTSOURCE EN EL SERVIDOR<\/p>\n<p>En el lado del servidor podemos seguir utilizando una soluci\u00f3n basada en PHP y la pila completa LAMP, pero como Apache no se comporta de manera estable con conexiones<\/p>\n<p>persistentes, constantemente trata de cerrar las conexiones y EventSource trata de volver a conectarse autom\u00e1ticamente. Esto da como resultado un comportamiento m\u00e1s parecido a Ajax que a una comunicaci\u00f3n unidireccional y en tiempo real desde el servidor.<br>\nRealmente, esta no es la mejor manera de aprovechar las ventajas de\u00a0<em><strong>EventSource<\/strong><\/em>. Para ello, necesitamos una conexi\u00f3n persistente con el servidor, y LAMP no nos lo puede proporcionar. Actualmente existen soluciones de servidor basadas en eventos, como pueden ser Node.js (un servidor basado en JavaScript) o Twisted para Python.<\/p>\n<p>UN SIMPLE SERVIDOR PARA EVENTSOURCE El siguiente c\u00f3digo muestra como crear un servidor muy simple con Node.js, el cual acepta conexiones y env\u00eda mensajes a los clientes conectados. En este caso, \u00fanicamente se notifica al resto de usuarios conectados al servicio, que un nuevo usuario se ha conectado.<br>\nvar http = require(\u2018http\u2019); http.createServer(function (req, res) { res.writeHead(200, {\u2018Content-Type\u2019: \u2018text\/event-stream\u2019, \u2018Cache-Control\u2019: \u2018no-cache\u2019}); \/\/ get the last event id and convert to a number var lastId = req.headers[\u2018last-event-id\u2019]*1; if (lastId) { for (var i = lastId; i &lt; eventId; i++) { res.write(\u2018data: \u2018 + JSON.stringify(history[eventId]) + \u2018\\nid: \u2018 + eventId + \u2018\\n\u2019); } }<\/p>\n<p>\/\/ finally cache the response connection connections.push(res);<\/p>\n<p>\/\/ When a regular web request is received connections.forEach(function (response) { history[++eventId] = { agent: req.headers[\u2018user-agent\u2019], time: +new Date }; res.write(\u2018data: \u2018 + JSON.stringify(history[eventId]) + \u2018\\nid: \u2018 + eventId + \u2018\\n\u2019); }); }).listen(1337, \u2018127.0.0.1\u2019); console.log(\u2018Server running at http:\/\/127.0.0.1:1337\/\u2019);<br>\nEn el lado del cliente, el c\u00f3digo ser\u00eda tan sencillo como el siguiente:<br>\nvar es = new EventSource(\u2018\/eventsource\u2019); es.onmessage = function (event) {<\/p>\n<p>var data = JSON.parse(event.data); log.innerHTML += \u2018&lt;li&gt;&lt;strong&gt;\u2019 + data.agent + \u2018&lt;\/strong&gt;&lt;br&gt; connected at &lt;em&gt;\u2019 + (new Date(data.time)) + \u2018&lt;\/em&gt;&lt;\/li&gt;\u2019; };<br>\nUna aplicaci\u00f3n muy simple, pero que nos da una idea del funcionamiento de los eventos en tiempo real, utilizando un servidor basado en eventos.<\/p>\n<h2><span style=\"text-decoration: underline;\"><strong><em>Eventsource<\/em><\/strong><\/span><\/h2>\n<p><a href=\"https:\/\/www.facebook.com\/disenopaginaweb\">#queesventsource<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Eventsource \u00a0 Los\u00a0EventSource\u00a0(tambi\u00e9n conocidos como Server-Sent Events), son eventos en tiempo real transmitidos por el servidor y recibidos en el navegador. Son similares a los WebSockets en que suceden el tiempo real, pero son principalmente un m\u00e9todo de comunicaci\u00f3n unidireccional desde el servidor. Al igual que en los WebSocket, creamos una nueva conexi\u00f3n indicando la &hellip;<\/p>\n<p class=\"read-more\"> <a class=\"ast-button\" href=\"https:\/\/disenoweb.mx\/blog\/eventsource\/\"> <span class=\"screen-reader-text\">Eventsource<\/span> Leer m\u00e1s \u00bb<\/a><\/p>\n","protected":false},"author":1,"featured_media":4040,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"default","ast-global-header-display":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","_joinchat":[],"footnotes":""},"categories":[1189,55],"tags":[70,46,143,47,779,128],"class_list":["post-3626","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desarrollo-web","category-diseno-web","tag-diseno","tag-diseno-web","tag-diseno-web-df","tag-diseno-web-guadalajara","tag-eventsource","tag-sitio-web"],"_links":{"self":[{"href":"https:\/\/disenoweb.mx\/blog\/wp-json\/wp\/v2\/posts\/3626","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/disenoweb.mx\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/disenoweb.mx\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/disenoweb.mx\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/disenoweb.mx\/blog\/wp-json\/wp\/v2\/comments?post=3626"}],"version-history":[{"count":0,"href":"https:\/\/disenoweb.mx\/blog\/wp-json\/wp\/v2\/posts\/3626\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/disenoweb.mx\/blog\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/disenoweb.mx\/blog\/wp-json\/wp\/v2\/media?parent=3626"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/disenoweb.mx\/blog\/wp-json\/wp\/v2\/categories?post=3626"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/disenoweb.mx\/blog\/wp-json\/wp\/v2\/tags?post=3626"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}