- Notifications
You must be signed in to change notification settings - Fork230
Server Sent Events#381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Merged
joaquinelio merged 7 commits intojavascript-tutorial:masterfromhomero304:Server-Sent-EventsSep 21, 2020
Uh oh!
There was an error while loading.Please reload this page.
Merged
Changes fromall commits
Commits
Show all changes
7 commits Select commitHold shift + click to select a range
110a9c4 Server Sent Events
omero3297dbf41d Merge branch 'master' into Server-Sent-Events
omero3294d8b170 Segunda línea - 49:
omero32982d2366 Update 5-network/12-server-sent-events/article.md
omero32972f9898 Update 5-network/12-server-sent-events/article.md
omero329cd290ad Update 5-network/12-server-sent-events/article.md
omero329aff46c4 Update 5-network/12-server-sent-events/article.md
omero329File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
222 changes: 111 additions & 111 deletions5-network/12-server-sent-events/article.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,271 +1,271 @@ | ||
| #Eventos enviados por el servidor | ||
| La especificación de los [Eventos enviados por el servidor](https://html.spec.whatwg.org/multipage/comms.html#the-eventsource-interface)describe una clase incorporada`EventSource`,que mantiene la conexión con el servidor y permite recibir eventos de él. | ||
| Similara `WebSocket`,la conexión es persistente. | ||
| Pero existen varias diferencias importantes: | ||
| | `WebSocket` | `EventSource` | | ||
| |-------------|---------------| | ||
| |Bidireccional: tanto el cliente como el servidor pueden intercambiar mensajes | Unidireccional: solo el servidor envía datos | | ||
| |Datos binarios y de texto | Solo texto | | ||
| |ProtocoloWebSocket|HTTP regular | | ||
| `EventSource`es una forma menos poderosa de comunicarse con el servidor que `WebSocket`. | ||
| ¿Por qué debería uno usarlo? | ||
| El motivo principal: es más sencillo. En muchas aplicaciones, el poder de `WebSocket`es demasiado. | ||
| Necesitamos recibir un flujo de datos del servidor: tal vez mensajes dechato precios de mercado, o lo que sea. Para eso es bueno`EventSource`. También admite la reconexión automática, algo que debemos implementar manualmente con`WebSocket`.Además, esHTTP común, no un protocolo nuevo. | ||
| ##Recibir mensajes | ||
| Para comenzar a recibir mensajes, solo necesitamos crear un `new EventSource(url)`. | ||
| El navegador se conectará a la`url`y mantendrá la conexión abierta, esperando eventos. | ||
| El servidor debe responder con el estado200y el encabezado `Content-Type:text/event-stream`,entonces mantener la conexión y escribir mensajes en el formato especial, así: | ||
| ``` | ||
| data:Mensaje 1 | ||
| data:Mensaje 2 | ||
| data:Mensaje 3 | ||
| data:de dos líneas | ||
| ``` | ||
| -Un mensaje de texto va después de`data:`,el espacio después de los dos puntos es opcional. | ||
| -Los mensajes están delimitados con saltos de línea dobles `\n\n`. | ||
| -Para enviar un salto de línea`\n`,podemos enviar inmediatamente un`data:` (tercer mensaje arriba) más. | ||
| En la práctica, los mensajes complejos generalmente se envían codificados enJSON. Los saltos de línea están codificados así`\n`dentro de los mensajes, por lo que los mensajes`data:`multilínea no son necesarios. | ||
| Por ejemplo: | ||
| ```js | ||
| data: {"user":"John","message":"Primera línea*!*\n*/!*Segunda línea"} | ||
| ``` | ||
| ... Entonces podemos asumir que un `data:`contiene exactamente un mensaje. | ||
| Para cada uno de estos mensajes, se genera el evento `message`: | ||
| ```js | ||
| let eventSource = new EventSource("/events/subscribe"); | ||
| eventSource.onmessage = function(event) { | ||
| console.log("Nuevo mensaje", event.data); | ||
| //registrará apuntes 3veces para el flujo de datos anterior | ||
| }; | ||
| //o eventSource.addEventListener('message', ...) | ||
| ``` | ||
| ###SolicitudesCross-origin | ||
| `EventSource`admite solicitudescross-origin, como `fetch`o cualquier otro método de red. Podemos utilizar cualquier URL: | ||
| ```js | ||
| let source = new EventSource("https://another-site.com/events"); | ||
| ``` | ||
| El servidor remoto obtendrá el encabezado `Origin`y debe responder con`Access-Control-Allow-Origin`para continuar. | ||
| Para pasar las credenciales, debemos configurar la opción adicional`withCredentials`,así: | ||
| ```js | ||
| let source = new EventSource("https://another-site.com/events", { | ||
| withCredentials: true | ||
| }); | ||
| ``` | ||
| Consulte el capítulo<info:fetch-crossorigin>para obtener más detalles sobre los encabezadoscross-origin. | ||
| ##Reconexión | ||
| Tras la creación con`new EventSource`, el cliente se conecta al servidor y, si la conexión se interrumpe, se vuelve a conectar. | ||
| Eso es muy conveniente, ya que no tenemos que preocuparnos por eso. | ||
| Hay un pequeño retraso entre las reconexiones, unos segundos por defecto. | ||
| El servidor puede establecer la demora recomendada usando `retry:`dentro de la respuesta (en milisegundos): | ||
| ```js | ||
| retry: 15000 | ||
| data:Hola, configuré el retraso de reconexión en 15segundos | ||
| ``` | ||
| El `retry:`puede venir junto con algunos datos, o como un mensaje independiente. | ||
| El navegador debe esperar esa cantidad de milisegundos antes de volver a conectarse. O más, por ejemplo: si el navegador sabe (desde el sistema operativo) quenohay conexión de red en este momento, puede esperar hasta que aparezca la conexión y luego volver a intentarlo. | ||
| -Si el servidor desea que el navegador deje de volver a conectarse, debería responder con el estado HTTP 204. | ||
| -Si el navegador quiere cerrar la conexión, debe llamar a `eventSource.close()`: | ||
| ```js | ||
| let eventSource = new EventSource(...); | ||
| eventSource.close(); | ||
| ``` | ||
| Además,nohabrá reconexión si la respuesta tiene un `Content-Type`incorrecto o su estado HTTP difiere de301, 307, 200y 204.En tales casos, se emitirá el evento`"error"`y el navegador no se volverá a conectar. | ||
| ```smart | ||
| Cuando una conexión finalmente se cierra,nohay forma de "reabrirla". Si queremos conectarnos de nuevo, simplemente crea un nuevo `EventSource`. | ||
| ``` | ||
| ##ID del mensaje | ||
| Cuando una conexión se interrumpe debido a problemas de red, ninguna de las partes puede estar segura de qué mensajes se recibieron y cuáles no. | ||
| Para reanudar correctamente la conexión, cada mensaje debe tener un campo`id`, así: | ||
| ``` | ||
| data:Mensaje 1 | ||
| id: 1 | ||
| data:Mensaje 2 | ||
| id: 2 | ||
| data:Mensaje 3 | ||
| data:de dos líneas | ||
| id: 3 | ||
| ``` | ||
| Cuando se recibe un mensaje con`id:`, el navegador: | ||
| -Establece la propiedad `eventSource.lastEventId`a su valor. | ||
| -Tras la reconexión, el navegador envía el encabezado`Last-Event-ID`con ese `id`,para que el servidor pueda volver a enviar los siguientes mensajes. | ||
| ```smart header="Pon `id:`después de `data:`" | ||
| Ten en cuenta: el `id`es adjuntado debajo del mensaje`data`por el servidor, para garantizar que `lastEventId`se actualice después de recibir el mensaje. | ||
| ``` | ||
| ##Estado de conexión: readyState | ||
| El objeto`EventSource`tiene la propiedad`readyState`, que tiene uno de tres valores: | ||
| ```js no-beautify | ||
| EventSource.CONNECTING = 0; //conectando o reconectando | ||
| EventSource.OPEN = 1; //conectado | ||
| EventSource.CLOSED = 2; //conexión cerrada | ||
| ``` | ||
| Cuando se crea un objeto, o la conexión no funciona, siempre es `EventSource.CONNECTING` (es igual a `0`). | ||
| Podemos consultar esta propiedad para conocer el estado de `EventSource`. | ||
| ##Tipos de eventos | ||
| Por defecto, el objeto`EventSource`genera tres eventos: | ||
| - `message` --un mensaje recibido, disponible como `event.data`. | ||
| - `open` --la conexión está abierta. | ||
| - `error` --no se pudo establecer la conexión, por ejemplo, el servidor devolvió el estadoHTTP 500. | ||
| El servidor puede especificar otro tipo de evento con `event: ...`al inicio del evento. | ||
| Por ejemplo: | ||
| ``` | ||
| event: join | ||
| data: Bob | ||
| data:Hola | ||
| event: leave | ||
| data: Bob | ||
| ``` | ||
| Para manejar eventos personalizados, debemos usar`addEventListener`,no `onmessage`: | ||
| ```js | ||
| eventSource.addEventListener('join', event => { | ||
| alert(`Se unió ${event.data}`); | ||
| }); | ||
| eventSource.addEventListener('message', event => { | ||
| alert(`Dijo: ${event.data}`); | ||
| }); | ||
| eventSource.addEventListener('leave', event => { | ||
| alert(`Salió ${event.data}`); | ||
| }); | ||
| ``` | ||
| ##Ejemplo completo | ||
| Aquí está el servidor que envía mensajes con`1`, `2`, `3`,luego `bye`y cierra la conexión. | ||
| Luego, el navegador se vuelve a conectar automáticamente. | ||
| [codetabs src="eventsource"] | ||
| ##Resumen | ||
| El objeto`EventSource`establece automáticamente una conexión persistente y permite al servidor enviar mensajes a través de él. | ||
| Ofrece: | ||
| -Reconexión automática, con tiempo de espera de `reintento` ajustable. | ||
| -IDs en cada mensaje para reanudar los eventos, el último identificador recibido se envía en el encabezado`Last-Event-ID`al volver a conectarse. | ||
| -El estado actual está en la propiedad`readyState`. | ||
| Eso hace que`EventSource`sea una alternativa viable a`WebSocket`,ya que es de un nivel más bajo y carece de esas características integradas (aunque se pueden implementar). | ||
| En muchas aplicaciones de la vida real, el poder de `EventSource`es suficiente. | ||
| Compatible con todos los navegadores modernos (no IE). | ||
| La sintaxis es: | ||
| ```js | ||
| let source = new EventSource(url, [credentials]); | ||
| ``` | ||
| El segundo argumento tiene solo una opción posible: `{withCredentials: true}`,permite enviar credenciales decross-origin. | ||
| La seguridad general decross-origines la misma que para `fetch`y otros métodos de red. | ||
| ###Propiedades de un objeto`EventSource` | ||
| `readyState` | ||
| :El estado de conexión actual:`EventSource.CONNECTING (=0)`, `EventSource.OPEN (=1)`o `EventSource.CLOSED (=2)`. | ||
| `lastEventId` | ||
| :El último`id` recibido. Tras la reconexión, el navegador lo envía en el encabezado `Last-Event-ID`. | ||
| ###Métodos | ||
| `close()` | ||
| :Cierra la conexión. | ||
| ###Eventos | ||
| `message` | ||
| :Mensaje recibido, los datos están en `event.data`. | ||
| `open` | ||
| :Se establece la conexión. | ||
| `error` | ||
| :En caso deerror,se incluyen tanto la pérdida de conexión (se reconectará automáticamente) como los errores fatales. Podemos comprobar`readyState`para ver si se está intentando la reconexión. | ||
| El servidor puede establecer un nombre de evento personalizado en`event:`.Tales eventos deben manejarse usando`addEventListener`,no `on<evento>`. | ||
| ###Formato de respuesta del servidor | ||
| El servidor envía mensajes, delimitados por `\n\n`. | ||
| Un mensaje puede tener los siguientes campos: | ||
| - `data:` --cuerpo del mensaje, una secuencia de múltiples `datos` se interpreta como un solo mensaje, con `\n`entre las partes. | ||
| - `id:` --renueva `lastEventId`,enviado en el encabezado`Last-Event-ID`al volver a conectarse. | ||
| - `retry:` --recomienda una demora de reintento para las reconexiones en milisegundos. No hay forma de configurarlo desde JavaScript. | ||
| - `event:` --nombre del evento, debe preceder a `data:`. | ||
| Un mensaje puede incluir uno o más campos en cualquier orden, pero `id:`suele ser el último. |
Oops, something went wrong.
Uh oh!
There was an error while loading.Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.