当前位置: 首页 > wzjs >正文

建设网站的推广的软文北京商场招商

建设网站的推广的软文,北京商场招商,wordpress免费,在线做ppt的网站有哪些问题背景 在 electron 开发中,也不可避免地遇到端到端的通信问题,Electron 已经内置一些通信 API,但是实际用下来会发现,在引入 Webview 之后,通信链路会很长,参考 利用本地 Express Web 服务解决复杂的 Elec…

背景

在 electron 开发中,也不可避免地遇到端到端的通信问题,Electron 已经内置一些通信 API,但是实际用下来会发现,在引入 Webview 之后,通信链路会很长,参考  利用本地 Express Web 服务解决复杂的 Electron 通信链路的问题_ipcrenderer.invoke('save-data-CSDN博客的问题, 在这个过程中有一种机制可以有效解决通信链路的问题,这个就是 MessageChannel,MessageChannel 可以提供两个 port,一个自己拿着,另外一个发给别人,以此来实现双向通信,有了这个东西,无论再远的距离,只需要有个中间人帮你把话筒拿给那个人,你们就可以实现互聊。

MessageChannel 在多 iframe 开发上的表现

纯用Grok 实现一个多 iframe 互聊对话框 利用父子框架通信和MessageChannel 实现 n 个 iframe 的动态创建——通用编码习惯-CSDN博客

代码仓库

electron-demo: electron 22 初始代码开发和讲解https://e.gitee.com/sen2020/projects/203933/repos/sen2020/electron-demo/tree/feature%2Fmessageport

feature/messageport 分支

 

Electron 中的概念纠正

  1. Webview 和 Renderer 是同级的,两者只有一个关联关系,也即 Webview 在那个 Renderer 中展现的,Webview 所有运行方式以及通信方式,均与 Renderer 没有任何差别,Webview 可以直接与主进程通信,这个概念特别重要,否则就会绕一大圈,Electron 官网给了一个 sendToHost API,误解性很大,让我们误以为只有 sendToHost 才能与 Webview 依附的渲染通信,然后再中转给其他渲染进程或者 webview 等,实际上完全不需要

  2. 同级这个概念其实在代理拦截,打开外部链接,以及请求头替换等方面都有表现,只是被忽略了

  3. preload.js 代码是被当作一个闭包执行的,如果你在 console 控制台查看时,会发现的确是一个闭包在执行,所以里面的函数和变量你不暴露在 window 上的话,注入 js 是拿不到这些函数,当然前提条件是,去掉上下文隔离。

去掉上下文隔离设置

必备知识

  1. 因为 Electron 主进程是基于 Node.js 环境来运行的,所以并不是 V8 的环境,要想实现类似 Web 环境的 MessageChannel,Electron 就必须自己重新实现,因此 Electron 中的 MessageChannel 类型为 MessageChannelMain,这里为了照顾系统起来后,就会立即推送信息过来,而主进程没有充分启动,导致消息丢失问题,Electron 团队追加了一个 port.start() 函数,也即主进程完全 OK 后,可开启消息消费。

  2. 主进程的MessageChannel 不重要,因为主进程并不创建MessageChannel,只管理来自其他 Renderer 和 Webview 的 channel.port,并将信息进行及时中转,因为所有的其他进程都可以直接联系到主进程,利用 send,invoke,sendSync,postMessage 等 API 都可以与主进程直接通信

  3. Electron 官方很鼓励使用 MessagePort 进行通信,原因是这个通信机制是点对点通信,并不是像监听一样采用广播机制发送消息,在一定意义上对内存的耗费就大大降低了,所以更换 MessagePort 方向是对的

具体实现思路

  1. 在 preload.js 或者任意注入脚本任意位置的组件内部,都可以创建一个 MessageChannel,给自己起一个名字,并把自己注册到主进程去,之后就可以加入到大家庭了

  2. 在渲染进程中的任意一个 Vue 组件里面创建一个 MessageChannel,给自己起个名字,然后注册给主进程,之后就可以加入到大家庭了

  3. 主进程监听来自各个渲染进程和 Webview 组件的 MessageChannel 注册,并实现每个 port 广播和 from to 的中转逻辑即可

实现快照

代码实现

主进程添加以下代码

// 使用 Map 存储 MessagePort,键为名称,值为 MessagePort 对象
const ports = new Map();// 监听渲染进程和 webview 的注册请求
ipcMain.on('register', (event, name) => {const port = event.ports[0]; // 获取传递的 MessagePortif (ports.has(name)) {port.postMessage({type: 'error',data: `Name "${name}" already registered`,});return;}ports.set(name, port);// 监听该 MessagePort 的消息port.on('message', (event) => {const { from, to, data } = event.data;console.log(`Forwarding message from ${from} to ${to}`);if (to === 'all') {// 广播给所有其他 MessagePortports.forEach((p, pName) => {if (pName !== from) {p.postMessage({ from, data });}});} else if (ports.has(to)) {// 转发给指定的 MessagePortports.get(to).postMessage({ from, data });} else {// 目标不存在,发送错误消息ports.get(from).postMessage({type: 'error',data: `Target ${to} not found`,});}});// 监听关闭事件port.on('close', () => {console.log(`${name} 的 MessagePort 已关闭`);ports.delete(name);});// 开始接收消息port.start();// 向注册者发送注册成功消息port.postMessage({ type: 'registered', name });
});

渲染进程添加如下代码,任意位置,代码是通用的,只需要改改 name 即可

// 创建 MessageChannelconst { port1, port2 } = new MessageChannel();const myPort = port2;const myName = "mainWindow"// 将 port1 发送给主进程,附带名称ipcRenderer.postMessage('register', myName, [port1]);// 监听来自主进程的消息myPort.onmessage = (event) => {const { type, from, data } = event.data;console.log(`Received message from ${from}`);if (type === 'registered') {console.log(`注册成功: ${myName}`);} else if (type === 'error') {console.log(`错误: ${data}`);} else {console.log(`[${from}]: ${data}`);}};// 发送消息给另一个进程function sendMessage(to, data) {myPort.postMessage({ from: myName, to, data });}// 发送广播消息function broadcastMessage(data) {myPort.postMessage({ from: myName, to: 'all', data });}window.sendMessage = sendMessage;window.broadcastMessage = broadcastMessage;// 示例用法setTimeout(() => {sendMessage('wb1', 'Hello from renderer1!');broadcastMessage('Broadcast from renderer1!');}, 10000);}

preload.js 中的实现代码,基本和渲染进程是一样的

// 因为WhatsApp也有个require函数,这里会干扰WhatsApp加载
delete window.require; // 这里是node.js环境,必须用require引入
const {ipcRenderer} = require("electron") ; 
// 创建 MessageChannel
const { port1, port2 } = new MessageChannel();
window.myPort = port2;
window.myName = "wb1"// 将 port1 发送给主进程,附带名称
ipcRenderer.postMessage('register', myName, [port1]);// 监听来自主进程的消息
myPort.onmessage = (event) => {const { type, from, data } = event.data;console.log(`Received message from ${from}`);if (type === 'registered') {console.log(`注册成功: ${myName}`);} else if (type === 'error') {console.log(`错误: ${data}`);} else {console.log(`[${from}]: ${data}`);}
};// 发送消息给另一个进程
function sendMessage(to, data) {myPort.postMessage({ from: myName, to, data });
}window.sendMessage = sendMessage;// 发送广播消息
function broadcastMessage(data) {myPort.postMessage({ from: myName, to: 'all', data });
}window.broadcastMessage = broadcastMessage;// 示例用法
setTimeout(() => {sendMessage('mainWindow', 'Hello from renderer1!');broadcastMessage('Broadcast from renderer1!');
}, 2000);

http://www.dtcms.com/wzjs/596091.html

相关文章:

  • wordpress主页显示关键词优化的策略
  • 公司定制网站建设公司专门做孕婴用品的网站
  • 网站栏目名seo推广优化
  • 番禺网站建设三杰科技中国建设银行网站的主要功能
  • 网站建设费用上海合肥晚报社官方网站
  • 如何提高网站加载速度慢wordpress文章tags
  • 目录网站做外链长沙seo培训
  • 如何建网站免费网站建设项目数
  • 网站建设投票主题cps广告是什么意思
  • 兰州网站建设和维护工作wordpress模板网
  • 哪些网站做的比较好看的图片唯品会网站建设数据安全分析
  • 网站开发公司哪里好网络优化大师手机版
  • 青海营销网站建设服务一元购网站开发
  • 30分钟seo网站淄博城乡建设局网站
  • 花生壳做网站需要备案值得买wordpress
  • 怎样做内网网站安徽建设局网站
  • 重庆家政网站建设网站建设项目验收表
  • 宁波网站建设哪里有手机微信网站链接
  • flash企业网站源码中国域名注册中心
  • 狍与女人做爰网站如何制作个人网站教程
  • 网站优化 图片百度关键词排名代发
  • 重庆一站式建设网站平台市场咨询公司排名
  • 墨鱼网站建设合肥企业网站推广
  • 房产类网站建设英国做暧小视频网站
  • 怎么做企业网站教程视频足球直播网站怎么做的
  • 张家港杨舍网站制作广州品牌型网站建设
  • 重庆网站推广什么个人 网站建设
  • 郑州企业网站制作艺术字logo生成器
  • app网站开发小程序做交通事故的网站
  • 网站开发过程 知乎老版本网站开发工具