Skip to content

网络服务器插件

网络服务器插件提供 HTTP 和 WebSocket 端点,将 JSON-RPC 请求转发到 json_rpc 插件。它包含以 method + params(不含 id)为键的响应缓存(每个应用的区块使其失效),以及用于并发请求处理的线程池。

源码: plugins/webserver/webserver_plugin.cpp


依赖

json_rpc::plugin

配置

选项默认值描述
webserver-http-endpointHTTP 监听地址,例如 0.0.0.0:8090
webserver-ws-endpointWebSocket 监听地址,例如 0.0.0.0:8091
webserver-thread-pool-size256处理 HTTP 和 WebSocket 请求的工作线程数。
webserver-cache-enabledtrue启用响应缓存。
webserver-cache-size10000缓存响应的最大数量。达到此限制时整个缓存被驱逐。

插件至少需要设置 webserver-http-endpointwebserver-ws-endpoint 之一才能工作。两者可同时启用。


最小 config.ini

ini
plugin = webserver

webserver-http-endpoint = 0.0.0.0:8090
webserver-ws-endpoint   = 0.0.0.0:8091

响应缓存

缓存什么

每个只读 JSON-RPC 响应都有资格被缓存。缓存键是 method + params 的 SHA-256 哈希 — 故意排除 id,这样轮换请求 id 就无法绕过缓存。

永不缓存

命名空间原因
network_broadcast_api.*改变状态(交易/区块广播)
debug_node.*改变状态的调试操作
格式错误/无法解析的请求无法可靠地派生键

批量请求(JSON 数组)被视为单个原子缓存条目,以完整数组哈希为键。

失效

缓存在每个应用的区块上被清除。响应永远不会超过一个区块间隔(3 秒)地服务过时内容。

禁用缓存

ini
webserver-cache-enabled = false

对于服务高延迟敏感或实时客户端(3 秒缓存窗口不可接受)的节点,请禁用。


线程池

HTTP 和 WebSocket 服务器各自运行在专用的 io_service 实例上。传入请求被分派到 webserver-thread-pool-size 个工作线程的共享线程池。

大小指导:

  • 混合读写流量的公共 API 节点:256(默认)对大多数工作负载足够。
  • 高吞吐量节点:增加到 512 或更多。监控 CPU 饱和 — 线程数超过 CPU 核心数对 CPU 密集操作没有帮助。
  • 开发/本地节点:48 足够。

WebSocket 订阅

WebSocket 客户端可以注册回调:

方法描述
database_api.set_block_applied_callback每个应用的区块触发,带区块头
database_api.set_pending_transaction_callback交易进入待处理池时触发
database_api.cancel_all_subscriptions取消所有回调的订阅

订阅需要持久的 WebSocket 连接。普通 HTTP 不支持。


安全性

  • 绑定到 localhost127.0.0.1)并使用反向代理(nginx/Caddy)进行公共暴露。绑定到 0.0.0.0 会将 RPC 直接暴露给网络。
  • 插件没有内置身份验证或速率限制。在反向代理层应用这些。
  • 变更方法(network_broadcast_apidebug_node)在设计上受到保护,不受缓存中毒影响,但它们仍可从任何连接的客户端调用 — 如需要,在网络级别限制访问。

故障排除

症状检查
启动时端口已被使用另一个进程绑定到配置的端口;更改端口或终止冲突进程
高内存使用减少 webserver-cache-size 或禁用缓存
负载下响应慢增加 webserver-thread-pool-size;检查 CPU 饱和
WebSocket 订阅未触发订阅需要 WebSocket 连接,而非 HTTP
过时响应如果 webserver-cache-enabled = true,响应在一个区块间隔内(~3 秒)是新鲜的;对于实时使用请禁用缓存

通过 HTTPS 公开 API(nginx + certbot)

将节点绑定到本地地址,再用 nginx 作为前端代理。运行 certbot --nginx 时,certbot 会自动修改配置。

1. 节点 config.ini

ini
webserver-http-endpoint = 127.0.0.1:8090
webserver-ws-endpoint   = 127.0.0.1:8091

2. /etc/nginx/sites-enabled/viz-node

nginx
server {
    listen 80;
    server_name your.domain.com;  # ← 替换为您的域名

    # certbot 的 ACME challenge
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        # CORS — 允许任意来源(公开 API)
        add_header 'Access-Control-Allow-Origin'   '*'                                                                                         always;
        add_header 'Access-Control-Allow-Methods'  'GET, POST, PUT, DELETE, PATCH, OPTIONS'                                                    always;
        add_header 'Access-Control-Allow-Headers'  'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'                                                              always;

        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin'  '*'                                                                                         always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS'                                                    always;
            add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
            add_header 'Access-Control-Max-Age'       1728000;
            add_header 'Content-Type'                 'text/plain charset=UTF-8';
            add_header 'Content-Length'               0;
            return 204;
        }

        proxy_pass http://127.0.0.1:8090;
        proxy_http_version 1.1;

        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_connect_timeout 60s;
        proxy_send_timeout    60s;
        proxy_read_timeout    60s;
    }
}

3. 获取 TLS 证书

bash
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d your.domain.com

certbot 会自动添加 listen 443 ssl 块、ssl_certificate 指令以及 HTTP→HTTPS 重定向。完成后,节点可通过 https://your.domain.com 访问。

HTTPS 上的 WebSocket

WebSocket 客户端需要转发 Upgrade 头。添加单独的 location(或在 8091 端口上新增 server 块):

nginx
location /ws {
    proxy_pass http://127.0.0.1:8091;
    proxy_http_version 1.1;
    proxy_set_header Upgrade    $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host       $host;
    proxy_read_timeout 3600s;
}

参见:插件概述Database APIJSON-RPC API