javascript 事件源 EventSource
作者 : Jacky 发布于 2024-03-22 09:53:44 浏览 588 次
JavaScript的EventSource(事件源)对象提供了一种在客户端与服务器之间实现服务器推送的机制。它允许服务器通过HTTP协议发送事件流(Event stream)到客户端,而无需通过客户端的Ajax轮询。 EventSource对象是HTML5的一部分,由W3C规范定义。它的用途主要是实现实时通信(Real-time Communication, RTC)和服务器推送技术。

1.EventSource的创建

要使用EventSource对象,首先需要创建一个EventSource实例。创建EventSource实例时,需要传入一个URL参数,用于指定服务器端的事件源。例如:

var source = new EventSource("/GetSystemInfo", { withCredentials: true });

上述代码创建了一个EventSource对象,并指定了服务器端的事件源为/GetSystemInfo。

2.EventSource事件

EventSource对象提供了多个事件,用于监听与服务器端的通信状态。

2.1 open事件

当与服务器端建立连接时,open事件被触发。可以通过监听open事件来判断与服务器的连接状态,并执行相应的操作。例如:

source.onopen = function (e) {
    console.log('EventSource started!');
}

2.2 message事件

当服务器发送事件流(Event stream)时,message事件被触发。可以通过监听message事件来获取服务器发送的数据,并执行相应的操作。例如

source.onmessage = function(e){
    console.log('EventSource receive data:'+e.data);
}

2.3 error事件

当与服务器的连接发生错误时,error事件被触发。可以通过监听error事件来处理连接错误,并执行相应的操作。例如:

source.onerror = function (e) {
    console.log('EventSource error:'+e);
}

2.4 完整实例

下面是一个完整的示例,演示了如何监听EventSource的open、message和error事件:

var source = new EventSource("/GetSystemInfo", { withCredentials: true });
source.onopen = function (e) {
    console.log('EventSource started!');
}
source.onerror = function (e) {
    console.log('EventSource error:'+e);
}
source.onmessage = function(e){
    console.log('EventSource receive data:'+e.data);
}

3 EventSource 属性

EventSource对象还提供了一些属性,用于获取与服务器端的连接状态和事件信息。

3.1 readyState 属性

readyState属性用于获取与服务器的连接状态。它的值有以下几种:
1.CONNECTING:正在与服务器建立连接。
2.OPEN:与服务器已建立连接。
3.CLOSED:与服务器的连接已关闭。
可以通过监听readyState属性的变化,来获取当前连接的状态。例如:

console.log('connect status:', source.readyState);

3.2 url 属性

url属性用于获取EventSource对象所连接的服务器端URL。例如:

console.log('连接到的服务器URL:', source.url);

3.3 withCredentials 属性

withCredentials属性用于设置是否发送跨域请求时发送凭证(如Cookie、HTTP认证等)。默认值为 false,表示不发送凭证。例如:

source.withCredentials = true;

3.4 示例

下面是一个示例,演示了如何使用EventSource的属性:

var source = new EventSource('/GetSystemInfo');
console.log('连接状态:', source.readyState);
console.log('连接到的服务器URL:', source.url);
source.withCredentials = true;

4 服务端配置

要使用EventSource,服务器端需要配置支持服务器推送(Server-Sent Events)的功能。服务器需要设置特定的HTTP头,并按照规范发送事件流。

以下是一个使用 .net core 简单示例,展示了如何配置服务器端以支持EventSource:

/// <summary>
/// 获取系统信息
/// </summary>
/// <returns></returns>
public async Task GetSystemInfo()
{
    Response.ContentType = "text/event-stream";
    await Task.Run(async () =>
    {
        while (true)
        {
            var process = Process.GetCurrentProcess();
            var useMemory = process.WorkingSet64 / 1024.0 / 1024;
            var startCpu = process.TotalProcessorTime;
            var startTime = DateTime.UtcNow;
            await Task.Delay(1000);
            var endCpu = process.TotalProcessorTime;
            var endTime = DateTime.UtcNow;
            var useCpu = (endCpu - startCpu).TotalMilliseconds / ((endTime - startTime).TotalMilliseconds * Environment.ProcessorCount);
            await WriteDataAsync(ResponseState.success, "", new
            {
                cpu = useCpu,
                rem = useMemory,
                runtime = DateTime.Now.Subtract(process.StartTime).TotalSeconds,
                threads = process.Threads.Count
            });
            await Task.Delay(5000);
        }
    });
}
/// <summary>
/// 写数据
/// </summary>
/// <param name="state">状态</param>
/// <param name="message">消息</param>
/// <param name="data">数据</param>
/// <returns></returns>
private async Task WriteDataAsync(ResponseState state,string message,object data)
{
    var msg = "id: {0}\nretry: 10000\nevent: message\ndata: {1}\n\n";
    await Response.Body.WriteAsync(msg.format(Guid.NewGuid().ToString("N"), new
    {
        status = state.ToString(),
        message = message,
        data = data
    }.ToJson()).GetBytes());
    await Response.Body.FlushAsync();
}

5. nginx 配置

nginx 配置以下节点才可以转发eventsource事件

proxy_set_header      Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;

6. 浏览器兼容性

EventSource对象在现代浏览器中有良好的兼容性,并且不依赖任何外部库。以下是一些支持EventSource的常见浏览器版本:

  • Chrome 6+
  • Firefox 6+
  • Safari 5+
  • Opera 11.6+
  • Edge 12+
  • Internet Explorer 不支持

需要注意的是,Internet Explorer不支持EventSource对象,需要使用Polyfill库或其他技术来实现类似的功能。

所有评论(0)