马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
短轮询、长轮询与长连接详解及 Axios 代码实现
1. 短轮询(Short Polling)
原理
客户端通过 定时器(如每 5 秒) 主动向服务器发送请求,无论数据是否有更新。
特点:
• ✅ 实现简单,兼容所有 HTTP 服务
• ❌ 频繁无效请求,资源浪费严重
• ❌ 实时性差(依靠轮询间隔)
适用场景:静态数据低频更新(如气候预报、设置拉取)。
- // 短轮询代码(Axios)
- let isPollingActive = true;
- const startShortPolling = async () => {
- while (isPollingActive) {
- try {
- const response = await axios.get('/api/short-poll');
- console.log('短轮询数据:', response.data);
- await new Promise(resolve => setTimeout(resolve, 5000)); // 5秒间隔
- } catch (error) {
- console.error('短轮询失败:', error);
- isPollingActive = false; // 出错时停止
- }
- }
- };
- // 启动轮询
- startShortPolling();
- // 停止轮询
- const stopShortPolling = () => {
- isPollingActive = false;
- };
复制代码 2. 长轮询(Long Polling)
原理
客户端发送请求后,服务器会 挂起连接直到数据更新或超时(如 30 秒)。客户端收到响应后立即重新发起请求。
特点:
• ✅ 减少无效请求,实时性优于短轮询
• ❌ 需要服务器支持长时挂起
• ❌ 客户端需处置惩罚超时和重连
适用场景:实时谈天、订单状态跟踪等中等实时性需求。
- // 长轮询代码(Axios + AbortController)
- const abortController = new AbortController();
- const startLongPolling = async () => {
- try {
- const response = await axios.get('/api/long-poll', {
- signal: abortController.signal, // 绑定中断控制器
- timeout: 30000 // 30秒超时
- });
- console.log('长轮询数据:', response.data);
- startLongPolling(); // 立即发起下一次请求
- } catch (error) {
- if (axios.isCancel(error)) {
- console.log('长轮询被手动终止');
- } else {
- console.error('长轮询错误:', error);
- setTimeout(startLongPolling, 1000); // 1秒后重试
- }
- }
- };
- // 启动长轮询
- startLongPolling();
- // 终止长轮询
- const stopLongPolling = () => {
- abortController.abort();
- };
复制代码 3. 长连接(Long Connection)
原理
基于 WebSocket(双向通信) 或 SSE(Server-Sent Events,单向推送) 的持久连接,服务器可主动推送数据。
特点:
• ✅ 实时性最高,无频繁请求开销
• ❌ 需要协媾和服务器支持(如 WebSocket 需 ws://)
• ❌ 实现复杂度较高
3.1 WebSocket(双向通信)
- // 浏览器原生 API(Axios 不适用)
- const socket = new WebSocket('wss://your-websocket-server');
- socket.addEventListener('open', () => {
- socket.send('连接已建立');
- });
- socket.addEventListener('message', (event) => {
- console.log('收到消息:', event.data);
- });
复制代码 3.2 SSE(单向推送)
- // 浏览器原生 API(Axios 不适用)
- const eventSource = new EventSource('/api/sse');
- eventSource.onmessage = (event) => {
- console.log('SSE 数据:', event.data);
- };
- eventSource.onerror = () => {
- console.error('SSE 连接异常');
- };
复制代码 对比总结
方式实时性资源斲丧实现复杂度协议依靠短轮询低高(频繁请求)简单HTTP 1.1+长轮询中中(减少请求)中等需服务器支持挂起WebSocket高低(持久连接)复杂WebSocket 协议SSE高低(单向推送)中等HTTP/2+ 实际开发发起
- 短轮询
• 利用 setTimeout 或 setInterval 控制频率
• 添加请求锁(如 isPollingActive)避免并发冲突
- 长轮询
• 利用 AbortController 精准控制请求中断
• 添加重试机制(如指数退避 setTimeout(retry, 1000 * 2^attempt))
- 长连接
• 高频双向通信选 WebSocket(如在线游戏)
• 单向推送选 SSE(如新闻实时播报)
• 利用 Socket.io 库简化 WebSocket 开发
- // 长轮询重试逻辑示例(指数退避)
- let retryCount = 0;
- const MAX_RETRIES = 5;
- const fetchWithRetry = async () => {
- try {
- const response = await axios.get('/api/data');
- retryCount = 0; // 重置重试计数器
- return response.data;
- } catch (error) {
- if (retryCount < MAX_RETRIES) {
- retryCount++;
- await new Promise(resolve =>
- setTimeout(resolve, 1000 * Math.pow(2, retryCount))
- );
- return fetchWithRetry();
- } else {
- throw new Error('超过最大重试次数');
- }
- }
- };
复制代码 注意事项
• 服务端适配:长轮询需服务器支持挂起请求(如 Node.js 的 keep-alive)
• 性能监控:短轮询频繁请求大概触发服务器限流
• 欣赏器兼容性:SSE 不支持 IE,WebSocket 需今世欣赏器
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |