
音视频【免费下载链接】foundation-sunshineSunshine fork: an enhanced sunshine, a self-hosted game streaming host for Moonlight with HDR10/HDR Vivid, virtual displays, advanced audio, optimized encoders, and a modern control panel.项目地址https://gitcode.com/gh_mirrors/sunshine5/foundation-sunshine点击查看免费下载本篇技术指南以 Foundation SunshineSunshine fork仓库中的 Webhook 实现设计文档 为核心系统拆解这套可选通知模块的完整设计它如何把配对、应用与会话事件异步投递到用户配置的 HTTP/HTTPS 接收端如何在sunshine.conf之外独立持久化配置并热生效以及投递队列、重试策略、TLS 证书校验与故障隔离如何在源码层落地。读完本文你将能够直接上手配置 Webhook、调用其 Web API 进行读取/保存/测试并理解接收端应如何按 delivery ID 去重、如何解读 payload 与重试语义从而把该模块安全地集成进自己的自动化监控或通知管道。1. 功能定位与设计边界Webhook 是 Foundation Sunshine 的可选通知模块用于把三类事件——配对pairing、应用app和会话session——异步发送到用户配置的 HTTP 或 HTTPS 接收地址典型场景是接入企业 IM、监控系统或自建通知服务。它沿用了项目现有的 C、Boost.Asio、Simple-Web-Server、libcurl URL API、nlohmann/json、Vue 3、vue-i18n 与请求工具没有引入任何新的网络框架。设计文档为该模块划定了六条明确边界决定了后续所有实现细节故障不扩散Webhook 的任何故障都不能终止或阻塞 Sunshine 主流程独立配置与热生效配置独立于sunshine.conf保存并支持运行时热切换证书策略默认严格是否跳过 HTTPS 证书校验由用户自行决定默认严格校验投递资源有界事件投递采用有界队列、有限并发和有限重试重复投递可识别接收端应按 delivery ID 处理可能的重复投递日志与 API 不泄露敏感信息不得泄露 Webhook URL、查询参数、payload、凭据或本地路径。这些边界在源码中表现为src/webhook/webhook.h里明确的常量契约如MIN_TIMEOUT1000ms、MAX_TIMEOUT15000ms、DEFAULT_TIMEOUT5000ms、MAX_URL_SIZE4096、EVENT_TYPE_COUNT7、MAX_TEST_RETRIES3以及 src/webhook/webhook.cpp 中的运行上限常量MAX_PENDING_DELIVERIES64、MAX_IN_FLIGHT_DELIVERIES2、MAX_EVENTS_PER_MINUTE20、MAX_RESPONSE_BYTES16*1024。2. 模块结构与技术栈Webhook 功能被拆分为多个职责单一的文件模块划分如下模块职责src/webhook/webhook.cpp活动配置快照、事件过滤、异步队列、并发投递、重试与生命周期src/webhook/webhook_auth.cpp独立配置路径、严格 JSON 解析、备份和原子写入src/webhook/webhook_api.cpp已认证的配置读取、配置保存和测试投递业务处理src/webhook/webhook_format.cpp事件 payload、时间戳、UTF-8 截断和测试 payloadsrc/webhook/webhook_client_base.hHTTP/HTTPS 共用的响应头专用异步读取src/webhook/webhook_httpclient.*禁止隐式重连的 HTTP Clientsrc/webhook/webhook_httpsclient.*TLS 配置、证书校验和禁止隐式重连的 HTTPS Clientsrc/confighttp.cpp在现有 Web UI HTTPS 服务中注册并认证 Webhook 路由WebhookCard.vue网络页中的 Webhook 卡片、懒加载弹窗、测试和独立保存webhookService.jsWeb UI 的同源 Webhook API 调用webhookConfig.js前后端 DTO、秒/毫秒转换和事件编号规范化几个值得注意的实现细节路由注册位于 src/confighttp.cpp三个路由分别是GET /api/webhook/config、POST /api/webhook/config、POST /api/webhook/test与文档第 4 节完全对应。事件触发点同样在confighttp.cpp配对成功/失败时构造webhook::event_t并调用webhook::send_event_async见 src/confighttp.cpp说明 Webhook 是异步的“fire-and-forget”式调用。HTTP/HTTPS 客户端基于 Simple-Web-Server 的ClientBase派生WebhookHttpClient显式关闭了attempt_reconnectwebhook_httpclient.cpp并拒绝代理配置proxy_server非空直接返回operation_not_supportedWebhookHttpsClient则持有独立的boost::asio::ssl::context_用于证书策略控制。3. 配置模型3.1 配置位置有效配置文件位于实际选用的sunshine.conf同目录config/ ├── sunshine.conf └── webhook_auth.json要点配置文件名固定为webhook_auth.json不是credentials/webhook_auth.jsonsunshine.conf中可能残留的旧 Webhook 字段不迁移、不读取、不回退使用只按普通未知配置参与/api/config的通用读写路径解析由 src/webhook/webhook_auth.h 中的path_for()实现它接收选中的sunshine.conf路径并返回同目录下的webhook_auth.json备份文件由backup_path_for()解析为webhook_auth.json.bak。3.2 文件格式与字段规则配置文件必须是只包含五个字段的 JSON 对象{ webhook_enabled: false, webhook_events: 0,1,2,3,4,5,6, webhook_skip_ssl_verify: false, webhook_timeout: 5000, webhook_url: }字段规则字段类型规则webhook_enabledboolean是否发送生产事件webhook_urlstringHTTP/HTTPS URL最大 4096 字节webhook_skip_ssl_verifyboolean仅影响 HTTPS默认falsewebhook_timeoutinteger毫秒范围 1000–15000默认 5000webhook_eventsstring0..6的逗号列表-1表示空选加载行为由webhook_auth.cpp的load()实现文件缺失使用关闭、空 URL、严格证书校验、5000ms、事件全选的默认配置且不输出配置错误返回MISSING状态文件损坏文件存在但为空、过大、JSON 损坏、字段缺失、字段多余或类型不正确判定为损坏返回INVALID状态Webhook 被禁用Sunshine 继续运行事件列表解析与序列化分别由parse_event_ids()/serialize_event_ids()完成空列表序列化为-1这与前端 webhookConfig.js 的serializeWebhookEventIds空列表返回-1完全一致。3.3 保存与热生效配置保存按以下顺序串行执行校验并规范化全部字段完整分配一份尚未对事件入口可见的不可变配置快照对应webhook.h中 move-only 的prepared_configuration_t只有prepare_configuration()能创建合法 token调用方可读取用于持久化但无法修改或伪造已提交数据把新 JSON 写入同目录临时文件若旧配置存在将旧文件原始字节备份为webhook_auth.json.bak原子替换主配置文件磁盘保存成功后原子发布新的活动配置快照commit_configuration()。关键语义备份或主文件写入失败时活动配置保持旧值备份文件只用于人工恢复启动时不会自动读取已经排队或正在重试的投递保留其接收事件时的配置快照保存后产生的新事件立即使用新配置webhook_auth.json、临时文件和备份文件均被 Git 忽略POSIX 平台会在写入敏感内容之前把临时文件权限限制为文件所有者读写。从源码看准备与提交是分离的两步prepare_configuration→commit_configuration文档注释明确说明准备阶段不改变事件产生者可见的配置因此持久化失败也不会暴露未保存的接收地址提交阶段因预分配了全部动态存储不产生新分配。4. Web APIWebhook API 注册在现有 Web UI HTTPS 服务中复用相同认证逻辑。JSON 响应统一设置安全响应头Cache-Control: no-storeContent-Type: application/jsonX-Content-Type-Options: nosniffX-Frame-Options: DENY请求正文上限为 64 KiB。错误响应使用稳定的通用信息不回显 URL、文件路径或文件内容。4.1 读取配置GET /api/webhook/config打开 Webhook 卡片弹窗时异步调用。配置页面初始加载和/api/config不读取 Webhook 独立文件。成功响应{ status: true, webhook_enabled: false, webhook_events: 0,1,2,3,4,5,6, webhook_skip_ssl_verify: false, webhook_timeout: 5000, webhook_url: }配置文件损坏或无法读取时返回通用 500并使用稳定错误码webhook_config_invalid供前端显示简短的清理配置文件提示不显示本地绝对路径。4.2 保存配置POST /api/webhook/config Content-Type: application/json请求必须精确包含五个配置字段。保存成功后立即热应用不依赖网络页外层的保存或应用并生效按钮。成功响应{ status: true, runtime_active: true }statustrue表示配置已经持久化并发布runtime_activefalse表示配置已保存但 Webhook 运行时当前无法启动前端会提示通知服务不可用Sunshine 仍继续运行保存只校验结构、范围和 URL 语义不要求远端接收地址当前可达连通性通过独立测试接口检查。4.3 测试投递POST /api/webhook/test Content-Type: application/json请求{ webhook_retries: 0, webhook_skip_ssl_verify: false, webhook_timeout: 5000, webhook_url: https://example.invalid/webhook }规则不要求先启用 Webhook不读取或修改持久化配置webhook_retries可省略默认 0范围 0–3表示失败后的额外重试次数测试使用生产 transport和相同 payload 外层结构测试事件固定为event_id-1、event_typewebhook_test测试内容与正式通知使用相同的语言规则zh、zh_TW使用中文其他 Sunshine locale 使用英文配置服务线程只保留异步响应不同步等待远端网络。响应{ attempts: 1, error: none, http_status: 204, status: true }error使用稳定分类none、not_running、queue_full、rate_limited、invalid_url、transport、http_status、cancelled、internal。这些分类与 webhook.h 中delivery_error_t枚举一一对应并由delivery_error_name()输出稳定的 API 名称——test_webhook.cpp 中的DeliveryErrorsHaveStableApiNames测试对此做了断言。前端调用封装在 webhookService.jsloadWebhookConfig/saveWebhookConfig/sendWebhookTest分别指向三个端点并统一通过webhookConfig.js完成 DTO 转换——例如webhookTimeoutToMilliseconds把界面上的 1–15 秒整数换算为毫秒normalizeWebhookTestRetries把重试次数限制在 0–3。5. Web UI 交互设计Webhook 保留在网络配置页原有位置以大卡片和弹窗呈现不创建独立通知页签卡片挂载于 Network.vue弹窗组件为 WebhookCard.vue。界面行为要点初始只显示卡片点击后才异步读取独立配置URL 支持 HTTP 和 HTTPS内容默认隐藏并可通过显隐按钮查看HTTP 显示明文传输提醒Webhook 通知和跳过 HTTPS 证书校验使用启停开关证书校验被跳过时显示明确风险提示超时在界面中使用 1–15 秒整数API 和文件中继续使用毫秒七个事件使用多选框默认全选可全选或清空保存、测试和加载状态互斥避免并发编辑造成状态错报保存成功后关闭弹窗并通过页面顶部居中的通知显示热生效结果不依赖外层配置按钮配置损坏时提示用户清理webhook_auth.json不显示本地绝对路径同时提供 Linux/macOS shell 与 Windows PowerShell 的 curl 请求模板弹窗只允许通过取消或保存成功关闭点击遮罩或按 Escape 不关闭并保留键盘焦点循环和关闭后焦点恢复弹窗正文支持鼠标滚轮和触摸纵向滑动并隔离滚动越界避免带动背景页面浅色模式使用不透明弹窗表面和高对比度正文、标签及辅助文字。所有 Webhook 文案和七个事件名称使用项目现有vue-i18n体系。6. 事件与 Payload6.1 事件编号持久化协议编号event_type事件0config_pair_success配对成功1config_pair_failed配对失败2nv_app_launch应用启动3nv_app_resume应用恢复4nv_app_terminate应用终止5nv_session_start会话开始6nv_session_end会话结束事件编号属于持久化格式和接收端协议不能因代码中的枚举顺序变化而修改。源码中event_type_t枚举webhook.h的取值与上述表格严格对应test_webhook.cpp 的EventIdentifiersAndFilterAreStable测试专门验证编号与名称的稳定性以及事件过滤例如配置{1, 6}后nv_app_launch被禁用、nv_session_end仍启用。6.2 Payload 结构与字段生产事件使用 UTF-8 JSON。以下是当前默认 Markdown 格式下的一次完整应用启动上报样例所有地址、名称、ID 和时间均为虚构值请求头顺序不属于协议POST /webhook HTTP/1.1 Host: example.invalid Content-Type: application/json; charsetutf-8 Connection: close User-Agent: Sunshine_Foundation/1.0 (System Notification Service) X-Webhook-Delivery: 018f0000-0000-7000-8000-000000000001 X-Trace-ID: 018f0000-0000-7000-8000-000000000001 X-Webhook-Event-ID: 2 X-Webhook-Event: nv_app_launch X-Timestamp: 1785115229979 X-Hostname: sunshine-host X-Signature: 1234567890 X-Auth-Token: Sunshine_Foundation_9979 X-Client-ID: Sunshine_Foundation X-API-Version: v1.0 X-Client-Info: Foundation Sunshine X-Service-Name: Sunshine_Foundation_Service X-Component: Sunshine_Foundation_Component {event_id:2,event_type:nv_app_launch,markdown:{content:**Sunshine System Notification**\n\nfont color\info\**Application Launched**/font\n\nHostname: font color\comment\sunshine-host/font\nServer IP: font color\comment\192.168.1.10/font\nApp Name: font color\comment\Example App/font\nApp ID: font color\comment\123/font\nClient: font color\comment\Moonlight Client/font\nClient IP: font color\comment\192.168.1.20/font\nResolution: font color\comment\1920x1080/font\nFPS: font color\comment\60/font\nAudio: font color\comment\Enabled/font\nTime: font color\comment\2026-07-27 09:20:29.979/font\n},msgtype:markdown}示例中的X-Signature只展示数值形态实际值由当前 Cstd::hash实现生成不具备跨平台稳定性也不构成密码学签名。为便于阅读body 也可以展开为{ event_id: 2, event_type: nv_app_launch, markdown: { content: **Sunshine System Notification**\n\nfont color\info\**Application Launched**/font\n\nHostname: font color\comment\sunshine-host/font\nServer IP: font color\comment\192.168.1.10/font\nApp Name: font color\comment\Example App/font\nApp ID: font color\comment\123/font\nClient: font color\comment\Moonlight Client/font\nClient IP: font color\comment\192.168.1.20/font\nResolution: font color\comment\1920x1080/font\nFPS: font color\comment\60/font\nAudio: font color\comment\Enabled/font\nTime: font color\comment\2026-07-27 09:20:29.979/font\n }, msgtype: markdown }不同事件只输出实际存在的内容字段事件markdown.content中的事件字段配对成功/失败Client Name、Client IP失败异常时可包含 Error应用启动/恢复App Name、App ID、Client、Client IP、Resolution、FPS、Audio应用终止App Name、App ID会话开始App Name、Client、Client IP、Session ID、Resolution、FPS会话结束App Name、Client、Client IP、Session ID、End Reason所有生产事件还会包含 Hostname、可用时的 Server IP 和 Time。空值不输出。格式与安全约束Markdown 内容最大4096 字节超长内容在UTF-8 字符边界处截断并追加省略号test_webhook.cpp 的PayloadTruncationPreservesUtf8AndJson用 2000 个 a 加中文及大量界字符验证了截断后仍是合法 JSON 且以...结尾时间使用 Sunshine 主机的系统时区格式固定为YYYY-MM-DD HH:mm:ss.xxx毫秒三位get_current_timestamp()返回固定 23 字符长度test_webhook.cpp 逐字符校验了格式内容中的 HTML/特殊字符会被转义防止注入sanitize_json_string处理引号、换行、制表符、反斜杠及控制字符ProductionPayloadIsValidJsonAndEscapesMarkup 验证了script被转义、**admin**中的星号被反斜杠转义、中文与 emoji 原样保留若客户端指纹检测到可疑客户端payload 中还会追加客户端完整性警告test_webhook.cpp 验证了 Markdown 与 JSON 两种格式下的警告输出。6.3 测试 payload测试按钮使用相同外层结构。语言读取 Sunshine 本次启动时加载的config::sunshine.locale修改主配置语言后需要重启 Sunshine才会影响 Webhook。英文 Markdown payload{ event_id: -1, event_type: webhook_test, markdown: { content: **Sunshine Webhook Test**\n\nfont color\info\**Test Notification**/font\n\nResult: font color\comment\Webhook endpoint reached/font\nHostname: font color\comment\sunshine-host/font\nEvent Type: font color\comment\webhook_test/font\nSample Application: font color\comment\Sunshine Test Application/font\nSample Client: font color\comment\Sunshine Test Client/font\nSample Stream: font color\comment\1920x1080, 60 FPS, Audio Enabled/font\nTime: font color\comment\2026-07-27 09:20:29.979/font\n }, msgtype: markdown }中文 payload 保持event_id、event_type、msgtype等协议字段不变仅翻译接收端展示的文本{ event_id: -1, event_type: webhook_test, markdown: { content: **Sunshine Webhook 测试**\n\nfont color\info\**测试通知**/font\n\n结果: font color\comment\Webhook 接收地址已收到测试请求/font\n主机名: font color\comment\sunshine-host/font\n事件类型: font color\comment\webhook_test/font\n示例应用: font color\comment\Sunshine 测试应用/font\n示例客户端: font color\comment\Sunshine 测试客户端/font\n示例串流: font color\comment\1920x108060 FPS音频已启用/font\n时间: font color\comment\2026-07-27 09:20:29.979/font\n }, msgtype: markdown }真实测试中的主机名和时间由 Sunshine 动态填写其余带Sample的字段只展示接收端可能看到的生产内容形态不对应当前真实应用或客户端。WebhookFormat类webhook_format.h除 Markdown 外还支持TEXT、JSON、CUSTOM格式与颜色标签、自定义模板、简化 IP 等配置能力测试用例 ChineseTestPayloadSupportsTextAndJsonFormats 验证了text与json两种 msgtype 下的测试 payload 结构JSON 格式包含event_title、result、sample.audio等结构化字段。6.4 请求头每次投递包含Content-Type: application/json; charsetutf-8Connection: closeUser-AgentX-Webhook-Delivery稳定 delivery IDX-Trace-ID与 delivery ID 相同X-Webhook-Event-IDX-Webhook-EventX-TimestampX-Hostname既有X-Signature、X-Auth-Token、X-Client-ID、X-API-Version、X-Client-Info、X-Service-Name和X-Component仅作为兼容元数据保留。当前配置没有用户密钥因此这些字段不构成密码学身份认证接收端不能把它们当作访问控制依据。安全细节动态主机名字段会替换 ASCII 控制字符并限制为 512 字节避免请求头注入。test_webhook.cpp 的DynamicHeaderValuesCannotInjectAnotherHeader验证了\r\nInjected: yes\t会被改写为__Injected: yes_超长值截断到 512 字节。7. URL 与 TLS 策略URL 规则仅支持http和https必须具有非空 authority 主机不接受内嵌用户名或密码不接受 ASCII 空白、控制字符或超过 4096 字节的值保留 path 和 queryfragment 不发送到接收端不自动跟随重定向不使用 Webhook 专用代理配置与webhook_httpclient.cpp中代理直接报错的行为一致。测试用例 UrlParserPreservesQueryAndRemovesFragment 验证了https://example.invalid:8443/hooks/event?kindlaunch#local-view会保留 path 与 query、丢弃 fragmentUrlParserRejectsUnsupportedOrCredentialedUrls 验证了ftp://、带 user:password 的 URL、缺失 host、含空格或换行、内嵌 NUL 的 URL 全部被拒绝。HTTPS 策略默认同时校验证书链和目标主机身份只有用户明确设置webhook_skip_ssl_verifytrue时才使用verify_none域名目标会发送 SNI 并检查 OpenSSL 设置结果IPv4/IPv6 字面量按照 RFC 6066不发送 SNI开启证书校验时仍按 IP 身份校验证书Windows 打包环境中的 OpenSSL 默认 CA 路径不保证可用因此开启证书校验时①通过 Windows CryptoAPI 以只读方式打开LocalMachine\ROOT和CurrentUser\ROOT②只枚举公开 X.509 证书不读取私钥、不修改系统证书库③把可用信任根导入 Webhook 独立的 OpenSSL context④继续由 OpenSSL 完成证书链和主机身份校验系统 ROOT 无法打开或没有可用信任根时本次 HTTPS 投递按传输失败处理不会自动跳过证书校验也不会影响 Sunshine当前实现没有接入 Windows 原生证书链策略因此不会完整继承 Windows 链引擎的全部吊销、Disallowed 和动态链构建行为非 Windows 平台使用 OpenSSL 默认信任路径。8. 异步投递模型8.1 线程与并发Webhook 维护一个专属io_context工作线程。线程常驻以支持事件接收、定时器和配置热启用但 DNS、TCP、TLS、写入和响应读取均为异步操作。运行限制源码常量见 webhook.cpp最多64个未完成投递最多2个网络请求同时在途生产事件每分钟最多接收20条测试请求不消耗生产事件速率额度队列或速率超限时丢弃新事件并限频记录警告不阻塞事件产生方。单个慢请求等待网络或超时时同一 I/O 线程仍可推进另一条请求、重试 timer 和关闭操作不会形成同步串行阻塞。8.2 超时配置继续使用毫秒但 Simple-Web-Server 的底层秒级超时使用向上取整timeout_seconds max(1, ceil(webhook_timeout_ms / 1000))测试用例 TimeoutMillisecondsRoundUpToWholeSeconds 验证了 1ms→1s、1000ms→1s、1001ms→2s、1999ms→2s、15000ms→15s 的取整行为。每次尝试另有同一io_context上的总截止 timer从 DNS 开始覆盖 TCP、TLS、写入和等待响应头的完整过程到期后停止当前 client并按传输失败策略处理。8.3 短连接与响应头专用读取每次尝试创建独立HTTP/HTTPS Client请求显式发送Connection: close。Webhook 工作线程常驻但网络连接不常驻也不使用连接池。Webhook 的接收确认契约只依赖 HTTP 状态码和响应头使用最大 16 KiB 的独立响应头缓冲区正确跳过除101外的临时1xx响应连续临时1xx最多接受 8 个超出后按协议错误结束本次尝试取得最终响应头后立即完成尝试并关闭 client不读取或解释响应正文。这套仅读响应头的机制由 webhook_client_base.h 的WebhookClientBase模板实现它在写请求后调用read_response_headers()用async_read_until(HeaderEndMatch)只读到头部结束标记逐条解析状态行与头部识别并跳过临时 1xxMAX_INTERIM_RESPONSES8最终取得最终响应头后立即回调关闭。因此慢响应体或流式响应不会继续占用两个在途槽也不会把已返回成功状态的 POST 误判为超时重试。接收端不应把业务成败只放在2xx响应正文中。9. 状态码与重试策略结果策略任意2xx为成功webhook.cpp 中is_success_status判断status 200 status 300传输错误可以重试HTTP408、429、500、502、503、504可以重试其他 HTTP 状态不重试生产事件最多尝试3 次测试请求按webhook_retries进行 0–3 次额外重试总尝试次数为 1–4429和503支持Retry-After的秒数或 HTTP-date上限 60 秒无Retry-After时使用约 1 秒、2 秒并带小幅抖动的退避webhook.cpp 中attempt1 ? 1000ms : 2000ms配合取模 251 的抖动状态。测试用例 HttpStatusPolicyAcceptsAll2xxAndRetriesOnlyAllowlist 验证了 200/202/204 均成功、300 失败408/429/500/502/503/504 可重试而 400/401/403/404/409/501 不可重试RetryAfterAcceptsDelaySecondsAndAppliesCap 与 RetryAfterAcceptsHttpDateForms 验证了秒数形式120被钳制到 60与三种 HTTP-date 形式RFC 1123、RFC 850、asctime的解析。Simple-Web-Server 的底层隐式重连在 Webhook 专用 Client 中关闭attempt_reconnectfalse所有尝试都由 dispatcher 明确计数。POST 使用至少一次投递语义如果远端已经处理请求、但响应头未被成功接收Sunshine 可能重试。相同逻辑投递的 delivery ID 在重试之间保持不变接收端应据此去重。10. 生命周期与故障隔离Webhook 运行时在 Sunshine 启动阶段建立生命周期守卫webhook::init()返回 move-only 的deinit_t守卫。即使当前未启用 Webhook工作线程也可以安静启动并保持空闲使后续保存配置能够立即热启用ensure_running()可幂等启动运行时。故障隔离规则Webhook 初次启动失败时只记录通用错误Sunshine 继续启动保存或测试可以幂等重试启动运行时运行时不可用时生产事件被安全丢弃不反向阻塞主流程API、事件入口、I/O handler、完成回调和关闭路径均有异常边界Sunshine 开始退出后永久拒绝重新启动 Webhook关闭时停止接收新投递取消队列、重试 timer、总截止 timer 和活动 client完成等待中的测试回调停止io_context并 join 工作线程dispatcher 析构提供最终幂等回收兜底。从接口设计看webhook.hruntime_active()报告运行时是否正在接收投递current_configuration()返回活动配置的连贯副本send_event_async()无阻塞地排队生产事件send_test_async()使用与生产相同的 payload 外层与 transport 投递测试。Webhook 配置和网络故障不会传播为主程序退出条件。11. 日志与隐私边界允许记录delivery ID事件类型尝试次数HTTP 状态码总耗时稳定错误类别禁止记录或回显Webhook URL、host、path 或 querypayload 和响应正文凭据或 token本地配置绝对路径证书内容配置文件损坏、证书库不可用和网络错误只返回不包含本地细节的稳定错误。webhook_auth.h的load()注释明确承诺never throws and never logs file contents or paths这也是 API 错误码保持稳定通用如webhook_config_invalid的原因——前端只看到提示清理配置文件的短消息而看不到主机上的真实文件路径。12. 协议依据Webhook 实现依据的标准与约定RFC 3986URI scheme、authority、path、query 和 fragmentRFC 9110HTTP 状态码、Retry-After和连接语义RFC 6585429 Too Many RequestsRFC 9525HTTPS 服务身份校验RFC 8259UTF-8 JSON时间字段使用 Sunshine 主机系统时区和固定格式YYYY-MM-DD HH:mm:ss.xxx。接收端集成建议速览以X-Webhook-Delivery作为幂等键配合X-Trace-ID追踪把业务确认放在 HTTP 状态码而非响应正文对429/503遵循Retry-After不要把X-Signature等兼容头当作认证依据对 Markdown payload 中的 HTML 标签font color...、br等按富文本处理并做好渲染转义如需进一步研究实现细节可深入阅读 src/webhook 目录下各模块源码与 tests/unit/test_webhook.cpp 的完整测试套件。赞分享音视频【免费下载链接】foundation-sunshineSunshine fork: an enhanced sunshine, a self-hosted game streaming host for Moonlight with HDR10/HDR Vivid, virtual displays, advanced audio, optimized encoders, and a modern control panel.项目地址https://gitcode.com/gh_mirrors/sunshine5/foundation-sunshine点击查看免费下载相关推荐DeepSeek Harness 远程事件投递机制ctx.remote.$on 的设计、协议与实现DeepSeek Harness 远程事件投递机制 ctx.remote.$on 的设计、协议与实现 DeepSeek Harness 在既有 Typert人工智能AI AgentAgent 框架DeepSeek构建企业级AI数据库助手Vanna 2.0的架构解析与实践指南构建企业级AI数据库助手Vanna 2.0的架构解析与实践指南 在数据驱动的商业环境中非技术人员如何直接与数据库对话如何让业务人员用自然语言获取数据洞察人工智能AI AgentRAG数据库后端数据可视化Sunshine Webhook 格式与投递语义详解从配置文件到事件 Payload 的完整指南Sunshine Webhook 格式与投递语义详解从配置文件到事件 Payload 的完整指南 本文以 foundation sunshineSunshi音视频上一篇tModLoader全面指南泰拉瑞亚模组加载工具使用详解下一篇msaicerr 转换 Dump 文件数据类型bin 转 npy完整指南命令参数、底层实现与数据类型支持详解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考