Server-sent Event 简单介绍

现在前后端通讯的常用的方式有ajax,websocket,还有fetch。但是经常的我们会接到一些需求,比如说后端要给前端发送一些通知,前端接收到通知之后,做出相应的操作,比如说发说说之类的,当自己的朋友发一个说说的话,他也希望你这边的界面也要呈现出来,或者说当一个企业的管理员发送一个公告,你再你的电脑上面也要能够及时的响应出来,这样的需求我相信很多人都遇见过。

针对于上面的问题,我们常用的方式就是用setInterval去做轮询或者是websocket,只是前者setInterval轮询这个中间的时间间隔需要考虑好,如果事件间隔较短,这对服务器的压力比较大,如果事件较长,则有些需要立即立即做出响应的方式是做不到的。后者的websocket相对来说技技术要求有点高,实现起来比较复杂。

所以就有现在的这种方式就是Server-sent Events,也就是说服务器端给前端浏览器发送事件的方式。使用Server-sent Events其实是非常简单的。我们只需要需要在服务器端将事件流发送给前端,然后前端接收到后端所传给的事件流,然后触发事件,这是事件的捕获和监听其实和前端的事件捕获和触发是一样的。所以对于前端人员来说,这种处理方式是非常的简单的。

Server-sent Events是包含在EventSoruce对象中。我们可以通过创建一个EventSource对象,给对象中传入一个地址,也就是我们请求服务器端发送事件的地址,就创建了链接,如下所示:

var evtSource = new EventSource('/sse');

其中 '/sse' 是服务器端给的向前端发送事件的接口地址。通过get方式进行发送事件。

如果事件发送地址存在跨域问题,则,我们在创建EvenetSource对象的时候,需要制定具体的地址,比如说:

var evtSource = new EventSource('http://www.baidu.com', { withCredentials: true });

这个时候,我们的事件接收器就算是创建好了,然后通过通过onmessage来接收后台传给前端的数据,也可以通过addEventListener去创建事件的监听,但是通过addEventListener创建的事件监听是需要后端的事件发送方发送相对应的事件,才能够进行触发的。

var evtSource = new EventSource('/sse');

evtSource.onmessage = function (e) {
  console.log(e.data)
}

也就是当后端发送的内容之后就会进行触发,并且将data给打印出来,首先要提出的的是,Server-sent Events 所发送的内容都是字符串的流而且是通过utf-8的编码格式的,如果后端希望给前端发送一串json,也需要将json转化成相对应的字符串,然后在发送给前端,前端接收之后,再讲所发送的字符串转换成json,然后进行处理。

然后就是监听后端发送给前端的事件内容,不如说,我们后端给前端sent一个testEvent事件,前端通过事件接收者,去触犯相对应的事件监听,因此就有了下面的工作流程

var evtSource = new EventSource('/sse');

evtSource.addEventListener('testEvent', function (e) {
  console.log(e)
})

上面代码是前端的接收事件的放,是不是很类似,就像我们之前用的一样。

var btn = document.getElementById('button')

btn.addEventListener('click', funciont (e) { 
  console.log(e)
})

我们看到了前端的处理方案,但是后端应该如何才能给我们发送事件呢,

首先我们发送内容是需要给前端设置一个mime为text/event-stream,然后在进行发送事件的内容,下面是相对应的node代码

router.get('/sse', (req, res, next)=> {
  res.writeHead(200, {
    'Connection': 'keep-alive',
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache'
  });
  let data = { meg: '这是一个测试SSE的数据内容' };

  setTimeout(() => {
    console.log(JSON.stringify(data));
    res.write('data:' + JSON.stringify(data) + '\n\n');
  }, 2000)
})

这样就能够发送给前端一条消息,就能够触发前端的事件内容。

router.get('/sse', (req, res, next)=> {
  res.writeHead(200, {
    'Connection': 'keep-alive',
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache'
  });
  let data = { meg: '这是一个测试SSE的数据内容' };

  setTimeout(() => {
    console.log(JSON.stringify(data));
    res.write('event: testEvent\n\n');
    res.write('data:' + JSON.stringify(data) + '\n\n');
  }, 2000)
})

这个就是给前端发送图个testEvent,所传送的数据就是我们的data内容。

转载于:https://my.oschina.net/shuinian/blog/1606044

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值