服务器实现

数据格式

服务器向浏览器发送的 SSE 数据,必须是 UTF-8 编码的文本,具有如下的 HTTP 头信息。

  1. Content-Type: text/event-stream
  2. Cache-Control: no-cache
  3. Connection: keep-alive

上面三行之中,第一行的Content-Type必须指定 MIME 类型为event-steam

每一次发送的信息,由若干个message组成,每个message之间用\n\n分隔。每个message内部由若干行组成,每一行都是如下格式。

  1. [field]: value\n

上面的field可以取四个值。

  • data
  • event
  • id
  • retry

此外,还可以有冒号开头的行,表示注释。通常,服务器每隔一段时间就会向浏览器发送一个注释,保持连接不中断。

  1. : This is a comment

下面是一个例子。

  1. : this is a test stream\n\n
  2. data: some text\n\n
  3. data: another message\n
  4. data: with two lines \n\n

data 字段

数据内容用data字段表示。

  1. data: message\n\n

如果数据很长,可以分成多行,最后一行用\n\n结尾,前面行都用\n结尾。

  1. data: begin message\n
  2. data: continue message\n\n

下面是一个发送 JSON 数据的例子。

  1. data: {\n
  2. data: "foo": "bar",\n
  3. data: "baz", 555\n
  4. data: }\n\n

id 字段

数据标识符用id字段表示,相当于每一条数据的编号。

  1. id: msg1\n
  2. data: message\n\n

浏览器用lastEventId属性读取这个值。一旦连接断线,浏览器会发送一个 HTTP 头,里面包含一个特殊的Last-Event-ID头信息,将这个值发送回来,用来帮助服务器端重建连接。因此,这个头信息可以被视为一种同步机制。

event 字段

event字段表示自定义的事件类型,默认是message事件。浏览器可以用addEventListener()监听该事件。

  1. event: foo\n
  2. data: a foo event\n\n
  3. data: an unnamed event\n\n
  4. event: bar\n
  5. data: a bar event\n\n

上面的代码创造了三条信息。第一条的名字是foo,触发浏览器的foo事件;第二条未取名,表示默认类型,触发浏览器的message事件;第三条是bar,触发浏览器的bar事件。

下面是另一个例子。

  1. event: userconnect
  2. data: {"username": "bobby", "time": "02:33:48"}
  3. event: usermessage
  4. data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}
  5. event: userdisconnect
  6. data: {"username": "bobby", "time": "02:34:23"}
  7. event: usermessage
  8. data: {"username": "sean", "time": "02:34:36", "text": "Bye, bobby."}

retry 字段

服务器可以用retry字段,指定浏览器重新发起连接的时间间隔。

  1. retry: 10000\n

两种情况会导致浏览器重新发起连接:一种是时间间隔到期,二是由于网络错误等原因,导致连接出错。