Socket.io 实现订单实时跟踪与推送

在现今的网上购物时代,实时跟踪订单状态对于商户和顾客来说都是非常重要的。传统的订单追踪方式通常是通过轮询接口获取最新的订单状态,这种方式会造成频繁的网络请求,浪费服务器资源并且效率低下。而使用 Socket.io 技术实现订单实时跟踪和推送则可以避免以上问题。

什么是 Socket.io?

Socket.io 是一种实时通信库,可以在浏览器和服务器之间实现双向通信。它是基于 WebSocket 协议进行封装的,支持多种协议,包括 WebSocket、AJAX、长轮询和短轮询。使用 Socket.io 可以更加方便的在前端实现实时通信的功能。

实现订单实时跟踪与推送的流程

  • 后端实现订单状态更新的接口
  • 前端使用 Socket.io 实现订阅订单状态更新事件
  • 后端接收到订单状态更新请求后,向订阅了该订单状态更新事件的前端客户端发送订单状态更新事件

实现步骤

步骤一:服务端部分

在后端,首先需要建立订单更新事件,并且让订阅者能够接收到更新事件。以下是一个示例的 Node.js 服务端代码:

const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
  console.log('a user connected');

  socket.on('subscribeOrder', (orderId) => {
    console.log('subscribe order', orderId);
    socket.join(orderId);
  });

  socket.on('unsubscribeOrder', (orderId) => {
    console.log('unsubscribe order', orderId);
    socket.leave(orderId);
  });
  
  socket.on('disconnect', () => {
    console.log('user disconnected');
  });
});

app.post('/updateOrder', (req, res) => {
  const {orderId, status} = req.body;
  io.to(orderId).emit('orderUpdate', {
    orderId: orderId,
    status: status
  });
  res.send('Order updated');
});

http.listen(3000, () => {
  console.log('listening on *:3000');
});

服务端代码中,io 建立了一个 Socket.io 实例,用来处理客户端和服务端之间的通信。io.on('connection', (socket) => {...}) 表示每当有一个客户端与服务端连接之后,执行的回调函数,可以在该回调函数中处理监听和发送事件等操作。

socket.on('subscribeOrder', (orderId) => {...}) 用来订阅订单,socket.join(orderId) 表示加入到一个名为订单号 orderId 的房间中。socket.on('unsubscribeOrder', (orderId) => {...}) 用来取消订阅,socket.leave(orderId) 表示离开该房间。socket.on('disconnect', () => {...}) 表示当用户与服务端断开连接时的回调函数。

app.post('/updateOrder', (req, res) => {...}) 用来处理订单更新的请求。当服务端接收到一个订单更新请求时,需要向订阅该订单号的客户端发送订单更新事件,这点可以通过 io.to(orderId).emit('orderUpdate', {...}) 来实现。在这个例子中,客户端订阅订单号的房间,并在房间中收到订单更新事件。

步骤二:客户端部分

在前端中,需要使用 Socket.io 接收和发送事件。以下是一个示例的前端代码:

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <title>Socket.io Example</title>
</head>

<body>
  <script src="/socket.io/socket.io.js"></script>
  <script>
    const socket = io();

    function subscribeOrder(orderId) {
      socket.emit('subscribeOrder', orderId);
    }

    function unsubscribeOrder(orderId) {
      socket.emit('unsubscribeOrder', orderId);
    }

    socket.on('orderUpdate', (data) => {
      console.log('orderUpdate', data);
    });
  </script>
</body>

</html>

前端代码中,首先要引入 Socket.io 的客户端脚本 <script src="/socket.io/socket.io.js"></script>。接着 使用 const socket = io() 建立一个 Socket.io 连接实例。

socket.emit('subscribeOrder', orderId) 表示订阅给定的订单号 orderIdsocket.emit('unsubscribeOrder', orderId) 表示取消某订单号的订阅。socket.on('orderUpdate', (data) => {...}) 表示在订阅到订单更新事件时,执行的回调函数。

步骤三:将服务端部分和客户端部分结合起来

在实际应用中,客户端需要订阅的订单号可能来自于后端接口或者是用户的操作。在这里我们假设订阅的订单号来自于用户的操作,可以通过监听用户的点击事件来触发订阅行为。

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <title>Socket.io Example</title>
</head>

<body>
  <script src="/socket.io/socket.io.js"></script>
  <script>
    const socket = io();

    function subscribeOrder(orderId) {
      socket.emit('subscribeOrder', orderId);
    }

    function unsubscribeOrder(orderId) {
      socket.emit('unsubscribeOrder', orderId);
    }

    socket.on('orderUpdate', (data) => {
      console.log('orderUpdate', data);
    });

    const orderId = '123456';
    subscribeOrder(orderId);
  </script>
</body>

</html>

在这个例子中,当页面加载完成后,通过 subscribeOrder(orderId) 将订单号 123456 订阅到了服务器端。

总结

Socket.io 的使用可以极大地提高抓取数据的效率,同时减轻服务器等设备的压力。不仅如此,Socket.io 的可扩展性也极高,能够应对不同风险、需求变化,实现让程序员高控制,低耦合的程序设计。在真正的实际应用中,我们需要考虑诸多因素,对于每个实际的案例都需要探讨其具体的实现方案。无论如何,Socket.io 的便利性和弹性都是得到了业界及业内开发者的广泛认可。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b11f41add4f0e0ffa6c5f1