可以使用wx.request自己实现一个 export default class EventSource { constructor(url, retryTime = 0) { this.url = url; this.retryTime = retryTime; this.listeners = {}; this.requestTask = null; this.connect() } connect() { this.requestTask = wx.request({ url: this.url, enableChunked: true, responseType: 'text', method: 'GET', timeout: 300e3, success: res => { this.emit('success', res) if (this.retryTime > 0) { setTimeout(() => { this.connect() }, this.retryTime) } }, fail: () => { } }); this.requestTask.onHeadersReceived(res => { this.emit('open', res); }) this.requestTask.onChunkReceived(res => this.handleChunk(res)) } handleChunk(res) { const arrayBuffer = res.data; const uint8Array = new Uint8Array(arrayBuffer); let data = uni.arrayBufferToBase64(uint8Array) data = new Buffer(data, 'base64') data = data.toString('utf8'); const eventData = this.parseEventData(data); this.emit(eventData.event, {data: eventData.data}); } parseEventData(data) { const lines = data.split('\n'); const result = {}; lines.forEach(line => { const [key, value] = line.trim().split(':'); if (key === 'data') { const data = line.substring(5).trim(); try { result[key] = JSON.parse(data); } catch(e) { result[key] = data; } } else { result[key] = value; } }); if (!result.event) { result.event = 'message' } return result; } addEventListener(event, callback) { if (!this.listeners[event]) { this.listeners[event] = []; } this.listeners[event].push(callback); } emit(event, data) { if (this.listeners[event]) { this.listeners[event].forEach(callback => { callback(data); }); } } close() { if (this.requestTask) { this.requestTask.abort(); } } } // 使用方法 const eventSource = new EventSource('https://domain.com/test.php'); eventSource.addEventListener('message', res => { console.log('message', res) })
小程序什么时候能支持EventSource我想提一个需求,目前主流浏览器很多都支持HTML5 的EventSource(SSE),小程序什么时候能兼容这个API?相比需要单独搭建websocket服务,SSE有着先天的优势,特别在一些临时性的短场景中尤为轻便,例如A向B扫码,如果A扫码成功了,B就自动弹出提示,这样的场景用websocket显得大材小用。 或者上述场景有其他更好的解决方案么,求解答。
2023-11-08