UNPKG

@realsee/vr-signals

Version:

vr 信号器

77 lines (70 loc) 121 kB
<!DOCTYPE html><html class="default" lang="en" data-base="./"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>@realsee/vr-signals API Documentation - v2.0.0</title><meta name="description" content="Documentation for @realsee/vr-signals API Documentation"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css"/><link rel="stylesheet" href="assets/highlight.css"/><script defer src="assets/main.js"></script><script async src="assets/icons.js" id="tsd-icons-script"></script><script async src="assets/search.js" id="tsd-search-script"></script><script async src="assets/navigation.js" id="tsd-nav-script"></script><script async src="assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="index.html" class="title">@realsee/vr-signals API Documentation - v2.0.0</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><h1>@realsee/vr-signals API Documentation - v2.0.0</h1></div><div class="tsd-panel tsd-typography"><h1 id="realseevr-signals" class="tsd-anchor-link">@realsee/vr-signals<a href="#realseevr-signals" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p>VR 信号通信库,用于在 VR 应用和父窗口之间建立双向通信。</p> <h2 id="特性" class="tsd-anchor-link">特性<a href="#特性" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ul> <li>🔄 自动握手和连接管理</li> <li>📡 双向消息通信</li> <li>🚀 智能重试策略(指数退避 + 抖动)</li> <li>🔌 自动重连机制</li> <li>📝 详细的日志记录</li> <li>🎯 类型安全的 API</li> <li>🛡️ <strong>企业级安全特性</strong></li> <li>✨ <strong>开箱即用的核心类型</strong> - 无需传入泛型参数</li> </ul> <h2 id="🆕-核心类型支持" class="tsd-anchor-link">🆕 核心类型支持<a href="#🆕-核心类型支持" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>SDK 现在提供了核心类型支持,包含了必要的 Action 和 Event。这意味着你可以直接使用 SDK,无需定义自己的类型映射:</p> <h2 id="🚀-动态-action-注册系统" class="tsd-anchor-link">🚀 动态 Action 注册系统<a href="#🚀-动态-action-注册系统" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>SDK 现在支持动态注册和移除 Actions,无需在初始化时传入完整的 <code>actionMap</code>:</p> <h3 id="remote-端动态管理" class="tsd-anchor-link">Remote 端动态管理<a href="#remote-端动态管理" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="typescript"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">RealseeVRSignalsRemote</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;@realsee/vr-signals&#39;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">remote</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">RealseeVRSignalsRemote</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">logLevel:</span><span class="hl-1"> </span><span class="hl-3">&#39;INFO&#39;</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 动态注册单个 Action</span><br/><span class="hl-2">remote</span><span class="hl-1">.</span><span class="hl-6">registerAction</span><span class="hl-1">(</span><span class="hl-3">&#39;setState&#39;</span><span class="hl-1">, </span><span class="hl-4">async</span><span class="hl-1"> (</span><span class="hl-2">data</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;setState 被调用:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">)</span><br/><span class="hl-1"> </span><span class="hl-7">// data 包含 mode, longitude, latitude, fov 等 Five SDK 状态</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> { </span><span class="hl-2">success:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">, </span><span class="hl-2">message:</span><span class="hl-1"> </span><span class="hl-3">&#39;状态已设置&#39;</span><span class="hl-1"> }</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 批量注册 Actions</span><br/><span class="hl-2">remote</span><span class="hl-1">.</span><span class="hl-6">registerActions</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-3">&#39;updateCamera&#39;</span><span class="hl-2">:</span><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> (</span><span class="hl-2">data</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;updateCamera 被调用:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">)</span><br/><span class="hl-1"> </span><span class="hl-7">// data.state 包含 longitude, latitude, fov, offset 等 Five SDK 相机状态</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> { </span><span class="hl-2">success:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">, </span><span class="hl-2">message:</span><span class="hl-1"> </span><span class="hl-3">&#39;相机已更新&#39;</span><span class="hl-1"> }</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-3">&#39;tag.changeData&#39;</span><span class="hl-2">:</span><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> (</span><span class="hl-2">data</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;tag.changeData 被调用:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">)</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> { </span><span class="hl-2">success:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">, </span><span class="hl-2">message:</span><span class="hl-1"> </span><span class="hl-3">&#39;标签已更新&#39;</span><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 移除 Action</span><br/><span class="hl-2">remote</span><span class="hl-1">.</span><span class="hl-6">unregisterAction</span><span class="hl-1">(</span><span class="hl-3">&#39;tag.changeData&#39;</span><span class="hl-1">)</span><br/><br/><span class="hl-7">// 监听 Action 变化</span><br/><span class="hl-2">remote</span><span class="hl-1">.</span><span class="hl-6">onActionChange</span><span class="hl-1">((</span><span class="hl-2">event</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;Action 变化:&#39;</span><span class="hl-1">, </span><span class="hl-2">event</span><span class="hl-1">)</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 获取统计信息</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">stats</span><span class="hl-1"> = </span><span class="hl-2">remote</span><span class="hl-1">.</span><span class="hl-6">getActionStats</span><span class="hl-1">()</span><br/><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;已注册 Actions:&#39;</span><span class="hl-1">, </span><span class="hl-2">stats</span><span class="hl-1">.</span><span class="hl-2">registered</span><span class="hl-1">)</span> </code><button type="button">Copy</button></pre> <h3 id="client-端智能检查" class="tsd-anchor-link">Client 端智能检查<a href="#client-端智能检查" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="typescript"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">RealseeVRSignalsClient</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;@realsee/vr-signals&#39;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">client</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">RealseeVRSignalsClient</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">vrLink:</span><span class="hl-1"> </span><span class="hl-3">&#39;http://localhost:3000/vr-app&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">element:</span><span class="hl-1"> </span><span class="hl-2">iframeElement</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 检查 Action 是否可用</span><br/><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">isActionAvailable</span><span class="hl-1">(</span><span class="hl-3">&#39;setState&#39;</span><span class="hl-1">)) {</span><br/><span class="hl-1"> </span><span class="hl-7">// 安全调用</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">result</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">send</span><span class="hl-1">(</span><span class="hl-3">&#39;setState&#39;</span><span class="hl-1">, { </span><br/><span class="hl-1"> </span><span class="hl-2">mode:</span><span class="hl-1"> </span><span class="hl-3">&#39;panorama&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">longitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">latitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">fov:</span><span class="hl-1"> </span><span class="hl-8">90</span><br/><span class="hl-1"> })</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;结果:&#39;</span><span class="hl-1">, </span><span class="hl-2">result</span><span class="hl-1">)</span><br/><span class="hl-1">} </span><span class="hl-0">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;setState 不可用&#39;</span><span class="hl-1">)</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// 监听 Action 可用性变化</span><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">onActionAvailabilityChange</span><span class="hl-1">(</span><span class="hl-3">&#39;setState&#39;</span><span class="hl-1">, (</span><span class="hl-2">available</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">available</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;setState 现在可用了!&#39;</span><span class="hl-1">)</span><br/><span class="hl-1"> } </span><span class="hl-0">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;setState 不可用了&#39;</span><span class="hl-1">)</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 等待特定 Action 可用</span><br/><span class="hl-0">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">waitForAction</span><span class="hl-1">(</span><span class="hl-3">&#39;setState&#39;</span><span class="hl-1">, </span><span class="hl-8">5000</span><span class="hl-1">)</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;setState 可用,开始调用...&#39;</span><span class="hl-1">)</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">send</span><span class="hl-1">(</span><span class="hl-3">&#39;setState&#39;</span><span class="hl-1">, { </span><br/><span class="hl-1"> </span><span class="hl-2">mode:</span><span class="hl-1"> </span><span class="hl-3">&#39;panorama&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">longitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">latitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">fov:</span><span class="hl-1"> </span><span class="hl-8">90</span><br/><span class="hl-1"> })</span><br/><span class="hl-1">} </span><span class="hl-0">catch</span><span class="hl-1"> (</span><span class="hl-2">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;等待超时:&#39;</span><span class="hl-1">, </span><span class="hl-2">error</span><span class="hl-1">.</span><span class="hl-2">message</span><span class="hl-1">)</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// 获取可用 Actions 列表</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">availableActions</span><span class="hl-1"> = </span><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">getAvailableActions</span><span class="hl-1">()</span><br/><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;可用的 Actions:&#39;</span><span class="hl-1">, </span><span class="hl-2">availableActions</span><span class="hl-1">)</span> </code><button type="button">Copy</button></pre> <h3 id="无需泛型的简单用法" class="tsd-anchor-link">无需泛型的简单用法<a href="#无需泛型的简单用法" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="typescript"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">RealseeVRSignalsClient</span><span class="hl-1">, </span><span class="hl-2">RealseeVRSignalsRemote</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;@realsee/vr-signals&#39;</span><br/><br/><span class="hl-7">// 客户端 - 无需泛型</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">client</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">RealseeVRSignalsClient</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">vrLink:</span><span class="hl-1"> </span><span class="hl-3">&#39;http://localhost:3000/vr-app&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">element:</span><span class="hl-1"> </span><span class="hl-2">document</span><span class="hl-1">.</span><span class="hl-6">getElementById</span><span class="hl-1">(</span><span class="hl-3">&#39;vr-container&#39;</span><span class="hl-1">) </span><span class="hl-0">as</span><span class="hl-1"> </span><span class="hl-9">HTMLDivElement</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">logLevel:</span><span class="hl-1"> </span><span class="hl-3">&#39;INFO&#39;</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 服务端 - 无需泛型</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">remote</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">RealseeVRSignalsRemote</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">logLevel:</span><span class="hl-1"> </span><span class="hl-3">&#39;INFO&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">actionMap:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">setState</span><span class="hl-1">(</span><span class="hl-2">data</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;State update:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">)</span><br/><span class="hl-1"> </span><span class="hl-7">// data 包含 mode, longitude, latitude, fov 等 Five SDK 状态</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> { </span><span class="hl-2">success:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1"> }</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-6">updateCamera</span><span class="hl-1">({ </span><span class="hl-2">state</span><span class="hl-1"> }) {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;Camera update:&#39;</span><span class="hl-1">, </span><span class="hl-2">state</span><span class="hl-1">)</span><br/><span class="hl-1"> </span><span class="hl-7">// state 包含 longitude, latitude, fov, offset 等 Five SDK 相机状态</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> { </span><span class="hl-2">success:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 直接使用预定义的事件和动作</span><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">on</span><span class="hl-1">(</span><span class="hl-3">&#39;stateSynced&#39;</span><span class="hl-1">, (</span><span class="hl-2">data</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;State synced:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">)</span><br/><span class="hl-1"> </span><span class="hl-7">// data 包含 mode, longitude, latitude, fov 等 Five SDK 状态</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">on</span><span class="hl-1">(</span><span class="hl-3">&#39;cameraUpdate&#39;</span><span class="hl-1">, (</span><span class="hl-2">data</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;Camera updated:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">state</span><span class="hl-1">)</span><br/><span class="hl-1"> </span><span class="hl-7">// data.state 包含 longitude, latitude, fov, offset 等 Five SDK 相机状态</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">on</span><span class="hl-1">(</span><span class="hl-3">&#39;tag.click&#39;</span><span class="hl-1">, (</span><span class="hl-2">data</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;Tag clicked:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">title</span><span class="hl-1">)</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">on</span><span class="hl-1">(</span><span class="hl-3">&#39;monitor.open&#39;</span><span class="hl-1">, (</span><span class="hl-2">data</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;Monitor opened:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">name</span><span class="hl-1">)</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">on</span><span class="hl-1">(</span><span class="hl-3">&#39;monitor.close&#39;</span><span class="hl-1">, (</span><span class="hl-2">data</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;Monitor closed:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">name</span><span class="hl-1">)</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">on</span><span class="hl-1">(</span><span class="hl-3">&#39;overlay.visible&#39;</span><span class="hl-1">, (</span><span class="hl-2">data</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;Overlay visibility:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">visible</span><span class="hl-1">)</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 发送动作</span><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">send</span><span class="hl-1">(</span><span class="hl-3">&#39;setState&#39;</span><span class="hl-1">, { </span><br/><span class="hl-1"> </span><span class="hl-2">mode:</span><span class="hl-1"> </span><span class="hl-3">&#39;panorama&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">longitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">latitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">fov:</span><span class="hl-1"> </span><span class="hl-8">90</span><br/><span class="hl-1">})</span><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">send</span><span class="hl-1">(</span><span class="hl-3">&#39;updateCamera&#39;</span><span class="hl-1">, { </span><br/><span class="hl-1"> </span><span class="hl-2">state:</span><span class="hl-1"> { </span><br/><span class="hl-1"> </span><span class="hl-2">longitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><br/><span class="hl-1"> </span><span class="hl-2">latitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><br/><span class="hl-1"> </span><span class="hl-2">fov:</span><span class="hl-1"> </span><span class="hl-8">90</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">offset:</span><span class="hl-1"> { </span><span class="hl-2">x:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><span class="hl-2">y:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><span class="hl-2">z:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 发送事件</span><br/><span class="hl-2">remote</span><span class="hl-1">.</span><span class="hl-6">sendEvent</span><span class="hl-1">(</span><span class="hl-3">&#39;stateSynced&#39;</span><span class="hl-1">, { </span><span class="hl-2">mode:</span><span class="hl-1"> </span><span class="hl-3">&#39;editing&#39;</span><span class="hl-1">, </span><span class="hl-2">view:</span><span class="hl-1"> </span><span class="hl-3">&#39;panorama&#39;</span><span class="hl-1"> })</span><br/><span class="hl-2">remote</span><span class="hl-1">.</span><span class="hl-6">sendEvent</span><span class="hl-1">(</span><span class="hl-3">&#39;cameraUpdate&#39;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">state:</span><span class="hl-1"> { </span><br/><span class="hl-1"> </span><span class="hl-2">longitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><br/><span class="hl-1"> </span><span class="hl-2">latitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><br/><span class="hl-1"> </span><span class="hl-2">fov:</span><span class="hl-1"> </span><span class="hl-8">90</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">offset:</span><span class="hl-1"> { </span><span class="hl-2">x:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><span class="hl-2">y:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><span class="hl-2">z:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1"> }</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-2">userAction:</span><span class="hl-1"> </span><span class="hl-4">false</span><br/><span class="hl-1">})</span> </code><button type="button">Copy</button></pre> <h3 id="已实现的核心功能" class="tsd-anchor-link">已实现的核心功能<a href="#已实现的核心功能" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>SDK 包含了以下核心功能:</p> <h4 id="🎮-actions(动作)" class="tsd-anchor-link">🎮 Actions(动作)<a href="#🎮-actions(动作)" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><ul> <li><strong>状态管理</strong>: <code>setState</code> - 设置应用状态</li> <li><strong>相机控制</strong>: <code>updateCamera</code> - 更新相机状态</li> </ul> <h4 id="📡-events(事件)" class="tsd-anchor-link">📡 Events(事件)<a href="#📡-events(事件)" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><ul> <li><strong>状态同步</strong>: <code>stateSynced</code> - 状态同步事件</li> <li><strong>相机事件</strong>: <code>cameraUpdate</code> - 相机更新事件</li> <li><strong>标签事件</strong>: <code>tag.click</code> - 标签点击事件</li> <li><strong>监控事件</strong>: <code>monitor.open</code>, <code>monitor.close</code> - 监控开启/关闭事件</li> <li><strong>覆盖层事件</strong>: <code>overlay.visible</code> - 覆盖层显示/隐藏事件</li> </ul> <h3 id="高级用法---扩展核心类型" class="tsd-anchor-link">高级用法 - 扩展核心类型<a href="#高级用法---扩展核心类型" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>如果你需要添加自定义功能,仍然可以使用泛型:</p> <pre><code class="typescript"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">RealseeVRSignalsClient</span><span class="hl-1">, </span><span class="hl-2">DefaultActionMap</span><span class="hl-1">, </span><span class="hl-2">DefaultEventMap</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;@realsee/vr-signals&#39;</span><br/><br/><span class="hl-7">// 扩展核心类型</span><br/><span class="hl-4">interface</span><span class="hl-1"> </span><span class="hl-9">CustomActionMap</span><span class="hl-1"> </span><span class="hl-4">extends</span><span class="hl-1"> </span><span class="hl-9">DefaultActionMap</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">&#39;custom.action&#39;</span><span class="hl-1">: (</span><span class="hl-2">data</span><span class="hl-1">: { </span><span class="hl-2">message</span><span class="hl-1">: </span><span class="hl-9">string</span><span class="hl-1"> }) </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-9">Promise</span><span class="hl-1">&lt;{ </span><span class="hl-2">result</span><span class="hl-1">: </span><span class="hl-9">string</span><span class="hl-1"> }&gt;</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-4">interface</span><span class="hl-1"> </span><span class="hl-9">CustomEventMap</span><span class="hl-1"> </span><span class="hl-4">extends</span><span class="hl-1"> </span><span class="hl-9">DefaultEventMap</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">&#39;custom.event&#39;</span><span class="hl-1">: (</span><span class="hl-2">data</span><span class="hl-1">: { </span><span class="hl-2">message</span><span class="hl-1">: </span><span class="hl-9">string</span><span class="hl-1"> }) </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-9">void</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// 使用扩展的类型</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">customClient</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">RealseeVRSignalsClient</span><span class="hl-1">&lt;</span><span class="hl-9">CustomActionMap</span><span class="hl-1">, </span><span class="hl-9">CustomEventMap</span><span class="hl-1">&gt;({</span><br/><span class="hl-1"> </span><span class="hl-2">vrLink:</span><span class="hl-1"> </span><span class="hl-3">&#39;http://localhost:3000/vr-app&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">element:</span><span class="hl-1"> </span><span class="hl-2">document</span><span class="hl-1">.</span><span class="hl-6">getElementById</span><span class="hl-1">(</span><span class="hl-3">&#39;vr-container&#39;</span><span class="hl-1">) </span><span class="hl-0">as</span><span class="hl-1"> </span><span class="hl-9">HTMLDivElement</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 使用核心功能</span><br/><span class="hl-2">customClient</span><span class="hl-1">.</span><span class="hl-6">on</span><span class="hl-1">(</span><span class="hl-3">&#39;cameraUpdate&#39;</span><span class="hl-1">, (</span><span class="hl-2">data</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;Camera updated:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">state</span><span class="hl-1">)</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 使用自定义功能</span><br/><span class="hl-2">customClient</span><span class="hl-1">.</span><span class="hl-6">on</span><span class="hl-1">(</span><span class="hl-3">&#39;custom.event&#39;</span><span class="hl-1">, (</span><span class="hl-2">data</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;Custom event:&#39;</span><span class="hl-1">, </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">message</span><span class="hl-1">)</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-2">customClient</span><span class="hl-1">.</span><span class="hl-6">send</span><span class="hl-1">(</span><span class="hl-3">&#39;custom.action&#39;</span><span class="hl-1">, { </span><span class="hl-2">message:</span><span class="hl-1"> </span><span class="hl-3">&#39;Hello&#39;</span><span class="hl-1"> })</span> </code><button type="button">Copy</button></pre> <h2 id="安全特性" class="tsd-anchor-link">安全特性<a href="#安全特性" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><h3 id="🚨-安全风险提醒" class="tsd-anchor-link">🚨 安全风险提醒<a href="#🚨-安全风险提醒" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong>重要</strong>:为了兼容 1.x 版本,2.x 版本默认禁用了严格的安全模式:</p> <ul> <li>默认允许所有域名的跨域通信</li> <li>这提供了与 1.x 版本的最大兼容性</li> <li>在生产环境中建议启用安全模式以提高安全性</li> </ul> <h3 id="🛡️-内置安全机制" class="tsd-anchor-link">🛡️ 内置安全机制<a href="#🛡️-内置安全机制" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><ol> <li><strong>Origin 验证</strong>:验证消息来源域名</li> <li><strong>消息结构验证</strong>:验证消息格式和必需字段</li> <li><strong>时间戳验证</strong>:防止重放攻击</li> <li><strong>消息签名</strong>:可选的数字签名验证</li> <li><strong>严格模式</strong>:限制只允许可信域名</li> <li><strong>🆕 自适应策略</strong>:智能识别 iframe 和父级窗口的域名关系</li> </ol> <h3 id="🔄-自适应安全策略" class="tsd-anchor-link">🔄 自适应安全策略<a href="#🔄-自适应安全策略" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong>自适应策略</strong>是 <code>vr-signals</code> 的核心安全特性,能够智能识别和适应不同的域名关系:</p> <h4 id="自动识别的场景" class="tsd-anchor-link">自动识别的场景<a href="#自动识别的场景" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><ul> <li><strong>同源环境</strong>:<code>http://localhost:3000</code> ↔ <code>http://localhost:3000</code> ✅</li> <li><strong>同域名不同端口</strong>:<code>http://localhost:3000</code> ↔ <code>http://localhost:1234</code> ✅</li> <li><strong>同域名不同协议</strong>:<code>http://example.com</code> ↔ <code>https://example.com</code> ✅</li> <li><strong>子域名关系</strong>:<code>https://app.example.com</code> ↔ <code>https://vr.example.com</code> ✅</li> <li><strong>恶意域名</strong>:<code>https://app.example.com</code> ↔ <code>https://malicious-site.com</code> ❌</li> </ul> <h4 id="自适应策略优势" class="tsd-anchor-link">自适应策略优势<a href="#自适应策略优势" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><ol> <li><strong>🎯 零配置</strong>:开发环境无需手动配置域名白名单</li> <li><strong>🔧 自动适应</strong>:自动处理 localhost 不同端口的情况</li> <li><strong>🌐 智能识别</strong>:自动识别同域名下的子域名关系</li> <li><strong>🛡️ 安全可靠</strong>:完全避免使用危险的通配符</li> <li><strong>⚡ 开箱即用</strong>:减少配置错误和安全漏洞</li> </ol> <h3 id="🔒-安全配置示例" class="tsd-anchor-link">🔒 安全配置示例<a href="#🔒-安全配置示例" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><h4 id="完全自适应模式(推荐用于所有环境)" class="tsd-anchor-link">完全自适应模式(推荐用于所有环境)<a href="#完全自适应模式(推荐用于所有环境)" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">adaptiveClient</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">RealseeVRSignalsClient</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">vrLink:</span><span class="hl-1"> </span><span class="hl-3">&#39;http://localhost:1234/vr-app&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">element:</span><span class="hl-1"> </span><span class="hl-2">iframeElement</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><br/><span class="hl-1"> </span><span class="hl-7">// 安全配置:完全自适应</span><br/><span class="hl-1"> </span><span class="hl-2">security:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">strictMode:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">, </span><span class="hl-7">// 启用严格模式</span><br/><span class="hl-1"> </span><span class="hl-2">validateOrigin:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">, </span><span class="hl-7">// 验证消息来源</span><br/><span class="hl-1"> </span><span class="hl-2">validateSignature:</span><span class="hl-1"> </span><span class="hl-4">false</span><span class="hl-1">, </span><span class="hl-7">// 开发环境不启用签名验证</span><br/><span class="hl-1"> </span><span class="hl-2">signatureKey:</span><span class="hl-1"> </span><span class="hl-4">undefined</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">})</span> </code><button type="button">Copy</button></pre> <h4 id="生产环境配置(自适应--签名验证)" class="tsd-anchor-link">生产环境配置(自适应 + 签名验证)<a href="#生产环境配置(自适应--签名验证)" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="typescript"><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">productionClient</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">RealseeVRSignalsClient</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">vrLink:</span><span class="hl-1"> </span><span class="hl-3">&#39;https://vr-app.example.com&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">element:</span><span class="hl-1"> </span><span class="hl-2">iframeElement</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><br/><span class="hl-1"> </span><span class="hl-7">// 安全配置:自适应 + 签名验证</span><br/><span class="hl-1"> </span><span class="hl-2">security:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">strictMode:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">validateOrigin:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">validateSignature:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">, </span><span class="hl-7">// 启用消息签名验证</span><br/><span class="hl-1"> </span><span class="hl-2">signatureKey:</span><span class="hl-1"> </span><span class="hl-3">&#39;your-secret-key&#39;</span><span class="hl-1"> </span><span class="hl-7">// 签名密钥</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">})</span> </code><button type="button">Copy</button></pre> <h2 id="安装" class="tsd-anchor-link">安装<a href="#安装" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><pre><code class="bash"><span class="hl-6">npm</span><span class="hl-1"> </span><span class="hl-3">install</span><span class="hl-1"> </span><span class="hl-3">@realsee/vr-signals</span> </code><button type="button">Copy</button></pre> <h2 id="基本用法" class="tsd-anchor-link">基本用法<a href="#基本用法" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><h3 id="🆕-客户端(父窗口)--使用核心类型" class="tsd-anchor-link">🆕 客户端(父窗口)- 使用核心类型<a href="#🆕-客户端(父窗口)--使用核心类型" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="typescript"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">RealseeVRSignalsClient</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;@realsee/vr-signals&#39;</span><br/><br/><span class="hl-7">// 无需泛型参数,直接使用核心类型</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">client</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">RealseeVRSignalsClient</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">vrLink:</span><span class="hl-1"> </span><span class="hl-3">&#39;http://localhost:3000/vr-app&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">element:</span><span class="hl-1"> </span><span class="hl-2">iframeElement</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">logLevel:</span><span class="hl-1"> </span><span class="hl-3">&#39;INFO&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><br/><span class="hl-1"> </span><span class="hl-7">// 自定义握手重试策略</span><br/><span class="hl-1"> </span><span class="hl-2">handshakeRetryStrategy:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">baseDelay:</span><span class="hl-1"> </span><span class="hl-8">500</span><span class="hl-1">, </span><span class="hl-7">// 基础延迟 500ms</span><br/><span class="hl-1"> </span><span class="hl-2">maxDelay:</span><span class="hl-1"> </span><span class="hl-8">5000</span><span class="hl-1">, </span><span class="hl-7">// 最大延迟 5s</span><br/><span class="hl-1"> </span><span class="hl-2">jitterRange:</span><span class="hl-1"> [</span><span class="hl-8">0.85</span><span class="hl-1">, </span><span class="hl-8">1.15</span><span class="hl-1">] </span><span class="hl-7">// 抖动因子范围</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><br/><span class="hl-1"> </span><span class="hl-7">// 自定义重连策略</span><br/><span class="hl-1"> </span><span class="hl-2">reconnectStrategy:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">baseDelay:</span><span class="hl-1"> </span><span class="hl-8">2000</span><span class="hl-1">, </span><span class="hl-7">// 基础重连延迟 2s</span><br/><span class="hl-1"> </span><span class="hl-2">maxDelay:</span><span class="hl-1"> </span><span class="hl-8">30000</span><span class="hl-1">, </span><span class="hl-7">// 最大重连延迟 30s</span><br/><span class="hl-1"> </span><span class="hl-2">jitterRange:</span><span class="hl-1"> [</span><span class="hl-8">0.8</span><span class="hl-1">, </span><span class="hl-8">1.2</span><span class="hl-1">] </span><span class="hl-7">// 抖动因子范围</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><br/><span class="hl-1"> </span><span class="hl-2">shakehandRetryTimes:</span><span class="hl-1"> </span><span class="hl-8">10</span><span class="hl-1">, </span><span class="hl-7">// 握手重试次数</span><br/><span class="hl-1"> </span><span class="hl-2">enableAutoReconnect:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">, </span><span class="hl-7">// 启用自动重连</span><br/><span class="hl-1"> </span><span class="hl-2">maxReconnectAttempts:</span><span class="hl-1"> </span><span class="hl-8">5</span><span class="hl-1"> </span><span class="hl-7">// 最大重连次数</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 监听连接状态</span><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">onConnectionStatusChange</span><span class="hl-1">((</span><span class="hl-2">status</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;Connection status:&#39;</span><span class="hl-1">, </span><span class="hl-2">status</span><span class="hl-1">)</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 等待连接就绪</span><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">onReady</span><span class="hl-1">(() </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&#39;Client is ready!&#39;</span><span class="hl-1">)</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-7">// 发送核心动作(无需类型声明)</span><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">send</span><span class="hl-1">(</span><span class="hl-3">&#39;setState&#39;</span><span class="hl-1">, { </span><br/><span class="hl-1"> </span><span class="hl-2">mode:</span><span class="hl-1"> </span><span class="hl-3">&#39;panorama&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">longitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">latitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">fov:</span><span class="hl-1"> </span><span class="hl-8">90</span><br/><span class="hl-1">})</span><br/><span class="hl-2">client</span><span class="hl-1">.</span><span class="hl-6">send</span><span class="hl-1">(</span><span class="hl-3">&#39;updateCamera&#39;</span><span class="hl-1">, { </span><br/><span class="hl-1"> </span><span class="hl-2">state:</span><span class="hl-1"> { </span><br/><span class="hl-1"> </span><span class="hl-2">longitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><br/><span class="hl-1"> </span><span class="hl-2">latitude:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><br/><span class="hl-1"> </span><span class="hl-2">fov:</span><span class="hl-1"> </span><span class="hl-8">90</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">offset:</span><span class="hl-1"> { </span><span class="hl-2">x:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><span class="hl-2">y:</span><span class="hl-1"> </span><span class="hl-8">0</span><span class="hl-1">, </span><span class="hl-2">z:</span><s