11# Server Sent Events
22
3- [ Server-Sent Events] ( https://html.spec.whatwg.org/multipage/comms.html#the-eventsource-interface ) 标准描述了一个内建的类 ` EventSource ` ,它能保持与服务器的连接并允许从中接收事件 。
3+ [ Server-Sent Events] ( https://html.spec.whatwg.org/multipage/comms.html#the-eventsource-interface ) 规范描述了一个内建的类 ` EventSource ` ,它能保持与服务器的连接,并允许从中接收事件 。
44
5- 类似于 ` WebSocket ` ,其连接是持久的。
5+ 与 ` WebSocket ` 类似 ,其连接是持久的。
66
7- 但是两者之间也有几个重要的区别 :
7+ 但是两者之间有几个重要的区别 :
88
99| ` WebSocket ` | ` EventSource ` |
1010| -------------| ---------------|
11- | 双向(Bi-directional):客户端和服务端都能修改消息 | 单向( One-directional) :仅服务端能发送消息 |
11+ | 双向:客户端和服务端都能交换消息 | 单向:仅服务端能发送消息 |
1212| 二进制和文本数据 | 仅文本数据 |
13- | WebSocket 协议 | 普通 HTTP 协议 |
13+ | WebSocket 协议 | 常规 HTTP 协议 |
1414
15- 与 ` WebSocket ` 相比,` EventSource ` 是一种与服务器通信的低配版本 。
15+ 与 ` WebSocket ` 相比,` EventSource ` 是与服务器通信的一种不那么强大的方式 。
1616
17- 我们为什么要使用它呢 ?
17+ 我们为什么要使用它 ?
1818
19- 主要原因是 :简单。在许多应用中 ,` WebSocket ` 有点大材小用。
19+ 主要原因 :简单。在很多应用中 ,` WebSocket ` 有点大材小用。
2020
21- 我们需要从服务器接收数据流:可能是聊天消息或者商品价格等等。这是 ` EventSource ` 擅长之处。它支持自动重新连接 ,而在 ` WebSocket ` 中这个功能我们要手动实现。另外,它是一个普通的我们熟知的 HTTP,而不是其他新协议 。
21+ 我们需要从服务器接收一个数据流:可能是聊天消息或者市场价格等。这正是 ` EventSource ` 所擅长的。它还支持自动重新连接 ,而在 ` WebSocket ` 中这个功能需要我们手动实现。此外,它是一个普通的旧的 HTTP,不是一个新协议 。
2222
2323## 获取消息
2424
2525要开始接收消息,我们只需要创建 ` new EventSource(url) ` 即可。
2626
27- 浏览器将会连接到 ` url ` 并保持连接开启等待事件到来 。
27+ 浏览器将会连接到 ` url ` 并保持连接打开,等待事件 。
2828
29- 服务器应该响应状态码为 200 并返回响应头 ` Content-Type: text/event-stream ` ,然后保持此连接并以一种特殊的格式写入消息,就像这样:
29+ 服务器响应状态码应该为 200,header 为 ` Content-Type: text/event-stream ` ,然后保持此连接并以一种特殊的格式写入消息,就像这样:
3030
3131```
3232data: Message 1
@@ -39,7 +39,7 @@ data: of two lines
3939
4040- ` data: ` 后为消息文本,冒号后面的空格是可选的。
4141- 消息以双换行符 ` \n\n ` 分隔。
42- - 要发送换行 ` \n ` ,我们可以在要换行的位置添加一个 ` data: ` (上面的第三条消息)。
42+ - 要发送一个换行 ` \n ` ,我们可以在要换行的位置立即再发送一个 ` data: ` (上面的第三条消息)。
4343
4444在实际开发中,复杂的消息通常是用 JSON 编码后发送。换行符在其中编码为 ` \n ` ,因此不需要多行 ` data: ` 消息。
4545
@@ -49,30 +49,30 @@ data: of two lines
4949data: {" user" : " John" ," message" : " First line*!*\n */!* Second line" }
5050```
5151
52- ……因此我们可以假设一个 ` data: ` 只包含一条消息 。
52+ ……因此,我们可以假设一个 ` data: ` 只保存了一条消息 。
5353
54- 对每个消息,生成 ` message ` 事件:
54+ 对于每个这样的消息,都会生成 ` message ` 事件:
5555
5656``` js
5757let eventSource = new EventSource (" /events/subscribe" );
5858
5959eventSource .onmessage = function (event ) {
6060 console .log (" New message" , event .data );
61- // 对于上面的数据,将会打印三次
61+ // 对于上面的数据流将打印三次
6262};
6363
64- // 或者 eventSource.addEventListener('message', ...)
64+ // 或 eventSource.addEventListener('message', ...)
6565```
6666
67- ### 跨域请求
67+ ### 跨源请求
6868
69- ` EventSource ` 支持跨域请求 ,就像 ` fetch ` 任何其他的网络方法 。我们可以使用任何 URL:
69+ ` EventSource ` 支持跨源请求 ,就像 ` fetch ` 任何其他网络方法 。我们可以使用任何 URL:
7070
7171``` js
7272let source = new EventSource (" https://another-site.com/events" );
7373```
7474
75- 远程服务器将会获取到 ` Origin ` 请求头 ,并且必须以 ` Access-Control-Allow-Origin ` 响应才能继续 。
75+ 远程服务器将会获取到 ` Origin ` header ,并且必须以 ` Access-Control-Allow-Origin ` 响应来处理 。
7676
7777要传递凭证(credentials),我们应该设置附加选项 ` withCredentials ` ,就像这样:
7878
@@ -82,18 +82,18 @@ let source = new EventSource("https://another-site.com/events", {
8282});
8383```
8484
85- 请参见 < info:fetch-crossorigin > 章节以了解更多关于跨域头的细节信息 。
85+ 更多关于跨源 header 的详细内容, 请参见 < info:fetch-crossorigin > 。
8686
8787
8888## 重新连接
8989
9090创建之后,` new EventSource ` 连接到服务器,如果连接断开 —— 则重新连接。
9191
92- 这很方便 ,我们不用去关心重新连接的事情。
92+ 这非常方便 ,我们不用去关心重新连接的事情。
9393
9494每次重新连接之间有一点小的延迟,默认为几秒钟。
9595
96- 服务器可以使用 ` retry: ` 设置需要的延迟响应时间 (以毫秒为单位)。
96+ 服务器可以使用 ` retry: ` 来设置需要的延迟响应时间 (以毫秒为单位)。
9797
9898``` js
9999retry: 15000
@@ -102,28 +102,28 @@ data: Hello, I set the reconnection delay to 15 seconds
102102
103103` retry: ` 既可以与某些数据一起出现,也可以作为独立的消息出现。
104104
105- 浏览器需要等待很长时间才能再次重新连接。或者更长 ,例如: 如果浏览器知道(从系统知道的 )此时没有网络连接,它可能会等到连接出现 ,然后重试。
105+ 在重新连接之前,浏览器需要等待那么多毫秒。甚至更长 ,例如, 如果浏览器知道(从操作系统 )此时没有网络连接,它会等到连接出现 ,然后重试。
106106
107- - 如果服务器想要浏览器停止重新连接,那么它应该返回 HTTP 代码 204。
108- - 如果浏览器想要关闭连接,它应该调用 ` eventSource.close() ` :
107+ - 如果服务器想要浏览器停止重新连接,那么它应该使用 HTTP 状态码 204 进行响应 。
108+ - 如果浏览器想要关闭连接,则应该调用 ` eventSource.close() ` :
109109
110110``` js
111111let eventSource = new EventSource (... );
112112
113113eventSource .close ();
114114```
115115
116- 另外 ,如果响应具有不正确的 ` Content-Type ` 或者其 HTTP 状态码不是 301,307,200 和 204,则不重新连接。发出 ` "error" ` 事件的连接,浏览器不会重新连接 。
116+ 并且 ,如果响应具有不正确的 ` Content-Type ` 或者其 HTTP 状态码不是 301,307,200 和 204,则不会进行重新连接。在这种情况下,将会发出 ` "error" ` 事件,并且浏览器不会重新连接 。
117117
118118``` smart
119- 当连接最终被关闭时,就无法再 “重新打开”它了。如果我们想再次连接 ,只需要创建一个新的 `EventSource`。
119+ 当连接最终被关闭时,就无法 “重新打开”它。如果我们想要再次连接 ,只需要创建一个新的 `EventSource`。
120120```
121121
122122## 消息 id
123123
124- 当一个连接由于网络问题而断开时 ,客户端和服务器都无法确定哪些消息已经收到哪些没有收到。
124+ 当一个连接由于网络问题而中断时 ,客户端和服务器都无法确定哪些消息已经收到哪些没有收到。
125125
126- 要正确的恢复连接 ,每条消息都应该有一个 ` id ` 字段,就像这样:
126+ 为了正确地恢复连接 ,每条消息都应该有一个 ` id ` 字段,就像这样:
127127
128128```
129129data: Message 1
@@ -137,36 +137,36 @@ data: of two lines
137137id: 3
138138```
139139
140- 当收到带有 ` id ` 的消息时,浏览器会:
140+ 当收到具有 ` id ` 的消息时,浏览器会:
141141
142142- 将属性 ` eventSource.lastEventId ` 设置为其值。
143- - 重新连接时,使用该 ` id ` 发送 ` Last-Event-ID ` 请求头 ,以便服务器可以重新发送后面的消息。
143+ - 重新连接后,发送带有 ` id ` 的 header ` Last-Event-ID ` ,以便服务器可以重新发送后面的消息。
144144
145- ```smart header="把 ` id: ` 放到 ` data: ` 后"
146- 请注意:` id ` 是被服务器附加到 ` data ` 消息后的,以确保在收到消息后更新 ` lastEventId ` 。
145+ ```smart header="把 ` id: ` 放在 ` data: ` 后"
146+ 请注意:` id ` 被服务器附加到 ` data ` 消息后,以确保在收到消息后 ` lastEventId ` 会被更新 。
147147```
148148
149149## 连接状态:readyState
150150
151- `EventSource` 对象有 `readyState` 属性,具有下列其中一个值 :
151+ `EventSource` 对象有 `readyState` 属性,该属性具有下列值之一 :
152152
153153```js no-beautify
154154EventSource.CONNECTING = 0; // 连接中或者重连中
155155EventSource.OPEN = 1; // 已连接
156- EventSource.CLOSED = 2; // 连接关闭
156+ EventSource.CLOSED = 2; // 连接已关闭
157157```
158158
159- 创建对象或者连接断开时 ,它始终是 ` EventSource.CONNECTING ` (等于 ` 0 ` )。
159+ 对象创建完成或者连接断开后 ,它始终是 ` EventSource.CONNECTING ` (等于 ` 0 ` )。
160160
161- 我们可以查询这个属性以了解 ` EventSource ` 的状态。
161+ 我们可以查询该属性以了解 ` EventSource ` 的状态。
162162
163163## Event 类型
164164
165165默认情况下 ` EventSource ` 对象生成三个事件:
166166
167167- ` message ` —— 收到消息,可以用 ` event.data ` 访问。
168- - ` open ` —— 打开连接 。
169- - ` error ` —— 无法建立连接,例如: 服务器返回 HTTP 500 状态码。
168+ - ` open ` —— 连接已打开 。
169+ - ` error ` —— 无法建立连接,例如, 服务器返回 HTTP 500 状态码。
170170
171171服务器可以在事件开始时使用 ` event: ... ` 指定另一种类型事件。
172172
@@ -198,46 +198,46 @@ eventSource.addEventListener('leave', event => {
198198});
199199```
200200
201- ## 完整例子
201+ ## 完整示例
202202
203203服务器依次发送 ` 1 ` ,` 2 ` ,` 3 ` ,最后发送 ` bye ` 并断开连接。
204204
205- 此时浏览器会自动重新连接 。
205+ 然后浏览器会自动重新连接 。
206206
207207[ codetabs src="eventsource"]
208208
209209## 总结
210210
211- ` EventSource ` 对象自动建立一个持久的连接并允许服务器通过这个连接发送消息 。
211+ ` EventSource ` 对象自动建立一个持久的连接,并允许服务器通过这个连接发送消息 。
212212
213- 它可以:
214- - 在可调的 ` retry ` 时间内可以自动重连 。
215- - 使用消息 id 恢复事件,最后收到的标识符在重新连接时以 ` Last-Event-ID ` 请求头发送出去 。
213+ 它提供了:
214+ - 在可调的 ` retry ` 超时内自动重新连接 。
215+ - 用于恢复事件的消息 id,重新连接后,最后接收到的标识符被在 ` Last-Event-ID ` header 中发送出去 。
216216- 当前状态位于 ` readyState ` 属性中。
217217
218- 这使得 ` EventSource ` 成为 ` WebSocket ` 的一个可行替代品 ,因为 ` WebSocket ` 更低级(low-level),且缺乏这样内置功能 (尽管它们可以被实现)。
218+ 这使得 ` EventSource ` 成为 ` WebSocket ` 的一个可行的替代方案 ,因为 ` WebSocket ` 更低级(low-level),且缺乏这样的内建功能 (尽管它们可以被实现)。
219219
220- 在实际应用中 ,` EventSource ` 功能就已经够用了 。
220+ 在很多实际应用中 ,` EventSource ` 的功能就已经够用了 。
221221
222- ` EventSource ` 支持所有现代浏览器 (除了 IE)。
222+ ` EventSource ` 在所有现代浏览器 (除了 IE)中都得到了支持 。
223223
224224语法:
225225
226226``` js
227227let source = new EventSource (url, [credentials]);
228228```
229229
230- 第二个参数只有一个可选项:` { withCredentials: true } ` ,它允许发送跨域凭证 。
230+ 第二个参数只有一个可选项:` { withCredentials: true } ` ,它允许发送跨源凭证 。
231231
232- 总体跨域安全性与 ` fetch ` 以及其他网络方法相同。
232+ 总体跨源安全性与 ` fetch ` 以及其他网络方法相同。
233233
234234### ` EventSource ` 对象的属性
235235
236236` readyState `
237237: 当前连接状态:为 ` EventSource.CONNECTING (=0) ` ,` EventSource.OPEN (=1) ` ,` EventSource.CLOSED (=2) ` 三者之一。
238238
239239` lastEventId `
240- : 最后接收的 ` id ` 。重新连接后,浏览器在 ` Last-Event-ID ` 请求头中发送此 id。
240+ : 最后接收到的 ` id ` 。重新连接后,浏览器在 header ` Last-Event-ID ` 中发送此 id。
241241
242242### ` EventSource ` 对象的方法
243243
@@ -247,25 +247,25 @@ let source = new EventSource(url, [credentials]);
247247### ` EventSource ` 对象的事件
248248
249249` message `
250- : 接收到了消息 ,消息数据在 ` event.data ` 中。
250+ : 接收到的消息 ,消息数据在 ` event.data ` 中。
251251
252252` open `
253253: 连接已建立。
254254
255255` error `
256- : 如果出现错误 ,包括连接丢失(将会自动重连)以及其他致命错误。我们可以检查 ` readyState ` 以查看是否正在尝试重新连接。
256+ : 如果发生错误 ,包括连接丢失(将会自动重连)以及其他致命错误。我们可以检查 ` readyState ` 以查看是否正在尝试重新连接。
257257
258- 服务器可能在 ` event: ` 中发送一个自定义事件名称。这类事件应该使用 ` addEventListener ` 来处理而不是 ` on<event> ` 。
258+ 服务器可以在 ` event: ` 中设置自定义事件名称。应该使用 ` addEventListener ` 来处理此类事件,而不是使用 ` on<event> ` 。
259259
260260### 服务器响应格式
261261
262262服务器发送由 ` \n\n ` 分隔的消息。
263263
264264一条消息可能有以下字段:
265265
266- - ` data: ` —— 消息体,一系列多个 ` data ` 被解析为单个消息,各个部分由 ` \n ` 分隔。
266+ - ` data: ` —— 消息体(body) ,一系列多个 ` data ` 被解释为单个消息,各个部分之间由 ` \n ` 分隔。
267267- ` id: ` —— 更新 ` lastEventId ` ,重连时以 ` Last-Event-ID ` 发送此 id。
268- - ` retry: ` —— 建议以 ms 为重新连接的延迟单位。没有办法以 JavaScript 设置它 。
268+ - ` retry: ` —— 建议重连的延迟,以 ms 为单位。无法通过 JavaScript 进行设置 。
269269- ` event: ` —— 事件名,必须在 ` data: ` 之前。
270270
271- 一条消息可能包含任何顺序的一个或多个字段 ,但是 ` id: ` 通常是最后一个 。
271+ 一条消息可以按任何顺序包含一个或多个字段 ,但是 ` id: ` 通常排在最后 。
0 commit comments