BioforestChain / dweb_browser

BioforestChain Infrastructure
https://docs.dweb-browser.org
MIT License
11 stars 4 forks source link

【提案】dwebview获得直接和其它模块的通讯能力 #186

Open Gaubee opened 1 month ago

Gaubee commented 1 month ago
  1. 发现问题:
    1. dweb-deeplink 目前是直接做 200 返回,而不是有完整的 Response。因此如果有获得 dweb-deeplink 真实响应的需求(比方说想要知道处理了多久,真正的错误码是多少,错误信息是什么等),就需要有完整的 nativeFetch 的能力
    2. 目前 plaoc 的 api-server 并没有做什么特别的处理,只是单纯做了转发而已。但这些请求都要经由 https-reverse-proxy 来转发,逻辑路径较长,延迟高,性能低。尽管对 body 做了引用转发来减少了很多不必要的内容传输,但是像二维码扫描这种需求,会非常占用资源。
  2. 解决问题的推理过程:
    1. 考虑开放类似 navigator.dweb.nativeFetch 这样的接口能力。
    2. 但是这样的接口功能性太强了,基本上是全部的通讯能力,而且这背后其实是 ipc.postMessage/ipc.onMessage,而 ipc 都在后端,如果强行在 dwebview 这侧再连接一个,将违背单一原则,导致更多的问题。
    3. 我们并不需要完整的 ipc 能力,同时也不能违背单一原则;归根结底我们要做到的是让 ipcClientRequest 发送到位,然后将 ipcServerResponse 处理到位就行。
    4. 因此可以参考 webview.addJavascriptInterface 这个接口设计,原本到设计是需要开发者注入一个函数句柄,本质上,它是由一个:函数地址+函数参数+函数返回 组成的抽象,
    5. 于是,我们可以设计成声明式的接口设计:webview.sys.dweb/addJavaScriptInterface?path=${FUN_NAME}&interface_address=${IPC_METHOD+IPC_URL}&interface_params=${IPC_REQUEST}&interface_return=${IPC_RESPONSE_DECODE_TYPE}&api_sign=${IPC_SIGN}
    6. 简单说,就是让 webviewNMM 这个模块来直接发送 IpcClientRequest 对象,这在理论上是完全可以的。这固然会丢失原始的发送者的信息,于是 api_sign 的参数的目的就是在这里,用来附加原始发送者的签名。
    7. 或者我们可以用这个 api_sign 来做 fork 时候的验证,有了一个独立的 pid,生命周期会更加可靠。
    8. 数据返回后,就是靠 interface_return 这个声明来处理数据,提供一些内置的解码方案,比方说:text(utf-8 的解码)、binary(原始值不做解码)、number、boolean、void(不解码,空返回)等等。
    9. 这个方案不能解决所有的问题(比如 ipcChannel),但是可以满足绝大多数的请求发送。通常来说只要原本的 ipc 接口设计合理,那么基本上 api-server 就不再需要。
    10. 而且这个方案的能力是完全由后端决定,这就意味着要开放多少接口给 dwebview,是由后端决定,后端随时可以关闭某些接口,从而避免安全问题。