javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > 前端即时通讯

前端实现即时通讯的常用技术使用指南

作者:gnip

这篇文章主要为大家详细介绍了前端实现即时通讯的常用技术使用的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

概述

前面文章介绍了websocket,sse,轮询这些前后端通讯方案,本期做一期汇总和对比。

短轮询

短轮询(Short Polling)是一种通过定期向服务器发送请求来获取最新数据的实时通讯方法。与长轮询(Long Polling)不同,短轮询不会保持持久连接,而是在每次请求时向服务器询问是否有新数据。

以下是短轮询的基本工作流程:

在短轮询的实现中,客户端可以使用setInterval()函数周期性地发送请求,然后在收到响应后更新界面。以下是一个简单的示例:

function pollServerForUpdates() {
  setInterval(function() {
    fetch('http://example.com/update')
      .then(response => response.json())
      .then(data => {
        // 处理从服务器返回的数据
        console.log('收到新数据:', data);
      })
      .catch(error => {
        console.error('请求错误:', error);
      });
  }, 5000); // 每5秒发送一次请求
}

pollServerForUpdates();

在实际应用中,需要根据具体情况调整轮询的频率,并且考虑到服务器和网络的性能,以避免对系统造成过大的负担。

优缺点

优点:

缺点:

总的来说,短轮询适用于一些对实时性要求不高,且对服务器压力要求相对较低的场景。虽然实时性和效率不如长轮询或WebSocket,但在一些简单的应用中,短轮询可以是一种简单有效的实现方式。 在前端实现即时通讯,常用的技术包括短轮询,WebSocket和SSE。

长轮询

长轮询(Long Polling)是一种改进的轮询技术,它在某些方面优于传统的短轮询。

长轮询通过客户端向服务器发送一个持续连接的请求,在有新数据可用时立即返回响应,否则保持连接直到超时或者有新数据到达。

以下是长轮询的基本工作流程:

长轮询的优点是可以实现实时通讯的效果,并且相对于短轮询来说减少了不必要的 HTTP 请求次数,减少了网络流量和服务器负载。但是长轮询仍然存在一定的延迟,因为客户端需要等待服务器响应或者超时才能发送下一个请求。同时,长轮询需要服务器支持保持长连接,因此对服务器的资源消耗较大。

以下是使用 Node.js 实现的简单长轮询服务器和客户端的代码示例:

首先是服务器端的代码 (server.js):

const express = require('express');

const app = express();
const port = 3000;

let data = "Initial Data";

app.get('/data', (req, res) => {
  const timeout = 10; // 设置超时时间,单位为秒
  const startTime = new Date().getTime();

  const checkData = () => {
    // 检查数据是否发生变化或特定事件是否发生,这里假设直接使用一个全局变量 data 来模拟数据的变化
    if (data !== "Initial Data") {
      res.json({ data: data });
    } else if ((new Date().getTime() - startTime) > timeout * 1000) {
      res.json({ data: null }); // 如果超时,则返回空响应
    } else {
      setTimeout(checkData, 1000); // 等待一段时间后再次检查
    }
  };

  checkData();
});

app.post('/update', express.json(), (req, res) => {
  data = req.body.data;
  res.json({ message: "Data updated successfully" });
});

app.listen(port, () => {
  console.log(`Server is listening at http://localhost:${port}`);
});

接下来是客户端的代码 (client.js):

const fetch = require('node-fetch');

function longPolling() {
  setInterval(() => {
    fetch('http://localhost:3000/data')
      .then(response => response.json())
      .then(data => {
        if (data.data !== null) {
          console.log("Received updated data:", data.data);
        }
      })
      .catch(error => {
        console.error('Error:', error);
      });
  }, 1000); // 每秒重新发起请求
}

longPolling();

在这个示例中,服务器端使用 Express 框架创建了一个简单的 API,其中 /data 路由实现了长轮询的逻辑。客户端通过不断发送 GET 请求到 /data 路由来获取最新的数据。当数据发生变化时,服务器会立即返回响应。如果超过了设置的超时时间而没有新的数据可用,服务器会返回一个空响应,客户端会在收到空响应后立即重新发起请求。

优缺点

优点:

缺点:

综上所述,长轮询适用于需要实时通信但对延迟要求不是很高的场景,但在高并发和大规模部署的情况下,可能会带来一定的性能和资源开销。在选择长轮询还是其他实时通信技术时,需要根据具体的业务需求和技术环境进行权衡。

SSE

SSE(Server-Sent Events) 服务器推送事件,简称 SSE,是一种服务端实时主动向浏览器推送消息的技术。

SSEHTML5 中一个与通信相关的 API,主要由两部分组成:服务端与浏览器端的通信协议(HTTP 协议)及浏览器端可供 JavaScript 使用的 EventSource 对象。

SSE是一种用于实现服务器向客户端推送数据的技术,它允许服务器端实时地向客户端发送事件流。相比于长轮询,SSE 更加轻量级且易于实现,但也有一些限制。

SSE 协议非常简单,本质是浏览器发起 http 请求,服务器在收到请求后,返回状态与数据,并附带以下 headers:

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

下面是一个简单的使用 Node.js 实现 SSE 的示例代码:

const express = require('express');

const app = express();
const port = 3000;

let clients = [];

app.get('/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  const clientId = Date.now();
  clients.push({ id: clientId, res });

  // 发送一个初始化消息
  res.write(`data: Connected\n\n`);

  // 客户端断开连接时移除对应的客户端
  req.on('close', () => {
    clients = clients.filter(client => client.id !== clientId);
  });
});

// 路由用于发送数据到所有连接的客户端
app.post('/update', express.json(), (req, res) => {
  const newData = req.body.data;

  clients.forEach(client => {
    client.res.write(`data: ${JSON.stringify({ data: newData })}\n\n`);
  });

  res.json({ message: "Data sent successfully" });
});

app.listen(port, () => {
  console.log(`Server is listening at http://localhost:${port}`);
});

在这个示例中,客户端通过向 /events 路由发送 GET 请求来订阅服务器端的事件流。服务器端会维护一个客户端列表,当有新数据需要推送时,会遍历客户端列表将数据发送给所有客户端。

客户端可以使用 JavaScript 来监听事件流:

const eventSource = new EventSource('http://localhost:3000/events');

eventSource.onmessage = function(event) {
  const data = JSON.parse(event.data);
  console.log("Received updated data:", data.data);
};

eventSource.onerror = function(error) {
  console.error('Error:', error);
};

优缺点

优点:

但是,SSE 也有一些限制:

总的来说,SSE 适合那些需要实时推送数据且对双向通信要求不高的应用场景,例如实时通知、实时数据更新等。在选择实时通信技术时,开发人员应根据具体的需求和场景来选择合适的技术。

应用场景

兼容性

Websocket

Websocket 是一种在客户端和服务器之间实现双向通信的技术,它通过一个持久连接在客户端和服务器之间建立实时、高效的通信机制。

相比传统的 HTTP 请求,它能够提供更低的延迟和更高的效率,使得实时通讯成为可能。

下面是使用 JavaScript 的简单示例:

服务端代码

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws) {
  console.log('A client connected');

  ws.on('message', function incoming(message) {
    console.log('Received message:', message);

    // 发送数据给所有连接的客户端
    wss.clients.forEach(function each(client) {
      if (client !== ws && client.readyState === WebSocket.OPEN) {
        client.send(message);
      }
    });
  });

  ws.on('close', function close() {
    console.log('Client disconnected');
  });
});

客户端代码

const ws = new WebSocket('ws://localhost:8080');

ws.onopen = function() {
  console.log('Connected to the server');
};

ws.onmessage = function(event) {
  console.log('Received message:', event.data);
};

ws.onclose = function() {
  console.log('Disconnected from the server');
};

// 发送数据给服务器
ws.send('Hello, server!');

特点

优缺点

优点包括:

然而,Websocket 也有一些缺点:

总的来说,Websocket 是一种功能强大、实时性高的通信技术,适用于需要实时双向通信的应用场景。在选择实时通信技术时,开发人员可以根据需求和情况权衡各种通信技术的优缺点来选择最适合的技术。

应用场景

WebSocket 适用于需要实时双向通信的各种应用场景,包括但不限于:

总的来说,Websocket 在需要实时双向通信的各种应用场景中都有广泛的应用前景,特别是对于那些需要及时更新数据、实时交互的场景来说,是一种非常值得选择的通信技术。

兼容性

与SSE对比

好的,下面是一个比较 WebSocket 和 Server-Sent Events (SSE) 的表格:

特性WebSocketServer-Sent Events (SSE)
通信方向双向通信单向通信
协议基于 TCP基于 HTTP
使用难度相对复杂轻量级,使用简单
实时性实时通信,适用于需要即时更新的应用场景实时推送,适用于只需要服务器向客户端推送数据的简单应用场景
延迟通常较低,由于建立了持久性连接可能较高,受限于 HTTP 请求-响应模式
数据格式任意类型的数据只能传输文本数据
自动重连不支持,需要客户端手动重连支持,客户端断开连接时会自动尝试重新连接
连接个数可同时支持大量连接连接数 HTTP/1.1 6 个,HTTP/2 可协商(默认 100)
应用场景实时双向通信、即时更新的应用只需要服务器向客户端推送数据的简单应用

到此这篇关于前端实现即时通讯的常用技术使用指南的文章就介绍到这了,更多相关前端即时通讯内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文