javascript 服务器发送事件究竟是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6109418/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 19:30:42  来源:igfitidea点击:

How exactly does Server-Sent Events work?

javascriptperlserver-sent-events

提问by Mike

I am trying to get into the web push technology so I started looking around. I have basically found 2 technologies, that is Websockets and SSE. After ruling out Websockets because of lack of perl support, I wanted to try out the more native SSE-approach.

我正在尝试进入网络推送技术,所以我开始四处寻找。我基本上找到了 2 种技术,即 Websockets 和 SSE。由于缺乏 perl 支持而排除了 Websockets 之后,我想尝试更原生的 SSE 方法。

Now, trying to get SSE to work is a real pain in the arse. Every documentation has conflicting information and there does not seem to be a general consensus on how SSE works. Some say hat you need an <event-listen src="events.pm">tag, others say you only need an EventSourceJS object. Even with the EventSource object, I found around 4 possible implementations and none of them seem to work.

现在,试图让 SSE 发挥作用是一件非常痛苦的事情。每个文档都有相互矛盾的信息,并且似乎没有就 SSE 的工作方式达成普遍共识。有人说你需要一个<event-listen src="events.pm">标签,有人说你只需要一个EventSourceJS 对象。即使使用 EventSource 对象,我也发现了大约 4 种可能的实现,但它们似乎都不起作用。

Here is what I have. I have an events.pm, which uses mod-perl. If you call that file, it returns data: I haz a websocket. That is sent with the content-type application/x-dom-event-stream.

这是我所拥有的。我有一个events.pm,它使用 mod-perl。如果您调用该文件,它将返回data: I haz a websocket. 那是与 content-type 一起发送的application/x-dom-event-stream

The HTML and JS files have been rewritten so often with different implementations that I have given up on them. Can you guys please give me a working example?

HTML 和 JS 文件经常用不同的实现重写,我已经放弃了它们。你们能给我一个有效的例子吗?

Also: I do not understand how you can send specific messages to the client. Sending a predefined message seems to be fine. However, if I imagine a situation where someone sends me a message, I do not understand how exactly that information ('there is a new message for you') is transmitted to that exact browser that needs that information. Every post I found on this is vague at best.

另外:我不明白您如何向客户端发送特定消息。发送预定义的消息似乎没问题。但是,如果我想象有人向我发送消息的情况,我不明白该信息(“有一条新消息给您”)究竟是如何传输到需要该信息的确切浏览器的。我在这方面找到的每个帖子充其量都是含糊不清的。

EDIT

编辑

Basically, what I need is a way to say 'hey, are you allowed to get this notification? show me your id/session/token first!' on a per connected client basis. I wonder if it is at all possible with SSE.

基本上,我需要的是一种说‘嘿,你能收到这个通知吗?先给我看看你的 ID/会话/令牌!基于每个连接的客户端。我想知道 SSE 是否有可能。

采纳答案by yojimbo87

I would say that Server-sent events are described pretty good in Stream Updates with Server-Sent Eventsarticle, namely the Event Stream Format. With Firefox 6 SSEs are now supported by majority of modern browsers (unfortunately except IE).

我会说服务器发送的事件在带有服务器发送事件的流更新文章中描述得非常好,即事件流格式。现在大多数现代浏览器都支持 Firefox 6 SSE(不幸的是,IE 除外)。

I do not understand how you can send specific messages to the client. Sending a predefined message seems to be fine. However, if I imagine a situation where someone sends me a message, I do not understand how exactly that information ('there is a new message for you') is transmitted to that exact browser that needs that information.

我不明白您如何向客户端发送特定消息。发送预定义的消息似乎没问题。但是,如果我想象有人向我发送消息的情况,我不明白该信息(“有一条新消息给您”)究竟是如何传输到需要该信息的确切浏览器的。

Clients are connected with the SSE server by keep-alive event stream, uni-directional connection which isn't closed until browser/tab is closed, user invokes close method or network connection is lost.

客户端通过保持活动事件流与 SSE 服务器连接,单向连接在浏览器/选项卡关闭之前不会关闭,用户调用 close 方法或网络连接丢失。

Basically, what I need is a way to say 'hey, are you allowed to get this notification? show me your id/session/token first!' on a per connected client basis. I wonder if it is at all possible with SSE.

基本上,我需要的是一种说‘嘿,你能收到这个通知吗?先给我看看你的 ID/会话/令牌!基于每个连接的客户端。我想知道 SSE 是否有可能。

This kind of authentication logic would be required to do on the server side, so it's dependent on the language or platform you are using. Unless there is library for that in your environment you would probably have to write it.

这种身份验证逻辑需要在服务器端执行,因此它取决于您使用的语言或平台。除非您的环境中有用于该库的库,否则您可能必须编写它。

回答by Kornel

The spec has changed/evolved. Current version uses EventSourceobject. The HTML element is gone.

规范已经改变/发展。当前版本使用EventSource对象。HTML 元素不见了。

The current MIME type is text/event-stream. The x-dom-event-streamwas used only in early implementations (Opera in 2006).

当前的 MIME 类型是text/event-stream. 将x-dom-event-stream只使用在早期实现(歌剧于2006年)。

To identify/authenticate clients you can either use cookies or connect to an event stream URL that includes some kind of authentication token (session ID), and then you'll know that a particular TCP/IP connection is associated with that user.

要识别/验证客户端,您可以使用 cookie 或连接到包含某种身份验证令牌(会话 ID)的事件流 URL,然后您就会知道特定的 TCP/IP 连接与该用户相关联。

http://html5doctor.com/server-sent-events/

http://html5doctor.com/server-sent-events/

回答by Fatih

Adding to @porneL's answer; you can tell EventSourceto include cookies to the request it sends. Just create the EventSourceobject like this:

添加到@porneL 的答案;您可以告诉EventSource在它发送的请求中包含 cookie。只需EventSource像这样创建对象:

var evtsrc = new EventSource('./url_of/event_stream/',{withCredentials:true});

I tested this with latest version of chrome and firefox.

我用最新版本的 chrome 和 firefox 对此进行了测试。

Source: http://www.sitepoint.com/server-sent-events/

来源:http: //www.sitepoint.com/server-sent-events/

edit: apparently this is not necessary / useless. See @Tamlyn's comment.

编辑:显然这没有必要/没用。请参阅@Tamlyn 的评论。