Directorio de artículos
SSE (Eventos enviados por el servidor): en términos generales, es una tecnología basada en HTTP que envía continuamente datos desde el servidor al cliente en forma de flujo.
1. ESS
El servidor envía eventos según el http
protocolo, y es un canal único (el servidor envía datos al clienteWebSocket
) en comparación con el canal dúplex completo ( web
el cliente y el servidor se comunican entre sí ) . es una parte integral de la especificación.SSE
HTML 5
Escenas a utilizar
- alerta de nuevo correo
- video en vivo
- Supervise los datos en tiempo real del sistema.
En la web
función push del mensaje del terminal, debido a que el HTTP
protocolo tradicional es que el cliente inicia activamente la solicitud, el servidor responderá. Este es el caso de las técnicas básicas de ajax
sondeo. En SSE
, el navegador envía una solicitud al servidor y declara al cliente que se trata de una conexión larga a través de la Content-Type:text/event-stream
espera en el encabezado de respuesta, y envía datos de transmisión para que el cliente no cierre la conexión y espere a que el servidor enviar datos
Ejemplo de respuesta del servidor
//如下,每个事件通过空行来分隔,对于每一行来说, 冒号前表示的是该行的类型,冒号后面是对应的值
data: first event //类型为data, 表示改行表示的是数据,以data开头的行可以多次出现,都是该事件中的数据
data: second event
id: 001
event: myevent //类型为event,表示用来声名事件类型,浏览器收到该事件时,会产生对应类型的事件.如果没有该字段,会产生默认类型
data: third event
id: 002 //id,用来声名事件标识符
: this is a comment //类型为空白,表示该行是注释,回在处理时被忽略
data: fourth event
data: fourth event continue
retry: 1000 //表示该行用来声明浏览器在连接断开之后进行再次连接之前的等待时间
Si los datos devueltos por el servidor contienen un identificador de evento , el navegador registra el identificador del último evento recibido. Si se interrumpe la conexión con el servidor, cuando el navegador se vuelva a conectar, declarará el identificador del último evento recibido a través del http
encabezado Last-Event-ID
El servidor puede usar el identificador de evento enviado por el navegador para determinar desde qué evento continuar la conexión.
El navegador procesa los datos devueltos por el servidor.
Para la respuesta devuelta por el servidor, el navegador necesita js
usar el EventSource
objeto para procesarlo. EventSource
Se utiliza el método estándar de monitoreo de eventos: solo se debe agregar el método de procesamiento correspondiente al objeto. EventSource
Se proporcionan tres eventos estándar:
nombre | ilustrar | método de manejo de eventos |
---|---|---|
abierto | Se activa cuando se establece correctamente una conexión con el servidor | al abrir |
mensaje | Se activa cuando se recibe un evento enviado por el servidor | enmensaje |
error | Generado cuando ocurre un error | onerroe |
Si el lado del servidor devuelve tipos de eventos personalizados , puede usar addEventListener
métodos para agregar métodos de manejo de eventos correspondientes para estos eventos, por ejemplo:
let es = new EnventSource('events');
//标准事件
es.onmessage = function (e) {
console.log(e.data);
};
//自定义事件
es.addEventListener('myevent', function(e){
console.log(e.data);
})
Precauciones para usar SSE
- Cómo garantizar la integridad de los datos
Cada vez que el cliente recibe un mensaje, almacenaid
los campos del mensaje como atributos internos . De forma predeterminada, se admite el mecanismo de desconexión y reconexión , y el evento se activará cuando se desconecte la conexión y se volverá a conectar automáticamente al mismo tiempo. Cuando la conexión vuelva a ser exitosa, el atributo se enviará al servidor como un encabezado de solicitud, para que el servidor pueda realizar el procesamiento correspondiente de acuerdo con esto. Cabe señalar aquí que ⚠️ es que el campo no es obligatorio, es posible que el servidor no traiga el campo en el mensaje, por lo que el subcliente no tendrá este atributo. Entonces, para garantizar que los datos sean confiables, debemos agregar campos a cada mensaje.Last-Event-ID
SSE
EventSource
error
EventSource
Last-Event-ID
Last-Event-ID
id
id
Last-Event-ID
id
SSE
IE
Navegador no compatible
Ejemplo de uso
Servidor:
const http = require('http');
const fs = require('fs');
http.createServer((req, res) => {
let data = fs.readFileSync('./1.json');
// 服务器声明接下来发送的是事件流
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*',
});
// 发送消息
setInterval(() => {
res.write('event: slide1\n'); // 事件类型
res.write(`id: ${
+new Date()}\n`); // 消息 ID
res.write(`data:${
data} \n`); // 消息数据
res.write('retry: 10000\n'); // 重连时间
res.write('\n\n'); // 消息结束
}, 5000);
}).listen(2000);
Cliente:
if (window.EventSource) {
// 创建 EventSource 对象连接服务器
const source = new EventSource('http://localhost:2000');
// 连接成功后会触发 open 事件
source.addEventListener('open', () => {
console.log('Connected');
}, false);
// 服务器发送信息到客户端时,如果没有 event 字段,默认会触发 message 事件
source.addEventListener('message', e => {
console.log(`message: ${
e.data}`);
}, false);
// 自定义 EventHandler,在收到 event 字段为 slide 的消息时触发
source.addEventListener('slide1', e => {
console.log(`slide1: ${
e.data}`); // => data: 7
}, false);
// 连接异常时会触发 error 事件并自动重连
source.addEventListener('error', e => {
if (e.target.readyState === EventSource.CLOSED) {
console.log('Disconnected');
} else if (e.target.readyState === EventSource.CONNECTING) {
console.log('Connecting...');
}
}, false);
} else {
console.error('Your browser doesn\'t support SSE');
}
}
Para reducir la sobrecarga del servidor, también podemos desconectarnos y volver a conectarnos a propósito. La forma simple es que el servidor envíe un mensaje de apagado y especifique una marca de tiempo de reconexión, y el cliente cierre la conexión actual y cree un temporizador cuando el evento de apagado se activa. , lo que destruye el temporizador en la reconexión.
2. Sondeo
El cliente envía solicitudes al servidor regularmente, y si el servidor tiene datos, devuelve, y si no hay datos, devuelve datos vacíos.
Ventajas: fácil de implementar
. Desventajas: el tiempo de sondeo está determinado, el intervalo de tiempo es demasiado largo, la puntualidad es deficiente y el intervalo es demasiado corto, lo que provocará una gran cantidad de solicitudes no válidas.
3. WebSocket
¿Qué es el zócalo? ¿Qué es WebSocket?
socket
tcp/ip
No es un protocolo nuevo, es solo una encapsulación del mecanismo de comunicación de la familia de protocolos para comodidad de los programadores en la programación de redes .
websocket
El protocolo es html5
parte de la especificación. Proporciona un mecanismo de comunicación full-duplex para el cliente y el servidor. Es un nuevo protocolo de capa de aplicación. Generalmente expresado como ws://echo.websocket.org/?encoding=text
, se puede ver que excepto por el nombre del protocolo y la http
diferencia, su expresión es consistente con la tradición url
.
Entonces, ¿cómo establece él la conexión? ¿Cómo intercambiar datos? ¿Cómo mantener la conexión?
- Cómo establecer una conexión
Websocket
Utilice el HTTP
canal de apretón de manos tomado. Específicamente, el cliente negocia el protocolo de actualización http
con el servidor a través de una solicitud . WebSocket
Una vez completada la actualización del protocolo, el intercambio de datos posterior sigue el Websocket
protocolo. Entonces, ¿cómo actualizar el protocolo en el lado del cliente?
El proceso de establecer una conexión con WebSocket
- el intercambio de datos
websocket
Una vez que se establece una conexión entre el cliente y el servidor, las operaciones posteriores se basan en la transmisión de tramas de datos .
- Mantente conectado
WebSocket
Para mantener una comunicación bidireccional en tiempo real entre el cliente y el servidor, es necesario asegurarse de que la TCP
conexión entre el cliente y el servidor no esté desconectada. Sin embargo, para una conexión que no tiene intercambio de datos durante mucho tiempo, si aún se mantiene durante mucho tiempo, los recursos de conexión incluidos pueden desperdiciarse. Sin embargo, no se pueden descartar algunos escenarios, aunque el cliente y el servidor no tienen intercambio de datos durante mucho tiempo, todavía necesitan mantener una conexión.
En este momento, el latido del corazón se puede utilizar para lograr:
Remitente -> Receptor:ping
Receptor->Emisor: pong
ping、pong
La operación corresponde a WebSocket
los dos marcos de control, opcode
respectivamente 0x9、0xA
.
Por ejemplo: WebSocket
el servidor envía al cliente ping
, solo se requiere el siguiente código (usando ws
módulos)ws.ping('', false, true);