WEB communication technology. The front end realizes SSE long connection, nodejs+express builds a simple server, performs interface debugging, and requests data through curl

describe

Long connection (Keep-Alive) is a persistent connection technology of HTTP/1.1, which allows the client and server to perform multiple HTTP requests and responses on one TCP connection, without having to establish and disconnect one for each request/response new connection. Long connections help reduce server load and improve performance.

The HTTP request method of the persistent connection is the same as the ordinary HTTP request method, and HTTP request methods such as GET, POST, PUT, and DELETE can be used. However, before sending the HTTP response, the "Connection: keep-alive" request header needs to be set to indicate that the client wishes to establish a long-lasting connection with the server. Server-Sent Events (SSE for short) is a new API proposed to solve this problem, which is deployed on the EventSource object. Currently, all major browsers except IE support it. And the client (browser) is EventSource using HTML5.
SSE and WebSocket have similar functions, and both are used to establish a communication channel between the browser and the server. The difference between the two is:

  • WebSocket is a full-duplex channel, which can communicate in two directions and has stronger functions; SSE is a one-way channel, which can only be sent from the server to the browser.

  • WebSocket is a new protocol that requires server-side support; SSE is deployed on top of the HTTP protocol and is supported by existing server software.

  • SSE is a lightweight protocol that is relatively simple; WebSocket is a heavy protocol that is relatively complex.

  • SSE supports disconnection and reconnection by default, while WebSocket requires additional deployment.

  • SSE supports custom data types sent.

From the above comparison, we can see that both have their own characteristics and are suitable for different occasions.

client code

establish connection

  • First, the browser initiates a connection to the server and generates an instance object of EventSource.
  • The newly generated EventSource instance object has a readyState attribute, which indicates the state of the connection.

It can take the following values:
0, equivalent to the constant EventSource.CONNECTING, indicating that the connection has not been established, or the connection is disconnected.
1. It is equivalent to the constant EventSource.OPEN, indicating that the connection has been established and data can be accepted.
2. It is equivalent to the constant EventSource.CLOSED, indicating that the connection has been disconnected and will not be reconnected.

Open event Once the connection is established, the open event will be triggered, and the corresponding callback function can be defined.

The message event triggers the message event when data is received.
The parameter object event has the following attributes:
data: the data returned by the server (in text format).
origin: The domain name part of the server-side URL, that is, the protocol, domain name, and port.
lastEventId: The serial number of the data, sent by the server. If there is no number, this property is empty.

error event If a communication error occurs (such as a connection interruption), the error event will be triggered.

let source = ''
 if (!!window.EventSource) {
    
    
    source = new EventSource('http://localhost:8088/sses/');
 }
 source.onopen = function(event) {
    
    
   // handle open event
   console.log(source.readyState);
   console.log("长连接打开");
 };
 source.onmessage = function(event) {
    
    
   console.log(event);
   console.log(JSON.parse(event.data));
   console.log(source.readyState);
   console.log("收到长连接信息");
 };
 source.onerror = function(event) {
    
    
   console.log(source.readyState);
   console.log("长连接中断");
   // source.close();
 };

insert image description here


Set the SSE request header.

When using the EventSource object, you can set the request header to specify some additional parameters. These parameters are usually used to tell the server how to handle SSE requests, or for operations such as authentication.
To set the request header, you can pass in a configuration object when creating the EventSource object, for example:

const eventSource = new EventSource('/sse', {
    
    
  withCredentials: true,
  headers: {
    
    
    'Authorization': 'Bearer xxxxx',
    'X-Custom-Header': 'value'
  }
});

In the above code, we set the withCredentials parameter to true, indicating that the SSE request will carry cross-domain authentication information (if any). We also set two request headers, Authorization and X-Custom-Header, which are used to pass the authentication token and custom parameters respectively.

In addition to the commonly used request headers above, there are some other request headers that can be used, for example:

Last-Event-ID: It is used to specify the ID of the last received SSE event so that the server can send a new event.
Cache-Control: Used to control the cache policy for SSE requests.
Connection: Used to specify the connection type of the SSE request, usually set to keep-alive.
Accept: It is used to specify the SSE data type that the client can accept.
Note that not all request headers are supported by all browsers and servers. When using it, you need to check the relevant documents to determine whether it is available.


  • withCredentialsIt is an attribute of the XMLHttpRequest object, which is used to specify whether to carry authentication information (such as cookie, HTTP authentication, etc.) when cross-domain requests are made.
  • By default, cross-origin requests do not carry authentication information, as this could pose a security risk. But in some cases, we need to carry authentication information in cross-domain requests, such as sending user authentication credentials to the server. At this time, you can let the browser carry the authentication information by setting the withCredentials attribute.
  • When withCredentialsset to true, the browser will add a Cookie field or Authorization field (if HTTP authentication is used) to the request header. In this way, the server can identify the user identity of the current request and process it accordingly. It should be noted that if the server does not explicitly allow cross-origin requests to carry authentication information, the browser will still not send authentication information.
  • In the SSE request, withCredentials is the same as in the XMLHttpRequest object, and is used to specify whether the SSE request carries cross-domain authentication information. If you need to carry authentication information in the SSE request, you need to set withCredentials to true.

curl is a commonly used command line tool

curl is a commonly used command line tool that supports multiple protocols, including HTTP, HTTPS, FTP, SMTP, etc., and can be used to send HTTP requests, download files, upload files, etc. curl can be used from the command line or as a library in scripts.

Using curl, you can send an HTTP request to a server and receive a response, then display the response on the command line or save it to a file. Curl can set HTTP request parameters such as request header, request method, and request body, and also supports proxy, cookie, SSL and other features.
insert image description here

Here's an example of using curl to send a GET request and save the response to a file:

curl -o response.txt https://example.com

nodejs server

const express = require('express');
const Aixpor = require("./options")
const app = express()
const port = 8088

//设置跨域访问
app.all("*", function(req, res, next) {
    
    
	//设置允许跨域的域名,*代表允许任意域名跨域
	res.header("Access-Control-Allow-Origin", req.headers.origin || '*');
	 // //只允许http://xxx.xx.xx/可跨
    //res.header('Access-Control-Allow-Origin', 'http://xxx.xx.xx/');
	//允许的header类型
	res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
	//跨域允许的请求方式 
	res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
	// 可以带cookies
	res.header("Access-Control-Allow-Credentials", true);
	if (req.method == 'OPTIONS') {
    
    
		res.sendStatus(200);
	} else {
    
    
		next();
	}
})

app.listen(port, () => {
    
    
	console.log(`Example app listening at http://localhost:${
      
      port}`)
})

//实现接口
Aixpor.List(app);
Aixpor.Longstream(app);
//写个接口list
const List = function(app){
    
    
  var data = [{
    
    
		label: '早晨',
		value: '面条'
	},
	{
    
    
		label: '中午',
		value: '煎饼'
	}
];
  app.get('/list', function(req, res) {
    
    
    res.status(200);
    res.json(data);
  });
}

//长连接接口
const Longstream = function(app){
    
    
  var data = [{
    
    
		label: '早晨',
		value: '面条'
	},
	{
    
    
		label: '中午',
		value: '煎饼'
	}
  ];
  app.get('/sses', function(req, res) {
    
    
    res.set({
    
    
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive'
    });
    // 及时发送刷新响应头
    res.flushHeaders();
    setInterval(() => {
    
    
      const data = {
    
    
        message: `Current time is ${
      
      new Date().toLocaleTimeString()}`
      };
    res.write(`data: ${
      
      JSON.stringify(data)}\n\n`);
    }, 3000);  
  });
}
module.exports = {
    
    List,Longstream}

It can be eaten directly.

Description: res.flushHeaders()

In Node.js, res.flushHeaders() is a method for manually flushing HTTP response headers. It is usually used when the response headers need to be sent immediately without waiting for the response body. This is useful in certain situations, such as when dealing with large file downloads or streaming.

When Node.js receives an HTTP request, it automatically creates a response object res for the request, which has some properties and methods for setting and sending the HTTP response. The res.flushHeaders() method will immediately send the HTTP response headers to the client without waiting until the entire response body is ready. This can send response headers to the client faster and let the client know the content type, length, etc. of the response earlier.

Here is an example using the res.flushHeaders() method that sends a large file via streaming

const http = require('http');
const fs = require('fs');

http.createServer(function(req, res) {
    
    
  res.writeHead(200, {
    
    
    'Content-Type': 'application/octet-stream',
    'Content-Disposition': 'attachment; filename=largefile.dat'
  });

  const stream = fs.createReadStream('/path/to/largefile.dat');
  stream.pipe(res);

  // 刷新响应头
  res.flushHeaders();
}).listen(8080);

In the above example, we created a readable stream using the createReadStream() method and connected it to the res response object through the pipe pipe() method. Before starting to transfer the file, we called the res.writeHead() method to set the HTTP response headers, and called the res.flushHeaders() method during the transfer to immediately send the HTTP response headers to the client. In this way, the client can know information such as the file type and size faster, and start downloading the file.

For more details, please refer to: SSE description

Guess you like

Origin blog.csdn.net/m0_46672781/article/details/130296397