# 如何修复 Discourse 论坛的 /message-bus 或长轮询错误

**URL:** https://meta.discourse.org/t/how-to-fix-discourse-forum-message-bus-or-long-polling-errors/383861
**Category:** Self-hosting
**Tags:** chat
**Created:** [2025年九月24日 11:07 UTC](https://meta.discourse.org/t/how-to-fix-discourse-forum-message-bus-or-long-polling-errors/383861 "2025-09-24T11:07:41Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![qingfeng1024](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/qingfeng1024/32/495412_2.png) [@qingfeng1024](https://meta.discourse.org/u/qingfeng1024)
#### Post date: [2025年九月24日 11:07 UTC](https://meta.discourse.org/t/how-to-fix-discourse-forum-message-bus-or-long-polling-errors/383861/1 "2025-09-24T11:07:41Z")

</div>

## **1. 問題**

当 Discourse 配置了 CDN 时，会发生一个常见错误：

```plaintext
/message-bus/204234de907442e8b77e153786a58e5b/poll
连接失败 / 超时 / 状态码异常

```

**影响：**

- **通知失败** ：红点（新私信/回复）不再实时显示；更新可能延迟或根本不出现。

- **实时更新中断** ：新帖子/点赞/投票不会自动刷新；需要手动刷新页面。

- **用户体验下降** ：“连接丢失”消息出现；交互延迟。

- **服务器负载增加** ：前端不断重试轮询，给源站增加压力。

原因：Discourse 使用长轮询来维护实时通信。许多 CDN 会强制执行默认缓存、缩短超时时间、进行挑战/防火墙检查或对长连接进行缓冲，从而导致中断或缓存响应，破坏实时行为。

* * *

## **2. 通用方法（稳定性优先）**

- **域名分离** ：通过专用域名将 MessageBus 路由到源站。

- **反向代理（Nginx）层** ：

- **CDN 层（如果仍在使用）** ：

* * *

## **3. 实现步骤**

### **1) 配置 Discourse 环境变量**

编辑 app.yml（通常位于 /var/discourse/containers/app.yml），在 env:: 下添加/修改：

```yaml
env:
  DISCOURSE_MESSAGE_BUS_REDIS_ENABLED: true
  DISCOURSE_LONG_POLLING_BASE_URL: "https://messagebus.example.com"

```

应用更改（官方部署）：

```bash
cd /var/discourse
./launcher rebuild app

```

说明：

- DISCOURSE\_LONG\_POLLING\_BASE\_URL 告诉前端使用 MessageBus 域名。
- REDIS\_ENABLED 应保持启用。

* * *

### **2) DNS 和证书**

- 将 [messagebus.example.com](http://messagebus.example.com) 直接指向源站，绕过 CDN（最佳实践）。
- 为该域名设置有效的 HTTPS 证书。

* * *

### **3) Nginx（MessageBus 域名）反向代理和 CORS**

在 [messagebus.example.com](http://messagebus.example.com) 的 server 块中添加或更新以下内容：

```nginx
location ^~ /message-bus {

    # (1) 处理 CORS 预检 (OPTIONS)
    if ($request_method = OPTIONS) {
        add_header 'Access-Control-Allow-Origin' 'https://bbs.example.com' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,discourse-deferred-track-view-topic-id,discourse-present,discourse-track-view,discourse-deferred-track-view,x-silence-logger,dont-chunk,x-shared-session-key' always;
        add_header 'Access-Control-Max-Age' 1728000 always;
        add_header 'Content-Type' 'text/plain; charset=UTF-8' always;
        add_header 'Content-Length' 0 always;
        return 204;
    }

    # (2) 反向代理到 Discourse
    proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
    # 或者，如果是独立部署：
    # proxy_pass http://127.0.0.1:3000;

    # (3) 防止重复的 CORS 标头
    proxy_hide_header Access-Control-Allow-Origin;
    proxy_hide_header Access-Control-Allow-Credentials;
    proxy_hide_header Access-Control-Allow-Methods;
    proxy_hide_header Access-Control-Allow-Headers;
    proxy_hide_header Access-Control-Max-Age;

    # (4) 普通请求的 CORS
    add_header 'Access-Control-Allow-Origin' 'https://bbs.example.com' always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,discourse-deferred-track-view-topic-id,discourse-present,discourse-track-view,discourse-deferred-track-view,x-silence-logger,dont-chunk,x-shared-session-key' always;

    # (5) 长轮询稳定性设置
    proxy_read_timeout 120s;
    proxy_send_timeout 120s;
    proxy_connect_timeout 60s;

    proxy_buffering off;
    add_header X-Accel-Buffering no always;

    # (6) 明确禁止缓存
    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
}

```

⚠ 安全提示：如果使用 Access-Control-Allow-Credentials: true，Origin 不能是 \*；它必须与论坛的确切域名匹配。

* * *

### **4) CDN 规则（如果论坛仍通过 CDN）**

推荐：为以下路径设置_无缓存 + 延长超时时间 + 绕过 WAF/速率限制_：

正则表达式示例：

```regex
^/(session|login|message-bus|admin|u|users)(/|$)

```

策略：

- 无浏览器/节点缓存（no-store/no-cache）。
- 上游/读取/空闲超时时间 ≥ 60–120 秒。
- 禁用 JS 挑战/验证码/机器人管理。
- 传递 cookie 和 Authorization 标头（不要剥离）。

* * *

## **4. 如何验证成功**

### **1) 浏览器开发者工具 → 网络**

在论坛页面上：

- 观察 /message-bus/…/poll。
- 请求应“挂起”约 20–60 秒，然后返回 200（可能为空）。
- 下一个轮询请求会自动触发。

检查响应标头：

- Access-Control-Allow-Origin: [https://bbs.example.com](https://bbs.example.com)
- Cache-Control: no-store
- 无 Age、X-Cache: HIT 或 CF-Cache-Status: HIT（表示未缓存）。

常见问题：

- 固定的 10 秒/30 秒错误 → 边缘/源站超时。
- 504/524：超时。
- 499：中间层断开连接。
- 403/401：WAF/身份验证阻止。

* * *

### **2) 命令行快速探测（可选）**

检查连接性和标头（非完整轮询）：

```bash
curl -I "https://messagebus.example.com/message-bus/health-check" \
  -H "Origin: https://bbs.example.com"

```

注意：实际轮询需要会话上下文；这仅验证 CORS 和连接性。
