使用createWebMessagePorts是否可以创建多个端口

Web组件中可以用使用createWebMessagePorts进行端口的双向通信的时候,能创建多个端口吗?

HarmonyOS
2024-01-31 10:08:52
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
smallmeteror

可以根据实际业务需求创建多个端口,需要开发者自行管理端口。

示例代码

ArkUI侧

import webview from '@ohos.web.webview' 
 
@Entry 
@Component 
struct WebMessagePortsPage { 
  @State msgFromH5: string = 'Message from HTML' 
  @State msgFromArkUI: string = 'Message from ArkUI' 
  private webviewController: WebviewController = new webview.WebviewController() 
  @State arkUIPortsArr: Array<webview.WebMessagePort> = [] 
  @State h5PortsArr: Array<webview.WebMessagePort> = [] 
 
  aboutToAppear() { 
    webview.WebviewController.setWebDebuggingAccess(true); 
  } 
 
  build() { 
    Column() { 
      Column() { 
        Text(this.msgFromH5) 
          .fontSize(20) 
          .fontWeight(FontWeight.Bold) 
        TextInput({ placeholder: 'Send this message from ArkUI to HTML' }) 
          .onChange((value) => { 
            this.msgFromArkUI = `Message from ArkUI: ${value}`; 
          }) 
        Button('CreateWebMessagePorts').onClick((event: ClickEvent) => { 
          try { 
            const ports = this.webviewController.createWebMessagePorts(); 
 
            this.arkUIPortsArr.push(ports[0]); 
            this.h5PortsArr.push(ports[1]); 
 
            console.info(`Invoke webviewController.createWebMessagePorts succeed! ports number: ${this.h5PortsArr.length - 1}`); 
 
            ports[0].onMessageEvent((result) => { 
              const resultType = typeof result; 
              console.info(`Invoke h5Port${this.h5PortsArr.length - 1}.onMessageEvent! result: ${JSON.stringify(result)}, resultType: ${resultType}`); 
              if (resultType === 'string') { 
                this.msgFromH5 = `Message from HTML: ${result}`; 
              } else if (resultType === 'object' && result instanceof ArrayBuffer) { 
                this.msgFromH5 = `Message from HTML: ${result.byteLength}`; 
              } else { 
                console.error(`Invoke ports[0].onMessageEvent! result type not support!`); 
              } 
            }); 
 
            this.webviewController.postMessage('__init_port__', [ports[1]], '*'); 
          } catch (err) { 
            console.error(`Invoke webviewController.createWebMessagePorts failed! err: ${JSON.stringify(err)}}`); 
          } 
        }) 
        Button('postMessage').onClick((event: ClickEvent) => { 
 
          this.arkUIPortsArr.forEach((arkUIPort, idx) => { 
            try { 
              arkUIPort.postMessageEvent(`Invoke arkUIPort${idx}.postMEssageEvent!  ${this.msgFromArkUI}`); 
              console.info(`Invoke arkUIPort${idx}.postMEssageEvent succeed! msgFromArkUI: ${this.msgFromArkUI}`); 
            } catch (err) { 
              console.error(`Invoke arkUIPort${idx}.postMEssageEvent failed! err: ${JSON.stringify(err)}}`); 
            } 
          }) 
        }) 
      } 
 
      Column() { 
        Web({ src: $rawfile('web/index.html'), controller: this.webviewController }) 
          .width('100%') 
          .height('100%') 
      } 
      .layoutWeight(1) 
    } 
    .width('100%') 
    .height('100%') 
  } 
}

H5侧:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8" /> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0 maximum-scale=1.0, user-scalable=no" /> 
    <title>Document</title> 
    <style> 
      * { 
        margin: 0; 
        padding: 0; 
      } 
      #bg { 
        height: 2560px; 
        background-color: pink; 
        overflow: hidden; 
      } 
      .fx { 
        /* -webkit-display: flex; 
  display: flex; */ 
        margin-left: -20px; 
        margin-right: -20px; 
      } 
      .fx > div { 
        padding-left: 20px; 
        padding-right: 20px; 
      } 
      .fx > div:first-child { 
        width: 30%; 
      } 
      .flex { 
        -webkit-flex: 1; 
        flex: 1; 
      } 
    </style> 
</head> 
<body> 
<div id="bg"> 
    <div class="fx"> 
        <div> 
            <input type="text" name="" id="msgInput" /> 
            <button id="sendMsgBtn">发送</button> 
        </div> 
        <div class="flex"> 
            <pre id="console-log"></pre> 
        </div> 
    </div> 
</div> 
<script> 
      let consoleLog = document.getElementById('console-log'); 
      function logMessage(message) { 
        consoleLog.innerHTML = `${message}<br>` + consoleLog.innerHTML; 
      } 
      const h5PortsArr = []; 
      window.addEventListener('message', e => { 
        logMessage(`Invoke window.message! e: ${JSON.stringify(e)}`); 
        if (e.data === '__init_port__') { 
          const h5Port = e.ports[0]; 
          if (h5Port !== null) { 
            h5Port.onmessage = e => { 
              const msgFromArkUI = e.data; 
              const msgType = typeof msgFromArkUI; 
              if (msgType === 'string') { 
                logMessage(`Received String msg from ArkUI: ${msgFromArkUI}`); 
              } else if (msgType === 'object' && msgFromArkUI instanceof ArrayBuffer) { 
                logMessage(`Recevied ArrayBuffer msg from ArkUI: ${msgFromArkUI.byteLength}`); 
              } else { 
                logMessage(`Recevied not support type msg from ArkUI: ${JSON.stringify(msgFromArkUI)}`); 
              } 
            }; 
            h5PortsArr.push(h5Port); 
          } 
        } 
      }); 
      function postMsg2ArkUI(msg) { 
        if (h5PortsArr.length) { 
          h5PortsArr.forEach((h5Port, idx) => { 
            h5Port.postMessage(`h5Port${idx} msg: ${msg}`); 
          }); 
        } else { 
          console.error(`Invoke postMsg2ArkUI failed! h5Ports is empty, please initialize first`); 
        } 
      } 
      const msgInput = document.getElementById('msgInput'); 
      const sendMsgBtn = document.getElementById('sendMsgBtn'); 
      sendMsgBtn.addEventListener('click', () => { 
        const msgFromH5 = msgInput.value; 
        postMsg2ArkUI(msgFromH5); 
      }); 
    </script> 
</body> 
</html>
分享
微博
QQ
微信
回复
2024-02-01 17:16:58
相关问题
HarmonyOS是否可以申明多个头文件
467浏览 • 1回复 待解决
是否可以同时启动多个编码器
2060浏览 • 1回复 待解决
什么场景需要创建多个UIAbility
1946浏览 • 1回复 待解决
创建多个视频组件无法播放
2255浏览 • 1回复 待解决
TaskPool里面是否可以使用EventHub
1788浏览 • 1回复 待解决
元服务是否可以全程使用js实现
1715浏览 • 1回复 待解决
ohpm仓库地址可以设置多个吗?
182浏览 • 1回复 待解决
HDC是否可以针对模拟器上使用
740浏览 • 1回复 待解决
DevEco Studio 是否支持多个版本并存?
507浏览 • 1回复 待解决