Server-Sent Events (SSE) Koa2 & Nginx & React 实践

在现代 Web 应用中,实时数据传输变得越来越重要。Server-Sent Events (SSE) 是一种轻量级的技术,允许服务器向客户端主动发送更新。本文将详细介绍如何在 Koa2 框架下实现 SSE,并配置 Nginx 以支持 HTTP 和 HTTPS 协议。同时,我们还将展示如何在 React 前端使用 axios 来接收这些事件。

什么是 Server-Sent Events?

Server-Sent Events (SSE) 是一种基于 HTTP 的实时数据传输技术。与 WebSocket 不同,SSE 仅支持单向通信,即服务器到客户端。这使得 SSE 在某些场景下更为简单和高效,特别是当只需要从服务器推送数据到客户端时。

在 Koa2 中实现 SSE

首先,我们需要创建一个 Koa2 应用,并设置一个路由来处理 SSE 连接。

1. 创建 Koa2 应用

安装必要的依赖:

bash 复制代码
npm init -y
npm install koa koa-router

创建 app.js 文件,并设置基本的 Koa2 应用结构:

javascript 复制代码
const Koa = require('koa');
const Router = require('koa-router');

const app = new Koa();
const router = new Router();

// SSE 路由处理
router.get('/events', async (ctx, next) => {
    // SSE 相关逻辑将在这里实现
});

app.use(router.routes()).use(router.allowedMethods());

app.listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
});

2. 实现 SSE 逻辑

/events 路由中,我们需要设置响应头以支持 SSE,并发送实时数据:

javascript 复制代码
router.get('/events', async (ctx, next) => {
    // 设置响应头
    ctx.set({
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    });

    // 发送数据
    const sendEvent = (data) => {
        ctx.res.write(`data: ${JSON.stringify(data)}\n\n`);
    };

    // 模拟实时数据发送
    const interval = setInterval(() => {
        const message = { time: new Date().toLocaleTimeString() };
        sendEvent(message);
    }, 1000);

    // 当客户端关闭连接时清除定时器
    ctx.req.on('close', () => {
        clearInterval(interval);
    });
});

配置 Nginx 以支持 SSE

为了使 SSE 同时支持 HTTP 和 HTTPS,我们需要在 Nginx 中进行相应的配置。

假设你已经安装了 Nginx,并且有一个域名 example.com 指向你的服务器。

1. 修改 Nginx 配置文件

编辑你的 Nginx 配置文件(通常位于 /etc/nginx/sites-available/example.com),添加以下内容:

nginx 复制代码
server {
    listen 80;
    listen [::]:80;
    server_name example.com;
    
    # location根据实际来
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Connection '';
        proxy_buffering off;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name example.com;

    # SSL 证书配置(省略)

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Connection '';
        proxy_buffering off;
    }
}

这里的关键是设置 proxy_http_version1.1,并将 Connection 头设置为空字符串,以及关闭 proxy_buffering

2. 重启 Nginx

bash 复制代码
sudo systemctl restart nginx

在 React 前端使用 axios 接收 SSE

现在我们来创建一个简单的 React 应用来接收服务器发送的事件。

1. 创建 React 应用

使用 create-react-app 创建一个新的 React 应用:

bash 复制代码
npx create-react-app sse-client
cd sse-client
npm start

2. 使用 axios 接收事件

安装 axios:

bash 复制代码
npm install axios

修改 src/App.js,使用 axios 接收 SSE:

javascript 复制代码
import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
    const [events, setEvents] = useState([]);

    useEffect(() => {
        const eventSource = axios.get('http://example.com/events', {
            responseType: 'stream'
        });

        eventSource.then(response => {
            response.data.on('data', (event) => {
                const parsedEvent = JSON.parse(event.data);
                setEvents((prevEvents) => [...prevEvents, parsedEvent]);
            });
        });

        return () => {
            eventSource.cancel();
        };
    }, []);

    return (
        <div className="App">
            <h1>Server-Sent Events</h1>
            <ul>
                {events.map((event, index) => (
                    <li key={index}>{event.time}</li>
                ))}
            </ul>
        </div>
    );
}

export default App;

总结

通过本文,我们学习了如何在 Koa2 应用中实现 Server-Sent Events,配置 Nginx 以支持 HTTP 和 HTTPS 协议,并在 React 前端使用 axios 接收这些事件。SSE 提供了一种轻量级的方法来实现服务器到客户端的实时数据传输,适用于许多实时应用场景。希望本文能帮助你更好地理解和使用 SSE。

相关推荐
阳树阳树8 分钟前
signal-新的状态管理模式
前端·javascript
程序员鱼皮29 分钟前
2025最新 Java 面经:美团后端面试真实复盘,附答案模板,速速收藏!
java·后端·面试
有来技术44 分钟前
从0到1手撸企业级权限系统:基于 youlai-boot(开源) + Java17 + Spring Boot 3 完整实战
java·spring boot·后端
陈明勇1 小时前
一文掌握 MCP 上下文协议:从理论到实践
人工智能·后端·mcp
__不想说话__1 小时前
面试官问我React组件和state的关系,我指了指路口的红绿灯…
前端·javascript·react.js
SimonKing1 小时前
因为不知道条件注解@Conditional,错失15K的Offer!
java·后端·架构
橘猫云计算机设计1 小时前
基于springboot微信小程序的旅游攻略系统(源码+lw+部署文档+讲解),源码可白嫖!
java·spring boot·后端·微信小程序·毕业设计·旅游
雷渊2 小时前
spring-IoC容器启动流程源码分析
java·后端·面试
用户3315489111072 小时前
一招搞定Java线程池炸弹,系统吞吐量暴增10倍!
java·后端