{"id":1270,"date":"2023-02-22T19:08:31","date_gmt":"2023-02-22T11:08:31","guid":{"rendered":"https:\/\/fdream.net\/blog\/?p=1270"},"modified":"2023-02-22T19:08:31","modified_gmt":"2023-02-22T11:08:31","slug":"%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%8f%91%e9%80%81%e4%ba%8b%e4%bb%b6%ef%bc%88server-sent-events%ef%bc%89","status":"publish","type":"post","link":"https:\/\/fdream.net\/blog\/article\/1270","title":{"rendered":"\u670d\u52a1\u5668\u53d1\u9001\u4e8b\u4ef6\uff08Server-Sent Events\uff09"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"eryC3\">\u4ec0\u4e48\u662fServer-Sent Events<\/h2>\n\n\n\n<p id=\"u1e94b277\">\u4ece\u540d\u5b57\u53ef\u4ee5\u770b\u51fa\uff0c\u670d\u52a1\u5668\u53d1\u9001\u4e8b\u4ef6\uff08Server-Sent Events\uff09\u662f\u4e00\u79cd\u670d\u52a1\u7aef\u5411\u5ba2\u6237\u7aef\u63a8\u9001\u6d88\u606f\u7684\u65b9\u6cd5\u3002<a href=\"https:\/\/html.spec.whatwg.org\/multipage\/comms.html#the-eventsource-interface\" target=\"_blank\" rel=\"noreferrer noopener\">\u670d\u52a1\u5668\u53d1\u9001\u4e8b\u4ef6\u89c4\u8303(Server-Sent Event)<\/a>\u63cf\u8ff0\u4e86\u4e00\u4e2a\u5185\u7f6e\u7684\u7c7b<code>EventSource<\/code>\uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u4e0e\u670d\u52a1\u5668\u4fdd\u6301\u94fe\u63a5\u5e76\u4e14\u53ef\u4ee5\u4ece\u670d\u52a1\u5668\u63a5\u6536\u65f6\u95f4\u3002<\/p>\n\n\n\n<p id=\"ub2d3e142\">\u548c<code>WebSocket<\/code>\u7c7b\u4f3c\uff0c\u8fd9\u4e2a\u94fe\u63a5\u662f\u6301\u4e45\u7684\uff0c\u4f46\u662f\u4e24\u8005\u6709\u4e00\u4e9b\u4e0d\u540c\uff1a<\/p>\n\n\n\n<figure id=\"aTNPL\" class=\"wp-block-table\"><table><tbody><tr><td><\/td><td><code>WebSocket<\/code><\/td><td><code>EventSource<\/code><\/td><\/tr><tr><td>\u901a\u4fe1\u65b9\u5411<\/td><td>\u53cc\u5411\uff1a\u5ba2\u6237\u548c\u670d\u52a1\u5668\u90fd\u53ef\u4ee5\u4ea4\u6362\u4fe1\u606f<\/td><td>\u5355\u5411\uff1a\u53ea\u6709\u670d\u52a1\u5668\u80fd\u53d1\u9001\u6570\u636e<\/td><\/tr><tr><td>\u6d88\u606f\u7c7b\u578b<\/td><td>\u53ef\u4ee5\u53d1\u9001\u6587\u672c\u4ee5\u53ca\u4e8c\u8fdb\u5236\u6d88\u606f<\/td><td>\u53ea\u80fd\u53d1\u9001\u6587\u672c\u6d88\u606f<\/td><\/tr><tr><td>\u7f51\u7edc\u534f\u8bae<\/td><td>WebSocket\u534f\u8bae<\/td><td>\u5e38\u89c4HTTP\u534f\u8bae<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p id=\"uc812772b\">\u4ece\u4e0a\u8868\u53ef\u4ee5\u770b\u51fa\uff0c<code>Server-Sent Event<\/code>\uff08\u4ee5\u4e0b\u7b80\u79f0SSE\uff09\u76f8\u6bd4<code>WebSocket<\/code>\u662f\u4e00\u79cd\u66f4\u8f7b\u91cf\u7684\u6d88\u606f\u63a8\u9001\u65b9\u5f0f\u3002SSE\u4f7f\u7528\u5e38\u89c4HTTP\u534f\u8bae\uff0c\u5e76\u4e14\u652f\u6301\u65ad\u7ebf\u91cd\u8fde \uff0c\u65e0\u9700\u989d\u5916\u5b9e\u73b0\u3002SSE\u4f7f\u7528\u76f8\u5bf9\u6765\u8bf4\u66f4\u7b80\u5355\u2014\u2014\u5728\u670d\u52a1\u5668\u7aef\uff0c\u53ea\u9700\u8981\u6309\u7167\u4e00\u5b9a\u683c\u5f0f\u8fd4\u56de\u6d88\u606f\uff1b\u5728\u5ba2\u6237\u7aef\u4e2d\uff0c\u53ea\u9700\u8981\u4e3a\u4e00\u4e9b\u4e8b\u4ef6\u7c7b\u578b\u7ed1\u5b9a\u76d1\u542c\u51fd\u6570\uff0c\u548c\u5904\u7406\u5176\u4ed6\u666e\u901a\u7684\u4e8b\u4ef6\u6ca1\u591a\u5927\u533a\u522b\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Yo6IJ\">\u5ba2\u6237\u7aef\u63a5\u6536\u6d88\u606f<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"k2hyv\">\u521b\u5efa\u5bf9\u8c61<\/h3>\n\n\n\n<p id=\"ueea81c41\">\u5ba2\u6237\u7aef\u7684API\u5c31\u662f\u6587\u7ae0\u5f00\u5934\u63d0\u5230\u7684<code>EventSource<\/code>\u63a5\u53e3\uff0c\u8981\u63a5\u53d7\u6d88\u606f\uff0c\u6211\u4eec\u53ea\u9700\u8981\u521b\u5efa\u4e00\u4e2a<code>EventSource<\/code>\u5bf9\u8c61\u5373\u53ef\uff0c\u5e76\u5728\u521b\u5efa\u5bf9\u8c61\u7684\u540c\u65f6\u6307\u5b9a\u63a5\u53d7\u6d88\u606f\u7684\u6765\u6e90<code>URI<\/code>\uff0c\u4f8b\u5982\uff1a<\/p>\n\n\n\n<pre id=\"PQaTp\" class=\"wp-block-code\"><code>const evtSource = new EventSource(url);<\/code><\/pre>\n\n\n\n<p id=\"u8c99ea63\">\u8fd9\u4e2a<code>url<\/code>\u4e5f\u53ef\u4ee5\u8de8\u57df\uff0c\u8de8\u57df\u65f6\u53ef\u4ee5\u5728\u9009\u9879\u4e2d\u6307\u5b9a<code>withCredentials<\/code>\u5c5e\u6027\uff0c\u8868\u793a\u662f\u5426\u4e00\u8d77\u53d1\u9001\u51ed\u8bc1\uff0c\u4f8b\u5982\uff1a<\/p>\n\n\n\n<pre id=\"ANwsu\" class=\"wp-block-code\"><code>const evtSource = new EventSource(\"\/\/api.example.com\/message\", { withCredentials: true } );<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"EhKk8\">\u76d1\u542c\u6d88\u606f<\/h3>\n\n\n\n<p id=\"u5cb10f8b\">\u6210\u529f\u521d\u59cb\u5316\u4e4b\u540e\uff0c\u5c31\u53ef\u4ee5\u6dfb\u52a0onmessage\u4e8b\u4ef6\u5904\u7406\u51fd\u6570\u5f00\u59cb\u76d1\u542c\u4ece\u670d\u52a1\u5668\u53d1\u51fa\u7684\u6d88\u606f\u4e86\uff1a<\/p>\n\n\n\n<pre id=\"MYTSB\" class=\"wp-block-code\"><code>evtSource.onmessage = function(event) {\n  console.log(\"New message\", event.data);\n  \/\/ handle message\n};<\/code><\/pre>\n\n\n\n<p id=\"u2c0a563b\">\u5f53\u7136\u4e5f\u652f\u6301\u53e6\u5916\u4e00\u79cd\u5199\u6cd5\uff1a<\/p>\n\n\n\n<pre id=\"dXijo\" class=\"wp-block-code\"><code>evtSource.addEventListener('message', function (event) {\n  console.log(\"New message\", event.data);\n  \/\/ handle message\n}, false);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"QR9c6\">\u9519\u8bef\u5904\u7406<\/h3>\n\n\n\n<p id=\"u6867fdeb\">\u5982\u679c\u53d1\u751f\u9519\u8bef\uff08\u5982\u8fde\u63a5\u4e2d\u65ad\u6216\u8005\u8de8\u57df\u9519\u8bef\uff09\uff0c\u5c31\u4f1a\u89e6\u53d1onerror\u4e8b\u4ef6\uff1a<\/p>\n\n\n\n<pre id=\"syNVk\" class=\"wp-block-code\"><code>evtSource.onerror = function (event) {\n  \/\/ handle error event\n};<\/code><\/pre>\n\n\n\n<p id=\"uf06bbf78\">\u540c\u6837\uff0c\u4e5f\u652f\u6301\u53e6\u5916\u4e00\u79cd\u5199\u6cd5\uff1a<\/p>\n\n\n\n<pre id=\"Gg9Jw\" class=\"wp-block-code\"><code>evtSource.addEventListener('error', function (event) {\n  \/\/ handle error event\n}, false);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ENdxt\">\u91cd\u8fde<\/h3>\n\n\n\n<p id=\"u778c0780\">\u5728\u53d1\u751f\u9519\u8bef\u65ad\u5f00\u8fde\u63a5\u4e4b\u540e\uff0c\u8fde\u63a5\u4f1a\u81ea\u52a8\u91cd\u8fde\uff0c\u800c\u65e0\u9700\u989d\u5916\u5904\u7406\u3002\u5982\u679c\u9700\u8981\u6307\u5b9a\u81ea\u52a8\u91cd\u8fde\u7684\u5ef6\u8fdf\u65f6\u95f4\uff0c\u670d\u52a1\u5668\u7aef\u53ef\u4ee5\u5728\u8fd4\u56de\u7684\u6d88\u606f\u4e2d\u6307\u5b9a\u3002<\/p>\n\n\n\n<pre id=\"LA950\" class=\"wp-block-code\"><code>retry: 15000<\/code><\/pre>\n\n\n\n<p id=\"u468bcc41\">\u6d4f\u89c8\u5668\u4f1a\u7b49\u5f85\u6307\u5b9a\u7684\u65f6\u95f4\u4ee5\u540e\u5f00\u59cb\u91cd\u8fde\uff0c\u4e5f\u6709\u53ef\u80fd\u66f4\u957f\uff0c\u6bd4\u5982\u6d4f\u89c8\u5668\u77e5\u9053\u5f53\u524d\u6ca1\u6709\u7f51\u7edc\u7684\u60c5\u51b5\u4e0b\uff0c\u4f1a\u7b49\u5f85\u77e5\u9053\u6709\u7f51\u7edc\u4e4b\u540e\u518d\u91cd\u8fde\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"bPTUL\">\u5173\u95ed\u8fde\u63a5<\/h3>\n\n\n\n<p id=\"u3500eafe\">\u5982\u679c\u5ba2\u6237\u7aef\u8981\u5173\u95ed\u8fde\u63a5\uff0c\u76f4\u63a5\u8c03\u7528\u5bf9\u5e94\u7684\u65b9\u6cd5\u5373\u53ef\uff1a<\/p>\n\n\n\n<pre id=\"R6h8F\" class=\"wp-block-code\"><code>evtSource.close();<\/code><\/pre>\n\n\n\n<p id=\"u315a852e\">\u5982\u679c\u670d\u52a1\u7aef\u60f3\u62d2\u7edd\u5ba2\u6237\u7aef\u91cd\u8fde\uff0c\u53ea\u9700\u8fd4\u56deHTTP\u72b6\u6001\u7801204\u5373\u53ef\u3002<\/p>\n\n\n\n<p id=\"u8dc6fd52\">\u5907\u6ce8\uff1a\u5f53\u8fde\u63a5\u5173\u95ed\u4ee5\u540e\uff0c\u662f\u6ca1\u6709\u529e\u6cd5\u91cd\u65b0\u6253\u5f00\u8fd9\u4e2a\u8fde\u63a5\u7684\u3002\u5982\u679c\u9700\u8981\u91cd\u8fde\uff0c\u53ea\u80fd\u91cd\u65b0\u521b\u5efa\u4e00\u4e2a\u8fde\u63a5\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"d2cu1\">\u4e8b\u4ef6\u6d41\u6570\u636e\u683c\u5f0f<\/h2>\n\n\n\n<p id=\"u6a959b15\">\u670d\u52a1\u5668\u8981\u5411\u5ba2\u6237\u7aef\u53d1\u9001SSE\u6570\u636e\uff0c\u5fc5\u987b\u53d1\u9001\u4ee5\u4e0bHTTP\u5934\u4fe1\u606f\uff1a<\/p>\n\n\n\n<pre id=\"bX0yc\" class=\"wp-block-code\"><code>Content-Type: text\/event-stream\nCache-Control: no-cache<\/code><\/pre>\n\n\n\n<p id=\"u10d91475\">\u4e8b\u4ef6\u6d41\u53ea\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u6587\u672c\u6570\u636e\u6d41\uff0c\u4f7f\u7528UTF8\u7f16\u7801\u3002\u6bcf\u6761\u6d88\u606f\uff08message\uff09\u540e\u9762\u90fd\u6709\u4e00\u6761\u7a7a\u884c\u4f5c\u4e3a\u5206\u9694\u7b26\uff08\u4e24\u4e2a\u6362\u884c\u7b26\uff1a<code>\\n\\n<\/code>\uff09\u3002\u6bcf\u6761\u6d88\u606f\u7531\u591a\u884c\u7ec4\u6210\uff0c\u6bcf\u4e00\u884c\u7531\u4e00\u4e2a\u5b57\u6bb5\u540d\uff0c\u4e00\u4e2a\u5192\u53f7\u4ee5\u53ca\u5b57\u6bb5\u503c\u7ec4\u6210\u3002<\/p>\n\n\n\n<pre id=\"bavEu\" class=\"wp-block-code\"><code>field: value<\/code><\/pre>\n\n\n\n<p id=\"u1f4929e6\">\u5176\u4e2d\u5b57\u6bb5\u540dfield\u53ea\u80fd\u53d6\u4ee5\u4e0b\u56db\u79cd\uff1a<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"Bj4XF\"><code>event<\/code><\/h4>\n\n\n\n<p id=\"ue186fe8d\">\u4e8b\u4ef6\u7c7b\u578b\u3002\u5982\u679c\u6307\u5b9a\u4e86\u8be5\u5b57\u6bb5\uff0c\u5219\u5728\u5ba2\u6237\u7aef\u63a5\u6536\u5230\u8be5\u6761\u6d88\u606f\u65f6\uff0c\u4f1a\u5728\u5f53\u524d\u7684<code>EventSource<\/code>\u5bf9\u8c61\u4e0a\u89e6\u53d1\u4e00\u4e2a\u4e8b\u4ef6\uff0c\u4e8b\u4ef6\u7c7b\u578b\u5c31\u662f\u8be5\u5b57\u6bb5\u7684\u503c\uff0c\u4e5f\u79f0\u4e3a\u547d\u540d\u4e8b\u4ef6\u3002\u4f60\u53ef\u4ee5\u4f7f\u7528<code>addEventListener()<\/code>\u65b9\u6cd5\u5728\u5f53\u524d<code>EventSource<\/code>\u5bf9\u8c61\u4e0a\u76d1\u542c\u4efb\u610f\u7c7b\u578b\u7684\u547d\u540d\u4e8b\u4ef6\uff0c\u5982\u679c\u8be5\u6761\u6d88\u606f\u6ca1\u6709<code>event<\/code>\u5b57\u6bb5\uff0c\u5219\u4f1a\u89e6\u53d1<code>onmessage<\/code>\u5c5e\u6027\u4e0a\u7684\u4e8b\u4ef6\u5904\u7406\u51fd\u6570.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"WsZE9\"><code>data<\/code><\/h4>\n\n\n\n<p id=\"u1ad242ef\">\u6d88\u606f\u7684\u6570\u636e\u5b57\u6bb5\u3002\u5982\u679c\u4e00\u6761\u6d88\u606f\u5305\u542b\u591a\u4e2a<code>data<\/code>\u5b57\u6bb5\uff0c\u5ba2\u6237\u7aef\u4f1a\u7528\u6362\u884c\u7b26\u628a\u5b83\u4eec\u8fde\u63a5\u6210\u4e00\u4e2a\u5b57\u7b26\u4e32\u6765\u4f5c\u4e3a\u5b57\u6bb5\u503c\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"bkF3M\"><code>id<\/code><\/h4>\n\n\n\n<p id=\"u3bce6e0e\">\u4e8b\u4ef6 ID\uff0c\u4f1a\u6210\u4e3a\u5f53\u524d<code>EventSource<\/code>\u5bf9\u8c61\u7684\u5185\u90e8\u5c5e\u6027\u201c\u6700\u540e\u4e00\u4e2a\u4e8b\u4ef6 ID\u201d\uff08<code>Last-Event-ID<\/code>\uff09\u7684\u5c5e\u6027\u503c\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"csjgU\"><code>retry<\/code><\/h4>\n\n\n\n<p id=\"u6b7b9144\">\u4e00\u4e2a\u6574\u6570\u503c\uff0c\u6307\u5b9a\u4e86\u91cd\u8fde\u7684\u65f6\u95f4\u95f4\u9694\uff08\u5355\u4f4d\u4e3a\u6beb\u79d2\uff09\uff0c\u5fc5\u987b\u4e3a\u6574\u6570\u3002<\/p>\n\n\n\n<p id=\"u574e25bd\">\u6709\u4e00\u4e2a\u4f8b\u5916\u662f\uff0c\u6d88\u606f\u53ef\u4ee5\u4ee5\u5192\u53f7\u5f00\u5934\u3002\u4ee5\u5192\u53f7\u5f00\u5934\u7684\u6d88\u606f\u4f1a\u7406\u89e3\u4e3a\u6ce8\u91ca\uff0c\u88ab\u5ba2\u6237\u7aef\u5ffd\u7565\u3002\u5728\u6ca1\u6709\u6d88\u606f\u65f6\uff0c\u901a\u5e38\u4f1a\u95f4\u9694\u4e00\u6bb5\u65f6\u95f4\u53d1\u9001\u4e00\u6761\u6ce8\u91ca\u6765\u4fdd\u6301\u8fde\u63a5\u3002<\/p>\n\n\n\n<p id=\"u51e039ce\">\u4e00\u4e2a\u4e8b\u4ef6\u6d41\u793a\u4f8b\uff1a<\/p>\n\n\n\n<pre id=\"ite3Y\" class=\"wp-block-code\"><code>event: userconnect\ndata: {\"username\": \"bobby\", \"time\": \"02:33:48\"}\n\ndata: Here's a system message of some kind that will get used\ndata: to accomplish some task.\n\nevent: usermessage\ndata: {\"username\": \"bobby\", \"time\": \"02:34:11\", \"text\": \"Hi everyone.\"}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"RrcPD\">\u670d\u52a1\u7aef\u5b9e\u73b0<\/h2>\n\n\n\n<p id=\"ud9644e40\">\u4e00\u4e2a\u7b80\u5355\u7684node\u5b9e\u73b0\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre id=\"FoSsv\" class=\"wp-block-code\"><code>let http = require('http');\nlet static = require('node-static');\nlet fileServer = new static.Server('.');\n\nfunction onDigits(req, res) {\n  \/\/ \u8f93\u51fa\u56fa\u5b9a\u7684header\n  res.writeHead(200, {\n    'Content-Type': 'text\/event-stream; charset=utf-8',\n    'Cache-Control': 'no-cache'\n  });\n\n  let i = 0;\n\n  let timer = setInterval(write, 1000);\n  write();\n\n  function write() {\n    i++;\n\n    \/\/ \u56db\u6761\u6d88\u606f\u540e\u4f1a\u65ad\u5f00\n    if (i == 4) {\n      res.write('event: bye\\ndata: bye-bye\\n\\n');\n      clearInterval(timer);\n      res.end();\n      return;\n    }\n    res.write('data: ' + i + '\\n\\n');\n  }\n}\n\nfunction accept(req, res) {\n  if (req.url == '\/digits') {\n    onDigits(req, res);\n    return;\n  }\n\n  fileServer.serve(req, res);\n}\n\nif (!module.parent) {\n  http.createServer(accept).listen(8080);\n} else {\n  exports.accept = accept;\n}<\/code><\/pre>\n\n\n\n<p id=\"ud3f06460\">\u5ba2\u6237\u7aef\u5b9e\u73b0\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre id=\"L0SuR\" class=\"wp-block-code\"><code>&lt;!DOCTYPE html>\n&lt;script>\nlet eventSource;\n\nfunction start() {\n  if (!window.EventSource) {\n    \/\/ IE or an old browser\n    alert(\"The browser doesn't support EventSource.\");\n    return;\n  }\n\n  eventSource = new EventSource('digits');\n\n  eventSource.onopen = function(e) {\n    console.log(e);\n    log(\"Event: open\");\n  };\n\n  eventSource.onerror = function(e) {\n    log(\"Event: error\");\n    if (this.readyState == EventSource.CONNECTING) {\n      log(`Reconnecting (readyState=${this.readyState})...`);\n    } else {\n      log(\"Error has occured.\");\n    }\n  };\n\n  eventSource.addEventListener('bye', function(e) {\n    log(\"Event: bye, data: \" + e.data);\n  });\n\n  eventSource.onmessage = function(e) {\n    log(\"Event: message, data: \" + e.data);\n  };\n}\n\nfunction stop() { \/\/ when \"Stop\" button pressed\n  eventSource.close();\n  log(\"eventSource.close()\");\n}\n\nfunction log(msg) {\n  logElem.innerHTML += msg + \"&lt;br>\";\n  document.documentElement.scrollTop = 99999999;\n}\n&lt;\/script>\n\n&lt;button onclick=\"start()\">Start&lt;\/button> Press the \"Start\" to begin.\n&lt;div id=\"logElem\" style=\"margin: 6px 0\">&lt;\/div>\n\n&lt;button onclick=\"stop()\">Stop&lt;\/button> \"Stop\" to finish.<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"CV2Sw\">\u53c2\u8003\u94fe\u63a5<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Using server-sent events\uff1a<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Server-sent_events\/Using_server-sent_events\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Server-sent_events\/Using_server-sent_events<\/a><\/li>\n\n\n\n<li>MDN EventSource\uff1a<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/EventSource\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/EventSource<\/a><\/li>\n\n\n\n<li>Browser APIs and Protocols: Server-Sent Events (SSE)\uff1a<a href=\"https:\/\/hpbn.co\/server-sent-events-sse\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/hpbn.co\/server-sent-events-sse\/<\/a><\/li>\n\n\n\n<li>Server Sent Events\uff1a<a href=\"https:\/\/javascript.info\/server-sent-events\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/javascript.info\/server-sent-events<\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>\u4ec0\u4e48\u662fServer-Sent Events \u4ece\u540d\u5b57\u53ef\u4ee5\u770b\u51fa\uff0c\u670d\u52a1\u5668\u53d1\u9001\u4e8b\u4ef6\uff08Server-Sent Events\uff09\u662f\u4e00\u79cd\u670d\u52a1\u7aef\u5411\u5ba2\u6237\u7aef\u63a8\u9001\u6d88\u606f\u7684\u65b9\u6cd5\u3002\u670d\u52a1\u5668\u53d1\u9001\u4e8b\u4ef6\u89c4\u8303(Server-Sent Event)\u63cf\u8ff0\u4e86\u4e00\u4e2a\u5185\u7f6e\u7684\u7c7bEventSource\uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u4e0e\u670d\u52a1\u5668\u4fdd\u6301\u94fe\u63a5\u5e76\u4e14\u53ef\u4ee5\u4ece\u670d\u52a1\u5668\u63a5\u6536\u65f6\u95f4\u3002 \u548cWebSocket\u7c7b\u4f3c\uff0c\u8fd9\u4e2a\u94fe\u63a5\u662f\u6301\u4e45\u7684\uff0c\u4f46\u662f\u4e24\u8005\u6709\u4e00\u4e9b\u4e0d\u540c\uff1a WebSocket EventSource \u901a\u4fe1\u65b9\u5411 \u53cc\u5411\uff1a\u5ba2\u6237\u548c\u670d\u52a1\u5668\u90fd\u53ef\u4ee5\u4ea4\u6362\u4fe1\u606f \u5355\u5411\uff1a\u53ea\u6709\u670d\u52a1\u5668\u80fd\u53d1\u9001\u6570\u636e \u6d88\u606f\u7c7b\u578b \u53ef\u4ee5\u53d1\u9001\u6587\u672c\u4ee5\u53ca\u4e8c\u8fdb\u5236\u6d88\u606f \u53ea\u80fd\u53d1\u9001\u6587\u672c\u6d88\u606f \u7f51\u7edc\u534f\u8bae WebSocket\u534f\u8bae \u5e38\u89c4HTTP\u534f\u8bae \u4ece\u4e0a\u8868\u53ef\u4ee5\u770b\u51fa\uff0cServer-Sent Event\uff08\u4ee5\u4e0b\u7b80\u79f0SSE\uff09\u76f8\u6bd4WebSocket\u662f\u4e00\u79cd\u66f4\u8f7b\u91cf\u7684\u6d88\u606f\u63a8\u9001\u65b9\u5f0f\u3002SSE\u4f7f\u7528\u5e38\u89c4HTTP\u534f\u8bae\uff0c\u5e76\u4e14\u652f\u6301\u65ad\u7ebf\u91cd\u8fde \uff0c\u65e0\u9700\u989d\u5916\u5b9e\u73b0\u3002SSE\u4f7f\u7528\u76f8\u5bf9\u6765\u8bf4\u66f4\u7b80\u5355\u2014\u2014\u5728\u670d\u52a1\u5668\u7aef\uff0c\u53ea\u9700\u8981\u6309\u7167\u4e00\u5b9a\u683c\u5f0f\u8fd4\u56de\u6d88\u606f\uff1b\u5728\u5ba2\u6237\u7aef\u4e2d\uff0c\u53ea\u9700\u8981\u4e3a\u4e00\u4e9b\u4e8b\u4ef6\u7c7b\u578b\u7ed1\u5b9a\u76d1\u542c\u51fd\u6570\uff0c\u548c\u5904\u7406\u5176\u4ed6\u666e\u901a\u7684\u4e8b\u4ef6\u6ca1\u591a\u5927\u533a\u522b\u3002 \u5ba2\u6237\u7aef\u63a5\u6536\u6d88\u606f \u521b\u5efa\u5bf9\u8c61 \u5ba2\u6237\u7aef\u7684API\u5c31\u662f\u6587\u7ae0\u5f00\u5934\u63d0\u5230\u7684EventSource\u63a5\u53e3\uff0c\u8981\u63a5\u53d7\u6d88\u606f\uff0c\u6211\u4eec\u53ea\u9700\u8981\u521b\u5efa\u4e00\u4e2aEventSource\u5bf9\u8c61\u5373\u53ef\uff0c\u5e76\u5728\u521b\u5efa\u5bf9\u8c61\u7684\u540c\u65f6\u6307\u5b9a\u63a5\u53d7\u6d88\u606f\u7684\u6765\u6e90URI\uff0c\u4f8b\u5982\uff1a \u8fd9\u4e2aurl\u4e5f\u53ef\u4ee5\u8de8\u57df\uff0c\u8de8\u57df\u65f6\u53ef\u4ee5\u5728\u9009\u9879\u4e2d\u6307\u5b9awithCredentials\u5c5e\u6027\uff0c\u8868\u793a\u662f\u5426\u4e00\u8d77\u53d1\u9001\u51ed\u8bc1\uff0c\u4f8b\u5982\uff1a \u76d1\u542c\u6d88\u606f \u6210\u529f\u521d\u59cb\u5316\u4e4b\u540e\uff0c\u5c31\u53ef\u4ee5\u6dfb\u52a0onmessage\u4e8b\u4ef6\u5904\u7406\u51fd\u6570\u5f00\u59cb\u76d1\u542c\u4ece\u670d\u52a1\u5668\u53d1\u51fa\u7684\u6d88\u606f\u4e86\uff1a \u5f53\u7136\u4e5f\u652f\u6301\u53e6\u5916\u4e00\u79cd\u5199\u6cd5\uff1a \u9519\u8bef\u5904\u7406 \u5982\u679c\u53d1\u751f\u9519\u8bef\uff08\u5982\u8fde\u63a5\u4e2d\u65ad\u6216\u8005\u8de8\u57df\u9519\u8bef\uff09\uff0c\u5c31\u4f1a\u89e6\u53d1onerror\u4e8b\u4ef6\uff1a \u540c\u6837\uff0c\u4e5f\u652f\u6301\u53e6\u5916\u4e00\u79cd\u5199\u6cd5\uff1a \u91cd\u8fde \u5728\u53d1\u751f\u9519\u8bef\u65ad\u5f00\u8fde\u63a5\u4e4b\u540e\uff0c\u8fde\u63a5\u4f1a\u81ea\u52a8\u91cd\u8fde\uff0c\u800c\u65e0\u9700\u989d\u5916\u5904\u7406\u3002\u5982\u679c\u9700\u8981\u6307\u5b9a\u81ea\u52a8\u91cd\u8fde\u7684\u5ef6\u8fdf\u65f6\u95f4\uff0c\u670d\u52a1\u5668\u7aef\u53ef\u4ee5\u5728\u8fd4\u56de\u7684\u6d88\u606f\u4e2d\u6307\u5b9a\u3002 \u6d4f\u89c8\u5668\u4f1a\u7b49\u5f85\u6307\u5b9a\u7684\u65f6\u95f4\u4ee5\u540e\u5f00\u59cb\u91cd\u8fde\uff0c\u4e5f\u6709\u53ef\u80fd\u66f4\u957f\uff0c\u6bd4\u5982\u6d4f\u89c8\u5668\u77e5\u9053\u5f53\u524d\u6ca1\u6709\u7f51\u7edc\u7684\u60c5\u51b5\u4e0b\uff0c\u4f1a\u7b49\u5f85\u77e5\u9053\u6709\u7f51\u7edc\u4e4b\u540e\u518d\u91cd\u8fde\u3002 \u5173\u95ed\u8fde\u63a5 \u5982\u679c\u5ba2\u6237\u7aef\u8981\u5173\u95ed\u8fde\u63a5\uff0c\u76f4\u63a5\u8c03\u7528\u5bf9\u5e94\u7684\u65b9\u6cd5\u5373\u53ef\uff1a \u5982\u679c\u670d\u52a1\u7aef\u60f3\u62d2\u7edd\u5ba2\u6237\u7aef\u91cd\u8fde\uff0c\u53ea\u9700\u8fd4\u56deHTTP\u72b6\u6001\u7801204\u5373\u53ef\u3002 \u5907\u6ce8\uff1a\u5f53\u8fde\u63a5\u5173\u95ed\u4ee5\u540e\uff0c\u662f\u6ca1\u6709\u529e\u6cd5\u91cd\u65b0\u6253\u5f00\u8fd9\u4e2a\u8fde\u63a5\u7684\u3002\u5982\u679c\u9700\u8981\u91cd\u8fde\uff0c\u53ea\u80fd\u91cd\u65b0\u521b\u5efa\u4e00\u4e2a\u8fde\u63a5\u3002 \u4e8b\u4ef6\u6d41\u6570\u636e\u683c\u5f0f \u670d\u52a1\u5668\u8981\u5411\u5ba2\u6237\u7aef\u53d1\u9001SSE\u6570\u636e\uff0c\u5fc5\u987b\u53d1\u9001\u4ee5\u4e0bHTTP\u5934\u4fe1\u606f\uff1a \u4e8b\u4ef6\u6d41\u53ea\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u6587\u672c\u6570\u636e\u6d41\uff0c\u4f7f\u7528UTF8\u7f16\u7801\u3002\u6bcf\u6761\u6d88\u606f\uff08message\uff09\u540e\u9762\u90fd\u6709\u4e00\u6761\u7a7a\u884c\u4f5c\u4e3a\u5206\u9694\u7b26\uff08\u4e24\u4e2a\u6362\u884c\u7b26\uff1a\\n\\n\uff09\u3002\u6bcf\u6761\u6d88\u606f\u7531\u591a\u884c\u7ec4\u6210\uff0c\u6bcf\u4e00\u884c\u7531\u4e00\u4e2a\u5b57\u6bb5\u540d\uff0c\u4e00\u4e2a\u5192\u53f7\u4ee5\u53ca\u5b57\u6bb5\u503c\u7ec4\u6210\u3002 \u5176\u4e2d\u5b57\u6bb5\u540dfield\u53ea\u80fd\u53d6\u4ee5\u4e0b\u56db\u79cd\uff1a event \u4e8b\u4ef6\u7c7b\u578b\u3002\u5982\u679c\u6307\u5b9a\u4e86\u8be5\u5b57\u6bb5\uff0c\u5219\u5728\u5ba2\u6237\u7aef\u63a5\u6536\u5230\u8be5\u6761\u6d88\u606f\u65f6\uff0c\u4f1a\u5728\u5f53\u524d\u7684EventSource\u5bf9\u8c61\u4e0a\u89e6\u53d1\u4e00\u4e2a\u4e8b\u4ef6\uff0c\u4e8b\u4ef6\u7c7b\u578b\u5c31\u662f\u8be5\u5b57\u6bb5\u7684\u503c\uff0c\u4e5f\u79f0\u4e3a\u547d\u540d\u4e8b\u4ef6\u3002\u4f60\u53ef\u4ee5\u4f7f\u7528addEventListener()\u65b9\u6cd5\u5728\u5f53\u524dEventSource\u5bf9\u8c61\u4e0a\u76d1\u542c\u4efb\u610f\u7c7b\u578b\u7684\u547d\u540d\u4e8b\u4ef6\uff0c\u5982\u679c\u8be5\u6761\u6d88\u606f\u6ca1\u6709event\u5b57\u6bb5\uff0c\u5219\u4f1a\u89e6\u53d1onmessage\u5c5e\u6027\u4e0a\u7684\u4e8b\u4ef6\u5904\u7406\u51fd\u6570. data \u6d88\u606f\u7684\u6570\u636e\u5b57\u6bb5\u3002\u5982\u679c\u4e00\u6761\u6d88\u606f\u5305\u542b\u591a\u4e2adata\u5b57\u6bb5\uff0c\u5ba2\u6237\u7aef\u4f1a\u7528\u6362\u884c\u7b26\u628a\u5b83\u4eec\u8fde\u63a5\u6210\u4e00\u4e2a\u5b57\u7b26\u4e32\u6765\u4f5c\u4e3a\u5b57\u6bb5\u503c\u3002 id \u4e8b\u4ef6 ID\uff0c\u4f1a\u6210\u4e3a\u5f53\u524dEventSource\u5bf9\u8c61\u7684\u5185\u90e8\u5c5e\u6027\u201c\u6700\u540e\u4e00\u4e2a\u4e8b\u4ef6 ID\u201d\uff08Last-Event-ID\uff09\u7684\u5c5e\u6027\u503c\u3002 retry \u4e00\u4e2a\u6574\u6570\u503c\uff0c\u6307\u5b9a\u4e86\u91cd\u8fde\u7684\u65f6\u95f4\u95f4\u9694\uff08\u5355\u4f4d\u4e3a\u6beb\u79d2\uff09\uff0c\u5fc5\u987b\u4e3a\u6574\u6570\u3002 \u6709\u4e00\u4e2a\u4f8b\u5916\u662f\uff0c\u6d88\u606f\u53ef\u4ee5\u4ee5\u5192\u53f7\u5f00\u5934\u3002\u4ee5\u5192\u53f7\u5f00\u5934\u7684\u6d88\u606f\u4f1a\u7406\u89e3\u4e3a\u6ce8\u91ca\uff0c\u88ab\u5ba2\u6237\u7aef\u5ffd\u7565\u3002\u5728\u6ca1\u6709\u6d88\u606f\u65f6\uff0c\u901a\u5e38\u4f1a\u95f4\u9694\u4e00\u6bb5\u65f6\u95f4\u53d1\u9001\u4e00\u6761\u6ce8\u91ca\u6765\u4fdd\u6301\u8fde\u63a5\u3002 \u4e00\u4e2a\u4e8b\u4ef6\u6d41\u793a\u4f8b\uff1a \u670d\u52a1\u7aef\u5b9e\u73b0 \u4e00\u4e2a\u7b80\u5355\u7684node\u5b9e\u73b0\u5982\u4e0b\uff1a &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[379,364],"class_list":["post-1270","post","type-post","status-publish","format-standard","hentry","category-coding","tag-sse","tag-websocket"],"views":891,"_links":{"self":[{"href":"https:\/\/fdream.net\/blog\/wp-json\/wp\/v2\/posts\/1270","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fdream.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fdream.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fdream.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fdream.net\/blog\/wp-json\/wp\/v2\/comments?post=1270"}],"version-history":[{"count":0,"href":"https:\/\/fdream.net\/blog\/wp-json\/wp\/v2\/posts\/1270\/revisions"}],"wp:attachment":[{"href":"https:\/\/fdream.net\/blog\/wp-json\/wp\/v2\/media?parent=1270"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fdream.net\/blog\/wp-json\/wp\/v2\/categories?post=1270"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fdream.net\/blog\/wp-json\/wp\/v2\/tags?post=1270"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}