Skip to content

客户端桥接兼容层 (ClientBridge)

统一 Web 页面在 FinNex 与 WPF/CefSharp 客户端中的桥接调用方式。业务侧只需要调用 ClientBridge.call(method, params)ClientBridge.call(method, options),该方法始终返回 Promise

签名

typescript
interface ClientBridge {
  call<T = unknown>(method: string, options: ClientBridgeCallOptions): Promise<T>;
  call<T = unknown>(method: string, params?: unknown): Promise<T>;
  call<T = unknown>(
    method: string,
    params?: unknown,
    options?: ClientBridgeCallOptions
  ): Promise<T>;
  getFinnexClientBridgeInfo(): FinnexClientBridgeInfo;
  readonly isFinNex: boolean;
  readonly isWpf: boolean;
  readonly isClient: boolean;
}

interface ClientBridgeCallOptions {
  direct?: boolean;
}

interface FinnexClientBridgeInfo {
  isAvailable: boolean;
  protocolVersion?: string;
}

const ClientBridge: ClientBridge;

function callClientBridge<T = unknown>(
  method: string,
  options: ClientBridgeCallOptions
): Promise<T>;

function callClientBridge<T = unknown>(
  method: string,
  params?: unknown,
  options?: ClientBridgeCallOptions
): Promise<T>;

function installClientBridge(): ClientBridge;

参数

  • method (string): 客户端方法名,例如 Util.getSkinNameUtil.openURL2external.closeWebDlg
  • params (unknown, 可选): 客户端方法参数。推荐使用具名对象;Util.openURL 等历史方法可传数组
  • options (ClientBridgeCallOptions, 可选): 调用配置。WPF 环境下传 { direct: true } 会跳过 API.use,直接调用 window 上的方法

当第二参是 { direct: boolean } 且没有第三参时,会被识别为 options;如果业务参数本身就是 { direct: true },需要传第三参,例如 ClientBridge.call(method, { direct: true }, {})

返回值

(Promise<T>): 客户端返回值。无返回值的客户端方法会 resolve 为 null

示例

typescript
import { ClientBridge } from '@fu/matrix';

const skinName = await ClientBridge.call<string>('Util.getSkinName');

await ClientBridge.call('Util.openURL2', {
  url: 'https://example.com',
  mode: '24',
  width: 950,
  height: 700,
});

await ClientBridge.call('external.closeWebDlg');

// WPF 无参方法需要绕过 API.use 时,可以把 options 作为第二参
await ClientBridge.call('Util.openBindMobilePhoneNumberUrl', { direct: true });

// WPF 有参方法需要绕过 API.use 时,把 options 作为第三参
await ClientBridge.call('Util.openURL2', { url: 'https://example.com' }, { direct: true });

环境判断

typescript
import { ClientBridge } from '@fu/matrix';

if (ClientBridge.isFinNex) {
  // FinNex 客户端
}

if (ClientBridge.isWpf) {
  // WPF/CefSharp 客户端
}

if (ClientBridge.isClient) {
  // 任意客户端容器
}

const finnexInfo = ClientBridge.getFinnexClientBridgeInfo();
if (finnexInfo.isAvailable) {
  console.log(finnexInfo.protocolVersion);
}

CDN 全局挂载

Matrix 的 CDN 全局变量是 window.fuMatrix。如旧页面需要直接使用 window.ClientBridge,可以在业务代码执行前显式挂载:

html
<script src="https://s.thsi.cn/cd/futures-matrix-frontend/lib/matrix-latest.min.js"></script>
<script>
  window.fuMatrix.installClientBridge();
</script>

之后可直接调用:

javascript
ClientBridge.call('Util.getSkinName').then(function (skinName) {
  console.log(skinName);
});

支持的客户端协议

FinNex

当存在 window.__finnexBridgewindow.__finnexBridge.call 是函数时,会识别为 FinNex 客户端。调用会转发到:

typescript
window.__finnexBridge.call(method, params ?? null)

如需获取 FinNex 桥接对象信息,可调用:

typescript
const info = ClientBridge.getFinnexClientBridgeInfo();
// { isAvailable: true, protocolVersion: '1.0' }

protocolVersion 仅用于展示或调试协议版本,不参与客户端环境判断。

WPF/CefSharp

当存在 window.CefExternal,或 window.Util.getHxVer 是函数时,会识别为 WPF/CefSharp 环境。

  • 默认如果存在 window.API.use,优先使用 API.use 调用;API.use 触发 error 回调时会 rejected,不自动直连兜底
  • 传入 { direct: true } 时会跳过 API.use,直接调用 window 上的方法
  • 直连时解析方法名前缀,调用 window.Util.xxxwindow.external.xxxwindow.FuturesChainsExtra.xxx
  • 直接调用时不包装参数:未传 params 就无参调用,传了 params 就原样作为第一个参数传入,并把同步返回值转成 Promise
  • 无同步返回值、也未触发回调的 fire-and-forget 方法,会在一个 tick 后 resolve 为 null

常用方法

Util

方法名参数返回值
Util.getSkinNamenullstring
Util.isGuestAccountnullboolean
Util.getHxVernullstring
Util.getConnectInfonullstring
Util.getHxProductnullstring
Util.openURL[url, mode, title?]null
Util.openURL2{ url, mode, width?, height? }null
Util.OpenQuestionDlg{ url, ... }null
Util.pictureViewer{ url }null
Util.openBindMobilePhoneNumberUrl{ direct: true }null

FuturesChainsExtra

方法名参数返回值
FuturesChainsExtra.*{ ... }由 WPF window.FuturesChainsExtra.* 方法决定;需要传 { direct: true }

external

方法名参数返回值
external.closeWebDlgnullnull
external.minimizeWindownullnull
external.maximizeWindownullnull
external.setWindowRect{ left, top, width, height }null
external.handleWindow{ action }null
external.showCommunityWindow{ title, url, windowtype }null
external.closePostWindowRightNownullnull
external.showReLoginWindownullnull
external.ReLoginAndShowSmsLoginstringnull
external.openBindMobilePhoneNumberUrlnullnull

注意事项

  • 纯浏览器环境中调用会 rejected,并输出警告
  • 新代码推荐使用 ClientBridge.call,不要直接依赖 window.Utilwindow.externalAPI.use
  • 代码注入时序仍由页面保证:需要在业务桥接调用前加载 Matrix 或执行 installClientBridge