sse EventSource 浏览器兼容性 移动设备兼容性 sse单例模式 node搭建server EventSourcePolyfill配置url携带请求头信息 类似的长连接实时技术
SSE(Server-Sent Events)是一种在客户端和服务器之间实现单向实时通信的技术。它允许服务器向客户端推送数据,而无需客户端发起请求。
SSE(Server-Sent Events)在大多数现代浏览器中都有良好的支持,但仍然存在一些兼容性问题,特别是在旧版浏览器和移动设备上。下面是一些有关 SSE 在不同浏览器和移动设备上的兼容性问题的一般指导:
import { EventSourcePolyfill } from 'event-source-polyfill';
SSE自带客户端重启,在和服务器端失去连接,或者服务器端返回服务器端超时的时候会自动重连。不需要手动维护重连和重试。
-
浏览器兼容性:
- 支持良好的浏览器:Chrome、Firefox、Safari、Edge、Opera 等现代浏览器都对 SSE 提供了很好的支持。
- 旧版浏览器:Internet Explorer 不支持 SSE,因此在考虑 SSE 兼容性时需要注意。
-
移动设备兼容性:
- iOS:SSE 在 iOS Safari 上有良好的支持,适用于 iOS 4.2+ 的版本。
- Android:SSE 在 Android 上的兼容性取决于设备和浏览器。大多数现代 Android 设备上的 Chrome 浏览器都支持 SSE。但在旧版 Android 设备上或使用其他浏览器时,可能会遇到兼容性问题。
参考资料:SSE服务端消息推送:https://www.cnblogs.com/cxygg/p/17147296.html
if (typeof EventSource !== 'undefined') {
// 浏览器支持 SSE
// 可以在这里处理 SSE 的代码
} else {
// 浏览器不支持 SSE
// 可以提供替代方案或给出提示信息
//如果浏览器不支持 SSE,你可以在条件为假的分支中提供替代方案,如使用长轮询或 WebSocket 技术来实现实时数据推送,或者向用户显示一条提示信息,说明当前浏览器不支持 SSE
}
为了确保 SSE 在你的 H5 页面项目中的兼容性,你可以采取以下措施:
-
提供替代方案:考虑为不支持 SSE 的浏览器提供替代方案,例如使用长轮询(Long Polling)或 WebSocket 技术来实现实时数据推送。
-
浏览器嗅探:在项目中使用浏览器嗅探技术,检测用户所使用的浏览器和版本,并根据浏览器的兼容性情况选择合适的推送技术。
-
测试和适配:在开发过程中,使用不同的浏览器和移动设备进行测试,并根据测试结果进行适配和修复。确保 SSE 在目标浏览器和设备上正常运行。
需要注意的是,具体的兼容性问题可能会受到浏览器和设备版本的影响,因此在项目中最好进行兼容性测试,以确保 SSE 在目标浏览器和设备上的正常工作。
另外,可以使用一些 JavaScript 库或框架(如 EventSource Polyfill)(import { EventSourcePolyfill } from 'event-source-polyfill';
)来提供 SSE 的兼容性支持,以解决部分浏览器兼容性问题。这些库可以填补一些浏览器的实现差异,使 SSE 在更多浏览器和设备上能够正常工作。
在 Vue 3 中,你可以使用 SSE 来实现实时通信。下面是一个使用 SSE 的基本示例:
// 创建一个 SSE 连接
const eventSource = new EventSource('/sse-endpoint');
// 监听接收到的消息
eventSource.addEventListener('message', (event) => {
console.log('Received message:', event.data);
});
// 监听错误事件
eventSource.addEventListener('error', (error) => {
console.error('SSE error:', error);
});
在上面的代码中,/sse-endpoint
是服务器上 SSE 的端点,用于建立 SSE 连接。你需要在服务器端实现 SSE 的逻辑来处理客户端的连接和数据推送。
在服务器端,你需要设置 SSE 的响应头,并发送事件和数据给客户端。以下是一个 Node.js 的示例:
const http = require('http');
const server = http.createServer((req, res) => {
if (req.url === '/sse-endpoint') {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
// 每隔一秒发送一个事件和数据给客户端
setInterval(() => {
const message = 'Hello from server';
res.write(`data: ${message}\n\n`);
}, 1000);
}
});
server.listen(3000, () => {
console.log('SSE server is running on port 3000');
});
在上面的示例中,服务器通过每秒向客户端发送一个事件和数据来模拟实时通信。你可以根据自己的需求来调整实际的逻辑。
这是一个简单的 SSE 示例,它可以让你在 Vue 3 中实现实时通信。请注意,SSE 是一种单向通信技术,只允许服务器向客户端推送数据。如果你需要双向通信,你可能需要考虑使用其他技术,如 WebSockets。
希望对你有所帮助!如有其他问题,请随时提问。
sse-client.ts
export default class SSEClient {
source: EventSource;
element: HTMLElement;
constructor(url) {
this.source = new EventSource(url || 'http://127.0.0.1:8844/stream');
this.source.onopen = this.onOpen.bind(this);
this.source.onerror = this.onError.bind(this);
this.source.addEventListener('connecttime', this.onConnectTime.bind(this), false);
this.source.onmessage = this.onMessage.bind(this);
}
// eslint-disable-next-line class-methods-use-this
onOpen(event) {
console.log('onOpen-event :>> ', event);
}
// eslint-disable-next-line class-methods-use-this
onError(event) {
console.log('onError-event :>> ', event);
}
// eslint-disable-next-line class-methods-use-this
onConnectTime(event) {
console.log('onConnectTime-event :>> ', event);
}
// eslint-disable-next-line class-methods-use-this
onMessage(event) {
console.log('onMessage-event :>> ', event);
const localstore = useLocalStore();
localstore.setAdvertiseMsg([event.data]);
}
close() {
console.log('close :>> ');
this.source.close();
}
}
// 使用示例
// const sseClient = new SSEClient('http://127.0.0.1:8844/stream', 'example');
// 当你想关闭连接时,调用sseClient.close();
sse单例模式:
import { EventEmitter } from 'eventemitter3';
import { EventSourcePolyfill } from 'event-source-polyfill';
import { getChannelSync } from '../native';
import { useLocalStore } from '@/stores';
import { events } from '@/utils/eventBus';
import { ChannelMap, NormalErrorCode } from '@/utils/constants';
import { myTimeout } from '@/utils';
class H5SSE extends EventEmitter {
static instance: H5SSE;
sse: undefined | EventSource;
retryTimes = 0;
url = '';
init(url: string) {
this.url = url;
this.destroy();
const localStore = useLocalStore();
if (getChannelSync() === ChannelMap.Android || !localStore.userInfo?.token) return;
/** 处理浏览器多开 */
const bc = window?.BroadcastChannel ? new BroadcastChannel('cloud-h5') : null;
bc?.postMessage({ type: 'sse' });
this.sse = new EventSourcePolyfill(url, { headers: { Authorization: localStore.userInfo?.token }, heartbeatTimeout: 10 * 60 * 1000 });
this.sse!.addEventListener('message', e => {
try {
const data = JSON.parse(e.data);
events.trigger('SSE', data);
console.log('sse', data);
/** 登出消息,销毁SSE */
if (data.code === NormalErrorCode.LoginExpired) this.destroy();
} catch (error) {
console.log(error);
this.emit('error', error);
}
});
this.sse!.addEventListener('error', () => {
console.log('sse error:>> ');
if (this.retryTimes < 1) {
this.retryTimes++;
myTimeout(5 * 60 * 1000).then(() => {
this.init(this.url);
});
} else {
this.destroy();
}
});
if (bc)
bc.onmessage = e => {
if (e.data?.type === 'sse') {
this.destroy();
}
};
}
destroy() {
this.sse?.close();
this.sse = undefined;
}
static getInstance() {
if (!H5SSE.instance) {
H5SSE.instance = new H5SSE();
}
return H5SSE.instance;
}
}
export default H5SSE.getInstance();
server.js
const http = require('http');
http.createServer(function (req, res) {
const fileName = `.${req.url}`;
if (fileName === './stream') {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
'Access-Control-Allow-Origin': '*'
});
res.write('retry: 10000\n');
res.write('event: connecttime\n');
res.write(`data: ${new Date()}\n\n`);
res.write(`data: ${new Date()}\n\n`);
interval = setInterval(function () {
res.write(`data: ${new Date()}\n\n`);
}, 60000);
req.connection.addListener(
'close',
function () {
clearInterval(interval);
},
false
);
}
}).listen(8844, '127.0.0.1');
除了 SSE,还有其他一些长连接实时技术可以用于实现实时通信。以下是一些常见的选项:
-
WebSockets:WebSockets 是一种全双工通信协议,允许客户端和服务器之间建立持久性的连接。通过 WebSockets,客户端和服务器可以在任何时间点都能够相互发送消息。Vue 3 中可以使用 WebSocket API 或第三方库(如 Socket.io)来实现实时通信。
-
Comet:Comet 是一种基于 HTTP 的实时通信技术,它使用长轮询(Long Polling)或流(Streaming)方式来实现服务器向客户端推送数据。在长轮询中,客户端发送一个请求,服务器保持连接打开直到有新的数据可用,然后再响应给客户端。在流模式中,服务器会持续地向客户端发送数据流。Comet 技术在实现上相对复杂,但在一些特定场景下仍然有一定的应用。
-
Serverless Functions:Serverless Functions 允许你在云端运行小型函数,这些函数可以被触发并执行特定的操作。通过使用服务提供商如 AWS Lambda、Google Cloud Functions 或 Azure Functions,你可以创建一个函数来处理实时通信需求,例如接收客户端的请求并推送数据到客户端。
-
MQTT:MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅消息传输协议,常用于物联网(IoT)和实时通信场景。MQTT 协议支持异步、一对多的通信模式,可以实现高效的实时消息传递。
这些技术都可以用于实现实时通信,具体选择取决于你的应用场景和需求。对于 Vue 3,你可以使用相应的库或原生 API 来集成这些技术。请注意,这些技术可能需要在服务器端进行相应的设置和配置,以确保正确的通信流程。
希望这些信息对你有帮助!如有其他问题,请随时提问。