遇到的问题:
这几天在vue项目中需要使用EventSource实现服务端推送,并且使用utf8和hmacsha1签名。在这个项目中用到了Moment.js和CryptoJs。Moment.js是用来获取UTC格式的本地时间。CryptoJs是用来进行utf8,hmacsha1加密和base64加密。
EventSource
是什么: EventSource的官方名称应该是 Server-sent events(缩写SSE)服务端派发事件,EventSource 基于http协议只是简单的单项通信,实现了服务端推的过程客户端无法通过EventSource向服务端发送数据。喜闻乐见的是ie并没有良好的兼容当然也有解决的办法比如 npm install event-source-polyfill
。虽然不能实现双向通信但是在功能设计上他也有一些优点比如可以自动重连接,event IDs,以及发送随机事件的能力(WebSocket要借助第三方库比如socket.io可以实现重连。)
有什么用: 因为受单项通信的限制EventSource只能用来实现像股票报价、新闻推送、实时天气这些只需要服务器发送消息给客户端场景中。EventSource的使用更加便捷这也是他的优点。
解决方法:
// 实例化 EventSource 参数是服务端监听的路由。
if('EventSource' in window){ //判断当前浏览器是否支持sse
let urlLink = 'http://172.16.0.88';
this.source = new EventSource(urlLink);
this.source.onopen = function (event) { // 与服务器连接成功回调
if(this.source.readyState == 0){
console.log('sse通道未建立')
}
if(this.source.readyState == 1){
console.log('sse通道连接成功')
}
if(this.source.readyState == 2){
console.log('sse通道断开连接')
}
};
this.getEventListener(); //监听事件获取图片数据
this.source.onerror = function (error) { // 监听错误
console.log('错误')
}
},
//监听事件获取图片数据
getEventListener(){
let _that = this;
_that.source.addEventListener('getDataList',function(e){
if(e.data != null){
let imgArr = [];
imgArr = JSON.parse(e.data);
_that.getUtcTime(); //获取UTC格式的本地时间
_that.getHas1(imgArr); //通过has1加密获取signture
_that.getTest(imgArr); //获取图片
}
})
},
//获取utc格式的本地时间(使用moment.js)
getUtcTime(){
let localTime = new Date();
this.localTimeUtc = this.$moment(localTime).utc().format("ddd, DD MMM YYYY HH:mm:ss UTC");
},
//获取signture
getHas1(obj){
let _that = this;
if(obj != null){
obj.map(item=>{
let stringToSign = "GET\n\n\n\nx-amz-date:"+_that .localTimeUtc+"/n\thumbnail/"+item;
let sign1 = _that.$cryptoJs.enc.utf8.parse(stringToSign); //使用cryptoJs,转本地时间为utf8格式
let result = _that.$cryptoJs.HmacSHA1(sign1,"PoKKHHTEST"); //使用cryptoJs,将utf8格式后的结果进行HmacSHA1加密
return _that.Signture.push(_that.$cryptoJs.enc.Base64.stringify(result)); //将HmacSHA1加密后的结果使用cryptoJs,进行base64加密
})
}
}
二、如何使用EventSource在header里面传参呢?
那就要用到EventSourcePolyfill
首先,npm进行安装:
npm install event-source-polyfill
例子:
import {EventSourcePolyfill} from 'event-source-polyfill';
var es = new EventSourcePolyfill('/events', {
headers: {
'Authorization': 'token',
'X-Custom-Header': 'value'
}
});
es.onopen = function(event) {
console.log('连接成功')
}
es.onmessage = function(event) {
// to to something…
}
es.onerror = function (error) { // 监听错误
console.log('错误')
}