HTML — サーバから送信されるイベント

9.2. ~serverから送信される~event

【この訳に特有な表記規約】

◎表記記号

9.2.1. 序論

◎非規範的

~serverが~web~pageに向けて,~HTTP越しに, あるいは 専用の[ “server-push” ~protocol ]を利用して ~dataを~pushできるようにするため、 この仕様は `EventSource$I ~interfaceを導入する。 ◎ To enable servers to push data to web pages over HTTP or using dedicated server-push protocols, this specification introduces the EventSource interface.

この~APIの利用-法は、 `EventSource$I ~objを作成して,~event~listenerを登録するだけである。 ◎ Using this API consists of creating an EventSource object and registering an event listener.

var %source = new EventSource('updates.cgi');
%source.onmessage = function (%event) {
  alert(%event.data);
};

~server側の~script(この事例では `updates.cgi^l )は、 ~MIME型に `text/event-stream$mt を伴う~messageを,次の形で送信する: ◎ On the server-side, the script ("updates.cgi" in this case) sends messages in the following form, with the text/event-stream MIME type:

data: 第一~message

data: 第二~message
data: この~messageは 2 行lからなる

data: 第三~message

【 各~messageは、 空行(言い換えれば,連続する 2 個以上の改行( `end-of-line$P ))で終端する。 】【 この~pageの各~stream例は、 特に断らない限り,暗黙的に空行で終端されている。 】


作者は、 異なる~event型を利用することにより,各~eventを~~分類できる。 ここに 2 種の~event型 "`add^et", "`remove^et" が含まれた~streamがあるとする: ◎ Authors can separate events by using different event types. Here is a stream that has two event types, "add" and "remove":

event: add
data: 73857293

event: remove
data: 2153

event: add
data: 113411

そのような~streamを取扱う~scriptは、 次の様になろう ( %addHandler, %removeHandler は、 1 個の~event引数をとる関数とする): ◎ The script to handle such a stream would look like this (where addHandler and removeHandler are functions that take one argument, the event):

var %source = new EventSource('updates.cgi');
source.addEventListener('add', %addHandler, false);
source.addEventListener('remove', %removeHandler, false);

既定の~event型は "`message^et" である。 【すなわち、最初の例のように "`event:^c" 行lが省略された場合。】 ◎ The default event type is "message".

~event~streamは、 常に~UTF-8として復号される。 別の文字~符号化法を指定する仕方はない。 ◎ Event streams are always decoded as UTF-8. There is no way to specify another character encoding.


~event~stream要請は、 通常の~HTTP要請と同様に, ~HTTP[ `301$hst / `307$hst ]応答~codeにより~redirectされ得る(できる)。 接続が~closeされた場合、 ~clientは再接続することになる。 ~serverは、 ~HTTP `204$hst "No Content" 応答~codeを利用して, この再接続を停止するよう~clientに伝えれる。 ◎ Event stream requests can be redirected using HTTP 301 and 307 redirects as with normal HTTP requests. Clients will reconnect if the connection is closed; a client can be told to stop reconnecting using the HTTP 204 No Content response code.

この~APIを — `XMLHttpRequest$I や `iframe$e を利用してそれを模倣せずに — 利用すれば、 ~UAは — ~UAの実装者と~network運用者が高度に協調-可能な事例において — ~network資源をより良く利用できるようになる。 これには、 携帯機の~battery~~寿命を有意に節約できる便益もある — それについては、 § 無接続~push にて更に論じられる。 ◎ Using this API rather than emulating it using XMLHttpRequest or an iframe allows the user agent to make better use of network resources in cases where the user agent implementer and the network operator are able to coordinate in advance. Amongst other benefits, this can result in significant savings in battery life on portable devices. This is discussed further in the section below on connectionless push.

9.2.2. `EventSource^I ~interface

[Exposed=(Window,Worker)]
interface `EventSource@I : `EventTarget$I {
  `EventSource$mc(USVString %url, optional `EventSourceInit$I %eventSourceInitDict = {});

  readonly attribute USVString `url$m;
  readonly attribute boolean `withCredentials$m;

  // ready state
  const unsigned short `CONNECTING$m = 0;
  const unsigned short `OPEN$m = 1;
  const unsigned short `CLOSED$m = 2;
  readonly attribute unsigned short `readyState$m;

  // networking
  attribute `EventHandler$I `onopen$m;
  attribute `EventHandler$I `onmessage$m;
  attribute `EventHandler$I `onerror$m;
  undefined `close$m();
};

dictionary `EventSourceInit@I {
  boolean `~withCredentials0@m = false;
};

各 `EventSource$I ~objには、 次に挙げるものが結付けられる: ◎ Each EventSource object has the following associated with it:

`~URL@eS
`~URL~record$。 構築-時に設定される。 ◎ A url (a URL record). Set during construction.
`要請@eS
初期~時は ~NULL になるモノトスル。 ◎ A request. This must initially be null.
【 これもまた、 構築-時に ある`要請$に設定される。 】
`再接続~時間@eS
~milli秒数。 初期~時は`実装定義$な値 — おそらく,数秒を超えない~~範囲 — になるモノトスル。 ◎ A reconnection time, in milliseconds. This must initially be an implementation-defined value, probably in the region of a few seconds.
`最後の~event~ID文字列@eS
初期~時は空~文字列になるモノトスル。 ◎ A last event ID string. This must initially be the empty string.

`~URL$eSを除き、 現時点では,これらは `EventSource$I ~objに公開されていない。 ◎ Apart from url these are not currently exposed on the EventSource object.

%source = `new EventSource$m( %url [, { `~withCredentials0$m: true } ])
新たな `EventSource$I ~objを作成する。 ◎ Creates a new EventSource object.
%url は、 ~event~streamを供することになる資源の~URLを与える文字列。 ◎ url is a string giving the URL that will provide the event stream.
`~withCredentials0$m を ~T に設定すれば、 %url への接続~要請~用の`資格証~mode$rq は `include^l に設定されることになる。 ◎ Setting withCredentials to true will set the credentials mode for connection requests to url to "include".
%source.`close()$m
[ この `EventSource$I ~obj用に開始された`~fetch$~algoの~instance ]があれば,それらを中止した上で、 `readyState$m 属性を `CLOSED$m に設定する。 ◎ Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED.
%source.`url$m
`~event~streamを供している~URL$を返す。 ◎ Returns the URL providing the event stream.
%source.`withCredentials$m
`~event~streamを供している~URL$への接続~要請~用の`資格証~mode$rqに応じて[ `include^l ならば ~T / ~ELSE_ ~F ]を返す。 ◎ Returns true if the credentials mode for connection requests to the URL providing the event stream is set to "include", and false otherwise.
%source.`readyState$m
この `EventSource$I ~objの接続の状態を返す。 とり得る値は、 下に述べる。 ◎ Returns the state of this EventSource object's connection. It can have the values described below.

`new EventSource(url, eventSourceInitDict)@m 構築子~手続きは: ◎ The EventSource(url, eventSourceInitDict) constructor, when invoked, must run these steps:

  1. %設定群 ~LET コレに`関連な設定群~obj$ ◎ Let ev be a new EventSource object. ◎ Let settings be ev's relevant settings object.
  2. %~URL~record ~LET `~URLを符号化法の下で相対的に構文解析する$( %~URL, %設定群 ) ◎ Let urlRecord be the result of encoding-parsing a URL given url, relative to settings.
  3. ~IF[ %~URL~record ~EQ 失敗 ] ⇒ ~THROW `SyntaxError$E ◎ If urlRecord is failure, then throw a "SyntaxError" DOMException.
  4. コレの`~URL$eS ~SET %~URL~record ◎ Set ev's url to urlRecord.
  5. %~CORS属性~状態 ~LET `匿名$st ◎ Let corsAttributeState be Anonymous.
  6. ~IF[ %eventSourceInitDict[ "`~withCredentials0$m" ] ~EQ ~T ] ⇒# %~CORS属性~状態 ~SET `資格証を利用する$st; コレの `withCredentials$m 属性 ~SET ~T ◎ If the value of eventSourceInitDict's withCredentials member is true, then set corsAttributeState to Use Credentials and set ev's withCredentials attribute to true.
  7. %要請 ~LET `~CORSになり得る要請を作成する$( %~URL~record, 空~文字列, %~CORS属性~状態 ) ◎ Let request be the result of creating a potential-CORS request given urlRecord, the empty string, and corsAttributeState.
  8. %要請 の`~client$rq ~SET %設定群 ◎ Set request's client to settings.
  9. 任意選択で ⇒ %要請 の`~header~list$rq内で`~headerを設定する$( ( `Accept$h, ``^`text/event-stream$mt``^ ) ) ◎ User agents may set (`Accept`, `text/event-stream`) in request's header list.
  10. %要請 の ⇒# `~cache~mode$rq ~SET `no-store^l, `起動元~種別$rq ~SET `other^l ◎ Set request's cache mode to "no-store". ◎ Set request's initiator type to "other".
  11. コレの`要請$eS ~SET %要請 ◎ Set ev's request to request.
  12. %~event~source本体~終了~時の処理n ~LET 所与の ( `応答$ %応答 ) に対し,次を走らす手続き ⇒ ~IF[ %応答 は`~network~error$でない ] ⇒ `接続を確立し直す$ ◎ Let processEventSourceEndOfBody given response res be the following step: if res is not a network error, then reestablish the connection.
  13. %要請 を`~fetchする$ — 次を与える下で: ◎ Fetch request with\

    • `応答の本体~終了~時の処理n$i ~SET %~event~source本体~終了~時の処理n ◎ processResponseEndOfBody set to processEventSourceEndOfBody\
    • `応答の処理n$i ~SET 所与の ( `応答$ %応答 ) に対し,次を走らす手続き ◎ and processResponse set to the following steps given response res:

      1. ~IF[ %応答 は`中止~network~error$である ] ⇒ `接続を失敗させ$る ◎ If res is an aborted network error, then fail the connection.
      2. ~ELIF[ %応答 は`~network~error$である ] ⇒ `接続を確立し直す$ — ただし、 そうしても無益なことが判っている場合は,`接続を失敗させ$てもヨイ。 ◎ Otherwise, if res is a network error, then reestablish the connection, unless the user agent knows that to be futile, in which case the user agent may fail the connection.
      3. ~ELIF[ %応答 の`状態s$rs ~NEQ `200^hst ]~OR[ %応答 の`~Content-Type~metadata$ ~NEQ ``^`text/event-stream$mt``^ ] ⇒ `接続を失敗させ$る ◎ Otherwise, if res's status is not 200, or if res's `Content-Type` is not `text/event-stream`, then fail the connection.
      4. ~ELSE ⇒# `接続を公告する$; %応答 の`本体$rsを行lごとに解釈する ◎ Otherwise, announce the connection and interpret res's body line by line.
  14. ~RET %event ◎ Return ev.
`url@m 取得子~手続きは ⇒ ~RET `~URLを直列化する$( コレの`~URL$eS ) ◎ The url attribute's getter must return the serialization of this EventSource object's url.

`withCredentials@m 属性は:

  • 取得子~手続きは、 最後に初期化された値を返す。
  • コレの作成-時には、 ~F に初期化するモノトスル。
◎ The withCredentials attribute must return the value to which it was last initialized. When the object is created, it must be initialized to false.

`readyState@m 属性は、 当の接続の状態を表現する: ◎ The readyState attribute represents the state of the connection.\

  • 取得子~手続きは【この項は、この訳による補完】 ⇒ ~RET 最後に設定された値
  • 次のいずれかの値をとり得る: ◎ It can have the following values:

    `CONNECTING@m (数値 0 )
    接続は、 まだ確立されていないか,または ~closeされていて~UAは再接続している。 ◎ The connection has not yet been established, or it was closed and the user agent is reconnecting.
    `OPEN@m (数値 1 )
    ~UAは,~open接続を有していて、 ~eventが受信され次第 それを配送している。 ◎ The user agent has an open connection and is dispatching events as it receives them.
    `CLOSED@m (数値 2 )
    接続は~openしておらず,~UAは再接続しようと試行していない。 何らかの致命的~errorがあったか, `close()$m ~methodが呼出された。 ◎ The connection is not open, and the user agent is not trying to reconnect. Either there was a fatal error or the close() method was invoked.
  • コレの作成-時には、 `CONNECTING$m ( 0 )に設定するモノトスル。 値がいつ変化するかは、 下に与える,接続を取扱うための規則にて定義される。 ◎ When the object is created its readyState must be set to CONNECTING (0). The rules given below for handling the connection define when the value changes.
`close()@m ~method~手続きは ⇒ コレ用に開始された`~fetch$ ~algoがあれば すべて中止した上で、 コレの `readyState$m 属性を `CLOSED$m に設定する。 ◎ The close() method must abort any instances of the fetch algorithm started for this EventSource object, and must set the readyState attribute to CLOSED.

`EventSource$I ~interfaceを実装している~すべての~objは、[ 以下に挙げる各種`~event~handler$, および対応する各種`~event~handler~event型$ ]を`~event~handler~IDL属性$として~supportするモノトスル: ◎ The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by all objects implementing the EventSource interface:

`~event~handler$ `~event~handler~event型$
`onopen@m `open$et
`onmessage@m `message$et
`onerror@m `error$et

9.2.3. 処理~model

`接続を公告する@ ときは、 次を走らす`~taskを~queueする$モノトスル: ◎ When a user agent is to announce the connection, the user agent must queue a task which,\

  1. %O ~LET 当の `EventSource$I ~obj ◎ ↓
  2. ~IF[ %O の `readyState$m 属性~値 ~NEQ `CLOSED$m ]: ◎ if the readyState attribute is set to a value other than CLOSED,\

    1. %O の `readyState$m 属性 ~SET `OPEN$m ◎ sets the readyState attribute to OPEN and\
    2. `~eventを発火する$( %O, `open$et ) ◎ fires an event named open at the EventSource object.

`接続を確立し直す@ ときは、 次の手続きを`並列的$に走らす(したがって,この手続きを呼出した~taskの一部を成さない)モノトスル: ◎ When a user agent is to reestablish the connection, the user agent must run the following steps. These steps are run in parallel, not as part of a task. (The tasks that it queues, of course, are run like normal tasks and not themselves in parallel.)

  1. %O ~LET 当の `EventSource$I ~obj ◎ ↓
  2. %~task ~LET 次を走らす`~taskを~queueする$: ◎ Queue a task to run the following steps:

    1. ~IF[ %O の `readyState$m 属性 ~NEQ `CLOSED$m ] ⇒ ~RET ◎ If the readyState attribute is set to CLOSED, abort the task.
    2. %O の `readyState$m 属性 ~SET `CONNECTING$m ◎ Set the readyState attribute to CONNECTING.
    3. `~eventを発火する$( %O, `error$et ) ◎ Fire an event named error at the EventSource object.
  3. %O の`再接続~時間$eSだけ待機する ◎ Wait a delay equal to the reconnection time of the event source.
  4. 任意選択で ⇒ 更にいくばくか待機する。 特に,[ 前回の試みが失敗した場合、 ~serverはすでに過負荷dかもしれない ]ので、 ~UAは,[ ベキ乗打ち切り待機法( `exponential backoff^en )による遅延 ]を導入することもできる。 あるいは、[ ~OSから~network接続できないと報告された場合 ]には,[ ~OSから その~~回復が公告される ]まで待機する。 ◎ Optionally, wait some more. In particular, if the previous attempt failed, then user agents might introduce an exponential backoff delay to avoid overloading a potentially already overloaded server. Alternatively, if the operating system has reported that there is no network connectivity, user agents might wait for the operating system to announce that the network connection has returned before retrying.
  5. %~task が まだ走っていないならば、 走る【! 走り終える?】まで待機する ◎ Wait until the aforementioned task has run, if it has not yet run.
  6. 次を走らす`~taskを~queueする$: ◎ Queue a task to run the following steps:

    1. ~IF[ %O の `readyState$m 属性 ~NEQ `CONNECTING$m ] ⇒ ~RET ◎ If the EventSource object's readyState attribute is not set to CONNECTING, then return.
    2. %要請 ~LET %O の`要請$eS ◎ Let request be the EventSource object's request.
    3. %最後の~ID ~LET %O の`最後の~event~ID文字列$eS ◎ ↓
    4. ~IF[ %最後の~ID ~NEQ 空~文字列 ] ⇒ %要請 の`~header~list$rq内で`~headerを設定する$( ( `Last-Event-ID$h, `~UTF-8符号化する$( %最後の~ID ) ) ) ◎ If the EventSource object's last event ID string is not the empty string, then: • Let lastEventIDValue be the EventSource object's last event ID string, encoded as UTF-8. • Set (`Last-Event-ID`, lastEventIDValue) in request's header list.
    5. %要請 を`~fetchする$ ⇒ この~fetchに対し得された応答は、 この節の最初あたり†に述べたとおりに処理する

      【† 該当する箇所は、 更新により除去され, `new EventSource()$m 構築子~手続き~内の “~fetchする” 箇所に組入れられた。 】

      ◎ Fetch request and process the response obtained in this fashion, if any, as described earlier in this section.

`接続を失敗させ@ るときは、 次を走らす`~taskを~queueする$モノトスル: ◎ When a user agent is to fail the connection, the user agent must queue a task which,\

  1. %O ~LET 当の `EventSource$I ~obj ◎ \
  2. ~IF[ %O の `readyState$m 属性 ~NEQ `CLOSED$m ]: ◎ if the readyState attribute is set to a value other than CLOSED,\

    1. %O の `readyState$m 属性 ~SET `CLOSED$m ◎ sets the readyState attribute to CLOSED and\
    2. `~eventを発火する$( %O, `error$et ) ◎ fires an event named error at the EventSource object.\

~UAは、 `接続を失敗させ$たときは,再接続しようと`試みないこと^em。 ◎ Once the user agent has failed the connection, it does not attempt to reconnect.


`EventSource$I ~objにより`~queueされ$るどの`~task$に対しても,その`~task~source$は `~remote~event~task~source@ とする。 ◎ The task source for any tasks that are queued by EventSource objects is the remote event task source.

9.2.4. `Last-Event-ID^h ~header

`Last-Event-ID@h ~HTTP要請~headerは、 ~UAが`接続を確立し直す$ときに, `EventSource$I ~objの`最後の~event~ID文字列$eSを~serverへ報告する。 ◎ The Last-Event-ID` HTTP request header reports an EventSource object's last event ID string to the server when the user agent is to reestablish the connection.

値~空間を もっと良く定義することについては、 課題 #7363 を見よ。 それは、 本質的には,~UTF-8に符号化された文字列であって[ `0000^U `NULL^cn, `000A^U `LF^cn, `000D^U `CR^cn ]を包含しないものである。 ◎ See whatwg/html issue #7363 to define the value space better. It is essentially any UTF-8 encoded string, that does not contain U+0000 NULL, U+000A LF, or U+000D CR.

9.2.5. ~event~streamの構文解析

この~event~stream形式の`~MIME型$は、 `text/event-stream$mt である。 ◎ This event stream format's MIME type is text/event-stream.

~event~stream形式は、 次の `ABNF$r における `stream$P 生成規則で与えられる — この~ABNFの文字~集合は~Unicodeとする: ◎ The event stream format is as described by the stream production of the following ABNF, the character set for which is Unicode. [ABNF]

`stream@P
	= [ `bom$P ] *`event$P
`event@P
	= *( `comment$P / `field$P ) `end-of-line$P
`comment@P
	= `colon$P *`any-char$P `end-of-line$P
`field@P
	= 1*`name-char$P [ `colon$P [ `space$P ] *`any-char$P ] `end-of-line$P
`end-of-line@P
	= ( `cr$P `lf$P / `cr$P / `lf$P )

; 各種~文字
`lf@P
	= `000A^0x ; U+000A LINE FEED (LF)
`cr@P
	= `000D^0x ; U+000D CARRIAGE RETURN (CR)
`space@P
	= `0020^0x ; U+0020 SPACE
`colon@P
	= `003A^0x ; U+003A COLON (:)
`bom@P
	= `FEFF^0x ; U+FEFF BYTE ORDER MARK
`name-char@P
	= `0000-0009^0x / `000B-000C^0x / `000E-0039^0x / `003B-10FFFF^0x
	; 
`lf$P, `cr$P, `colon$P 以外の`~scalar値$
◎
; a scalar value other than U+000A LINE FEED (LF), U+000D CARRIAGE RETURN (CR), or U+003A COLON (:)

`any-char@P
	= `0000-0009^0x / `000B-000C^0x / `000E-10FFFF^0x
	; 
`lf$P, `cr$P 以外の`~scalar値$
◎
; a scalar value other than U+000A LINE FEED (LF) or U+000D CARRIAGE RETURN (CR)

この形式による~event~streamは、 常に ~UTF-8に符号化されなければナラナイ。 `ENCODING$r ◎ Event streams in this format must always be encoded as UTF-8. [ENCODING]

各 行lどうしは、 `end-of-line$P ([ `cr$P +`lf$P, `lf$P, `cr$P ]のいずれか) で分離されなければナラナイ。 ◎ Lines must be separated by either a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair, a single U+000A LINE FEED (LF) character, or a single U+000D CARRIAGE RETURN (CR) character.

そのような資源~用に確立された~remote~serverへの接続は,長く生き残ることが予期されるので、 ~UAは,適切な~buffer法が利用されることを確保するべきである。 特に,[ 各 行lが 1 個の `lf$P で終端するように定義される~buffer法 ]は安全である一方で、[ ~block~buffer法や, 異なる行l終端-法を期待する行l~buffer法 ]は,~event配送-を遅延させ得る。 ◎ Since connections established to remote servers for such resources are expected to be long-lived, UAs should ensure that appropriate buffering is used. In particular, while line buffering with lines are defined to end with a single U+000A LINE FEED (LF) character is safe, block buffering or line buffering with different expected line endings can cause delays in event dispatch.

9.2.6. ~event~streamの解釈-法

~streamは、 `~UTF-8復号する$~algoで復号するモノトスル。 ◎ Streams must be decoded using the UTF-8 decode algorithm.

注記: `~UTF-8復号する$~algoは、 先頭に~UTF-8 Byte Order Mark ( `bom$P )があれば それを剥ぎ取る。 ◎ The UTF-8 decode algorithm strips one leading UTF-8 Byte Order Mark (BOM), if any.

~streamは、 行lごとに そこに現れるすべてを読取ることにより,構文解析するモノトスル。 行lが終端するのは、 次のいずれか( “改行” )が現れる所に限られるとする:

  • `cr$P + `lf$P 文字~pair
  • `cr$P が先行しない 1 個の `lf$P
  • `lf$P が後続しない 1 個の `cr$P
【改行~自身は行lには含まれない。】 ◎ The stream must then be parsed by reading everything line by line, with a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair, a single U+000A LINE FEED (LF) character not preceded by a U+000D CARRIAGE RETURN (CR) character, and a single U+000D CARRIAGE RETURN (CR) character not followed by a U+000A LINE FEED (LF) character being the ways in which a line can end.

~streamを構文解析する~algoの各~instanceには,[ %~data~buffer, %~event型~buffer, %最後の~event~ID~buffer ]が結付けられる — いずれも,空~文字列に初期化するモノトスル。 ◎ When a stream is parsed, a data buffer, an event type buffer, and a last event ID buffer must be associated with it. They must be initialized to the empty string.

それは、 ~EACH ( 行l %行l ) に対し, 受信された順序で次を走らす: ◎ Lines must be processed, in the order they are received, as follows:

  1. ~IF[ %行l は空である(空行) ] ⇒ 下に定義されるように`~message~eventを配送する$ ◎ If the line is empty (a blank line) ◎ • Dispatch the event, as defined below.
  2. ~ELIF[ %行l の先頭の文字 ~EQ `colon$P ] ⇒ ~CONTINUE ◎ If the line starts with a U+003A COLON character (:) ◎ • Ignore the line.
  3. ~IF[ %行l は `colon$P を包含する ]: ◎ If the line contains a U+003A COLON character (:)

    1. ( %名, %値 ) ~LET %行l 内の最初の `colon$P より ( 前の部分の文字列, 後の部分の文字列 ) ◎ Collect the characters on the line before the first U+003A COLON character (:), and let field be that string. ◎ Collect the characters on the line after the first U+003A COLON character (:), and let value be that string. If value starts with a U+0020 SPACE character, remove it from value.
    2. ~IF[ %値 の先頭の文字 ~EQ `space$P ] ⇒ %値 から先頭の文字を除去する ◎ ↑
    3. `~fieldを処理する$( %名, %値 ) ◎ Process the field using the steps described below, using field as the field name and value as the field value.
  4. ~ELSE(文字列は空でないが `colon$P を包含しない) ⇒ `~fieldを処理する$( %行l, 空~文字列 ) ◎ Otherwise, the string is not empty but does not contain a U+003A COLON character (:) ◎ Process the field using the steps described below, using the whole line as the field name, and the empty string as the field value.

~streamの終端-に達したときの最後の~blockが,空行で終端されていない場合、 その~blockの~dataは破棄するモノトスル。 (そのような~blockに対しては、~eventは配送されない。) (~blockとは、空行で互いに分離されていない,一連の行lを意味する。) ◎ Once the end of the file is reached, any pending data must be discarded. (If the file ends in the middle of an event, before the final empty line, the incomplete event is not dispatched.)


`~fieldを処理する@ ときは、 所与の ( %名, %値 ) に対し, %名 に応じて: ◎ The steps to process the field given a field name and a field value depend on the field name, as given in the following list. Field names must be compared literally, with no case folding performed.

`event^l ◎ If the field name is "event"
%~event型~buffer ~SET %値 ◎ Set the event type buffer to field value.
`data^l ◎ If the field name is "data"
%~data~buffer に[ %値, 1 個の `lf$P ]を順に付加する ◎ Append the field value to the data buffer, then append a single U+000A LINE FEED (LF) character to the data buffer.
`id^l ◎ If the field name is "id"

~IF[ %値 は `0000^U `NULL^cn を包含しない ] ⇒ %最後の~event~ID~buffer ~SET %値

(他の場合、この~fieldは無視する。)

◎ If the field value does not contain U+0000 NULL, then set the last event ID buffer to the field value. Otherwise, ignore the field.
`retry^l ◎ If the field name is "retry"

~IF[ %値 は`~ASCII数字$のみからなる ] ⇒ ~event~streamの`再接続~時間$eS ~SET %値 を基数 10 の整数に解釈した結果

(他の場合、この~fieldは無視する。)

◎ If the field value consists of only ASCII digits, then interpret the field value as an integer in base ten, and set the event stream's reconnection time to that integer. Otherwise, ignore the field.
他の場合 ◎ Otherwise
何もしない(この~fieldは無視する。) ◎ The field is ignored.
【この例は、訳者による補足。】

したがって、 次の例の様に,同じ~block内に複数の `event^l 行lが含まれている場合、 最後に現れたものが他を上書きすることになる( `id^l についても同様になる):

event: add
event: remove
data: 1234

対照的に, `data^l 行lは、 行lごとに~data + `lf$P を付加する。 ただし、 ~block内の最後の `lf$P は除かれる (下に述べる~eventを配送する手続きの中で除去される)。

~UAは、 `~message~eventを配送する@ 【!~eventを配送する】 よう要求されたときは、 ( %~data~buffer, %~event型~buffer, %最後の~event~ID~buffer ) を~UAに適切な手続きを利用して処理するモノトスル。 ◎ When the user agent is required to dispatch the event, the user agent must process the data buffer, the event type buffer, and the last event ID buffer using steps appropriate for the user agent.

~web~browser用には、 `~message~eventを配送する$ための適切な手続きは,次に従うとする: ◎ For web browsers, the appropriate steps to dispatch the event are as follows:

  1. %O ~LET 当の `EventSource$I ~obj ◎ ↓
  2. %O の`最後の~event~ID文字列$eS ~SET %最後の~event~ID~buffer ◎ Set the last event ID string of the event source to the value of the last event ID buffer.\

    この~bufferは, 【他の~bufferと違って ~eventが生じるごとに】 設定し直されないので、 %O の`最後の~event~ID文字列$eSは, この~bufferが次回に~serverにより設定されるまで残り続ける。 ◎ The buffer does not get reset, so the last event ID string of the event source remains set to this value until the next time it is set by the server.

  3. ~IF[ %~data~buffer ~EQ 空~文字列 ] ⇒# ( %~data~buffer, %~event型~buffer ) ~SET ( 空~文字列, 空~文字列 ); ~RET ◎ If the data buffer is an empty string, set the data buffer and the event type buffer to the empty string and return.
  4. ~IF[ %~data~buffer の最後の文字 ~EQ `lf$P ] ⇒ %~data~buffer から最後の文字を除去する ◎ If the data buffer's last character is a U+000A LINE FEED (LF) character, then remove the last character from the data buffer.
  5. %~event ~LET `~eventを作成する$( `MessageEvent$I ~interface, %O に`関連な~realm$ ) ◎ Let event be the result of creating an event using MessageEvent, in the relevant realm of the EventSource object.
  6. %~event の各種~属性を次のように初期化する ⇒# `type$m ~SET "`message$et", `data$m ~SET %~data, `origin$m ~SET `生成元を直列化する$( 当の~event~streamの最終的な~URL(すなわち,~redirect後の~URL)の`生成元$url ), `lastEventId$m ~SET %O の`最後の~event~ID文字列$eS ◎ Initialize event's type attribute to "message", its data attribute to data, its origin attribute to the serialization of the origin of the event stream's final URL (i.e., the URL after redirects), and its lastEventId attribute to the last event ID string of the event source.
  7. ~IF[ %~event型~buffer ~NEQ 空~文字列 ] ⇒ %~event の `type$m ~SET %~event型~buffer ◎ If the event type buffer has a value other than the empty string, change the type of the newly created event to equal the value of the event type buffer.
  8. ( %~data~buffer, %~event型~buffer ) ~SET ( 空~文字列, 空~文字列 ) ◎ Set the data buffer and the event type buffer to the empty string.
  9. 次を走らす`~taskを~queueする$:

    1. ~IF[ %O の `readyState$m 属性~値 ~NEQ `CLOSED$m ] ⇒ `~eventを配送する$( %O, %~event )
    ◎ Queue a task which, if the readyState attribute is set to a value other than CLOSED, dispatches the newly created event at the EventSource object.

注記: ~event( `event$P )に `id^l ~fieldが伴われていない場合、[ その~eventから生じる `MessageEvent$I ~event の `lastEventId$m ~field ]は,最後に~~見出された `id^l ~fieldの値 — すなわち,その前の~eventにより設定された`最後の~event~ID文字列$eS 【 `id^l がまだ見出されていなければ,空~文字列( %最後の~event~ID~buffer の初期~値)】 — に設定されることになる。 ◎ If an event doesn't have an "id" field, but an earlier event did set the event source's last event ID string, then the event's lastEventId field will be set to the value of whatever the last seen "id" field was.

他の~UA用には、 `~message~eventを配送する$ための適切な手続きは,実装に依存するが、 最小限,手続きを終える前に[ %~data~buffer, %~event型~buffer ]を空~文字列に設定するモノトスル。 ◎ For other user agents, the appropriate steps to dispatch the event are implementation dependent, but at a minimum they must set the data and event type buffers to the empty string before returning.

次の~event~stream(空行で終端されている)に対しては: ◎ The following event stream, once followed by a blank line:

data: YHOO
data: +2
data: 10

`EventSource$I ~objに向けて, `MessageEvent$I ~interfaceを利用する `message$et ~eventを配送させることになる。 ~eventの `data$m 属性は、 文字列 `YHOO\n+2\n10^l を包含することになる ( `\n^l は改行文字( `lf$P )を表現する)。 ◎ ...would cause an event message with the interface MessageEvent to be dispatched on the EventSource object. The event's data attribute would contain the string "YHOO\n+2\n10" (where "\n" represents a newline).

これは、次のように利用できる: ◎ This could be used as follows:

var %stocks = new EventSource("https://stocks.example.com/ticker.php");
stocks.onmessage = function (%event) {
  var %data = %event.data.split('\n');
  updateStocks(%data[0], %data[1], %data[2]);
};

( `updateStocks()^c は、~data処理用の何らかの関数。) ◎ ...where updateStocks() is a function defined as: ◎ function updateStocks(symbol, delta, value) { ... } ◎ ...or some such.

次の~streamは、 4 個の~blockを包含する。 1 個目の~blockは、 ~commentなので,~eventは発火されない。 2 個目の~blockに対しては、 ~eventが発火されることになる — そこには、 名前 `data^l の~field(値に `first event^l を伴う)に加え, 名前 `id^l の~fieldもあり、 `最後の~event~ID文字列$eS を `1^l に設定することになる。 この~blockと次の~blockの合間で接続が切れた場合、 再接続-時に,~serverに向けて値 `1^bl を伴う `Last-Event-ID$h ~headerが送信されることになる。 3 個目の~blockも~eventを発火し, `data^l の値に `second event^l を伴うが、 `id^l ~fieldには値は伴われていない — それは、 `最後の~event~ID文字列$eSを空~文字列に設定し直す (今度は、 再接続が試みられる場合には, `Last-Event-ID$h ~headerは送信されないことを意味する)。 4 個目(最後)の~blockは、 単に~dataに ` third event^l (先頭の文字は `space$P )を伴わせた~eventを発火する。 最後の~blockであっても,空行で終端させる必要があることに注意 — ~streamが終端するだけでは、 最後の~blockに対する~event配送を誘発するには十分でない。 ◎ The following stream contains four blocks. The first block has just a comment, and will fire nothing. The second block has two fields with names "data" and "id" respectively; an event will be fired for this block, with the data "first event", and will then set the last event ID to "1" so that if the connection died between this block and the next, the server would be sent a `Last-Event-ID` header with the value `1`. The third block fires an event with data "second event", and also has an "id" field, this time with no value, which resets the last event ID to the empty string (meaning no `Last-Event-ID` header will now be sent in the event of a reconnection being attempted). Finally, the last block just fires an event with the data " third event" (with a single leading space character). Note that the last still has to end with a blank line, the end of the stream is not enough to trigger the dispatch of the last event.

: test stream

data: first event
id: 1

data:second event
id

data:  third event

次の~streamは、 最後の~blockは空行で終端されていないならば, 2 個の~eventを発火する: ◎ The following stream fires two events:

data

data
data

data:

1 個目の~blockは、 ~data が空~文字列にされた~eventを発火する。 2 個目の~blockは、 ~dataを 1 個の改行文字に設定した上で,~eventを発火する。 3 個目の~blockは、 空行が後続していないので,破棄される。 ◎ The first block fires events with the data set to the empty string, as would the last block if it was followed by a blank line. The middle block fires an event with the data set to a single newline character. The last block is discarded because it is not followed by a blank line.

次の~streamは、 2 個の~~等価な~eventを発火する: ◎ The following stream fires two identical events:

data:test

data: test

`colon$P の直後にある 1 個の `space$P は、 無視されるので。 ◎ This is because the space after the colon is ignored if present.

9.2.7. 著作~上の注記

旧来の~proxy~serverは、 ある種の事例では,短い制限時間~後に~HTTP接続を落とすことが知られている。 作者は、 およそ毎 15 秒ごとに,~comment行l(`colon$P から開始される行l)を含ませることにより, そのような~proxy~serverに抗して保護できる。 ◎ Legacy proxy servers are known to, in certain cases, drop HTTP connections after a short timeout. To protect against such proxy servers, authors can include a comment line (one starting with a ':' character) every 15 seconds or so.

~event~source接続を[ 互いに, あるいは以前に~serveされた特定の文書 ]に関係させたいと望む作者は、 ~IP~addressに依拠するのでは,うまく働かないことを見出すであろう — 同じ~clientが(複数の~proxy~serverを通すことに因り)複数の~IP~addressから接続することもあれば、 複数の~clientが(~proxy~serverを共有していることに因り)同じ~IP~addressから接続することもあるので。 文書を~serveするときに, その文書~内に一意な識別子を含ませておいて、 接続の確立-時に その識別子を~URLの一部として渡す方が良い。 ◎ Authors wishing to relate event source connections to each other or to specific documents previously served might find that relying on IP addresses doesn't work, as individual clients can have multiple IP addresses (due to having multiple proxy servers) and individual IP addresses can have multiple clients (due to sharing a proxy server). It is better to include a unique identifier in the document when it is served and then pass that identifier as part of the URL when the connection is established.

作者は,また、 ~HTTP~chunk法 【~HTTP11の ~chunk化~転送~符号法】 は,この~protocolの信頼性に期待されない負な効果を及ぼし得ることにも警戒すること — 特に、 ~chunk法が~timing要件に関知しない層で行われている場合には。 これが問題になる場合、 ~event~streamを~serveするときは,~chunk法を不能化できる。 ◎ Authors are also cautioned that HTTP chunking can have unexpected negative effects on the reliability of this protocol, in particular if the chunking is done by a different layer unaware of the timing requirements. If this is a problem, chunking can be disabled for serving event streams.

~HTTPによる~serverごとの接続~数~制限 【~HTTP11の § 同時並行性】 を~supportする~clientは、 ある~siteから複数の~pageを~openしたとき,[ その各~pageに同じ~domainへの `EventSource$I がある場合 ]に困らされることもある。 作者がこれを避ける方法には、 次が挙げられる:

  • より複階的な仕組みを利用する
  • 接続ごとに一意な~domain名を利用する
  • 利用者が~pageごとに `EventSource$I の機能性を[ 可能化する/不能化する ]ことを許容する
  • 単独の `EventSource$I ~objを`共用~worker内$で共有する
◎ Clients that support HTTP's per-server connection limitation might run into trouble when opening multiple pages from a site if each page has an EventSource to the same domain. Authors can avoid this using the relatively complex mechanism of using unique domain names per connection, or by allowing the user to enable or disable the EventSource functionality on a per-page basis, or by sharing a single EventSource object using a shared worker.

9.2.8. 無接続~pushと他の特能

制御~下にある環境で走っている~UA — 例:特定の~carrierに束ねられている携帯機の~browser — は、 接続の管理を~network上の~proxyに負荷委譲してもヨイ。 適合性の目的においては、 そのような状況における~UAは, その携帯機~softwareと~network~proxyの両者を含むものと見なされる。 ◎ User agents running in controlled environments, e.g. browsers on mobile handsets tied to specific carriers, may offload the management of the connection to a proxy on the network. In such a situation, the user agent for the purposes of conformance is considered to include both the handset software and the network proxy.

例えば,携帯機の~browserは、 接続を確立した後に[ その接続は 【~proxyが】~supportしている~networkである ]ことを検出して,[ その~network上の~proxy~serverに,接続の管理を司るよう要請する ]かもしれない。 そのような状況においては、 次のような経過を~~辿ることになる: ◎ For example, a browser on a mobile device, after having established a connection, might detect that it is on a supporting network and request that a proxy server on the network take over the management of the connection. The timeline for such a situation might be as follows:

  1. ~browserは、 作者が `new EventSource()$m 構築子にて指定した資源を, ~remote~HTTP~serverへ接続して要請する。 ◎ Browser connects to a remote HTTP server and requests the resource specified by the author in the EventSource constructor.
  2. ~serverは、 各~messageを不定期に送信する。 ◎ The server sends occasional messages.
  3. ~browserは、 ある 2 つの~messageの合間に[ ~TCP接続を~~維持し続けるための~network活動を除き,自身は遊休~中にある ]ことを検出したので,[ 電力を節約するため,~sleep~modeへ切替える ]ものと裁定した。 ◎ In between two messages, the browser detects that it is idle except for the network activity involved in keeping the TCP connection alive, and decides to switch to sleep mode to save power.
  4. ~browserは、 ~serverから切断される。 ◎ The browser disconnects from the server.
  5. ~browserは、 当の接続を保守する代わりに上述した~network上の~serviceに接触して, “~push~proxy” ~serviceを要請する。 ◎ The browser contacts a service on the network, and requests that the service, a "push proxy", maintain the connection instead.
  6. “~push~proxy” ~serviceは、 ~remote~HTTP~serverに接触して, 作者が `new EventSource()$m 構築子にて指定した資源を要請する (場合によっては、 `Last-Event-ID$h ~HTTP~header, 等々が含まれる)。 ◎ The "push proxy" service contacts the remote HTTP server and requests the resource specified by the author in the EventSource constructor (possibly including a `Last-Event-ID` HTTP header, etc.).
  7. ~browserは、 携帯機に~sleepすることを許容する。 ◎ The browser allows the mobile device to go to sleep.
  8. ~serverは、 別の~messageを送信する。 ◎ The server sends another message.
  9. “~push~proxy” ~serviceは、 ~eventを携帯機に伝達するため,~OMA~pushなどの技術を利用する — それは、 ~eventを処理するに足るだけ携帯機を目覚めさせてから,~sleepに戻す。 【OMA は、おそらく `Open Mobile Alliance^en(携帯電話の規格を策定する組織)の略語。】 ◎ The "push proxy" service uses a technology such as OMA push to convey the event to the mobile device, which wakes only enough to process the event and then returns to sleep.

これは、 総~data使用量を抑制するので,電力をかなり節約する。 ◎ This can reduce the total data usage, and can therefore result in considerable power savings.

[ 既存の~API, および `text/event-stream$mt 伝送路~形式 ]を[ この仕様により定義されるとおりに, および 上に述べたように より分散的な仕方 ]で実装することに加え、 `適用-可能な仕様$により定義される[ ~event~frame法の形式 ]も~supportしてヨイ。 この仕様は、 それがどう構文解析され, 処理されるかは,定義しない。 ◎ As well as implementing the existing API and text/event-stream wire format as defined by this specification and in more distributed ways as described above, formats of event framing defined by other applicable specifications may be supported. This specification does not define how they are to be parsed or processed.

9.2.9. ~garbage収集

[ `Window$I / `WorkerGlobalScope$I ]~obj %G 内の構築子を呼出して作成された `EventSource$I ~obj %O に対しては、 ~OR↓ が満たされている間は, %G から %O への強い参照-があるモノトスル: ◎ ↓

  • [ %O の `readyState$m ~EQ `CONNECTING$m ]~AND[ %O には[ `open$et / `message$et /`error$et ]~event用の~event~listenerが 1 個~以上~登録されている ] ◎ While an EventSource object's readyState is CONNECTING, and the object has one or more event listeners registered for open, message or error events, there must be a strong reference from the Window or WorkerGlobalScope object that the EventSource object's constructor was invoked from to the EventSource object itself.
  • [ %O の `readyState$m ~EQ `OPEN$m ]~AND[ %O には[ `message$et / `error$et ]~event用の~event~listenerが 1 個~以上~登録されている ] ◎ While an EventSource object's readyState is OPEN, and the object has one or more event listeners registered for message or error events, there must be a strong reference from the Window or WorkerGlobalScope object that the EventSource object's constructor was invoked from to the EventSource object itself.
  • %O により`~remote~event~task~source$から~queueされた~taskがある ◎ While there is a task queued by an EventSource object on the remote event task source, there must be a strong reference from the Window or WorkerGlobalScope object that the EventSource object's constructor was invoked from to that EventSource object.

`EventSource$I ~obj %O を `強制的に~closeする@ ときは (これは `Document$I ~objが永続的に消去ったときに起こる), 次を走らすモノトスル:

  1. %O 用に開始された すべての`~fetch$~algoを中止する
  2. %O の `readyState$m 属性 ~SET `CLOSED$m
◎ If a user agent is to forcibly close an EventSource object (this happens when a Document object goes away permanently), the user agent must abort any instances of the fetch algorithm started for this EventSource object, and must set the readyState attribute to CLOSED.

`EventSource$I ~obj %O が,接続が依然として~openしている間に~garbage収集された場合、 ~UAは, %O 用に開始された すべての`~fetch$~algoを中止するモノトスル。 ◎ If an EventSource object is garbage collected while its connection is still open, the user agent must abort any instance of the fetch algorithm opened by this EventSource.

9.2.10. 実装~向けの助言

◎非規範的

この~APIを利用している作者による~codeの~debugを援助するため、 ~UAには,[[ `EventSource$I ~obj, および それに関係する~network接続 ]についての詳細な診断~情報 ]を開発~console内に供することが強く督促される。 ◎ User agents are strongly urged to provide detailed diagnostic information about EventSource objects and their related network connections in their development consoles, to aid authors in debugging code using this API.

例えば~UAは、 ~pageが作成した各 `EventSource$I ~obj用に, 次に挙げるもの等々を表示する~panelを備えることもできる: ◎ For example, a user agent could have a panel displaying all the EventSource objects a page has created, each listing\

  • 構築子の引数 ◎ the constructor's arguments,\
  • ~network~errorが生じたかどうか ◎ whether there was a network error,\
  • 接続の~CORS状態s — および,その状態sに至らせたのは (~clientが送信した/~serverから受信した)どの~headerたちか ◎ what the CORS status of the connection is and what headers were sent by the client and received from the server to lead to that status,\
  • 受信した~message — および,それは どう構文解析されたか ◎ the messages that were received and how they were parsed, and so forth.

とりわけ, `error$et ~eventが発火されたときには、 実装には[ 詳細な情報を自身の開発~consoleに報告する ]ことが奨励される — ~event自体から可用になる情報は少ししかないので。 ◎ Implementations are especially encouraged to report detailed information to their development consoles whenever an error event is fired, since little to no information can be made available in the events themselves.