如何使用createWebMessagePorts、postMessage进行端口通信,能创建多个端口吗

如何使用createWebMessagePorts、postMessage进行端口通信,能创建多个端口吗

HarmonyOS
2024-03-17 17:38:43
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
coolhead2000

应用侧页面中通过createWebMessagePorts方法创建消息端口,再把其中一个端口通过postMessage()接口发送到前端页面,便可以在前端页面和应用侧之间互相发送消息。

完整代码参考可以参考建立应用侧与前端页面数据通道

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

参考代码如下:

ArkUI侧:

import { webview } from '@kit.ArkWeb' 
 
@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('hello.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-03-18 21:16:05
相关问题
HarmonyOS Web调试页面转发端口问题
73浏览 • 1回复 待解决
华为交换机如何配置端口绑定mac或ip
7785浏览 • 0回复 待解决
Windows和Mac OS关闭指定端口应用的方法
5854浏览 • 1回复 待解决
TaskPool如何跟主线程进行通信
600浏览 • 1回复 待解决
HarmonyOS HAP之间如何进行通信
478浏览 • 1回复 待解决