开发专题
队列
RabbitMQ消息队列
redis+mq实现秒杀功能
非结构化存储OSS
使用minio进行数据存储
非结构化文档在线预览
使用kkfileView实现在线文档预览
OnlyOffice实现文档在线编辑
全文搜索
Elasticsearch构建全文搜索系统
windowns下使用Logstash7.6.2同步Mysql数据到ElasticSearch,并使用kibana进行检索
工作流Flowable应用
Flowable基础入门知识
Springboot+mybatisplus+flowable6.5.0 开发房产审批模块
人脸识别
虹软人脸识别应用
人脸识别基础入门知识
WebSocket在线聊天
Springboot+WebSocket+redis实现在线客服系统
WebSocket基础入门
信创产业
领域驱动DDD
定时任务quartz
流媒体
流媒体服务LALMAX的部署安装与使用
使用go2rtc+webrtc-streamer在网页上播放rtsp 的摄像头视频
RPA数字员工
使用盘匠设计器进行RPA项目的开发
RPA开发过程中的一些经验之谈
业务系统
litemall开源商城
dbblog开源博客
electron-egg关于通信部分的一些补充
本文档使用 MrDoc 发布
-
+
首页
electron-egg关于通信部分的一些补充
electron-egg这个框架 开发桌面应用是一个不错的选择,但是在第一次使用的时候,他的那文档看得让人很迷糊。 前端 和 业务层 通过以下三种方式通信: - ipc - http/https - socket ## 单向通信: ~~~ # 定义通信频道,即路由 const ipcApiRoute = { hello: 'controller/example/hello', } # 发送请求 # 该请求会访问 controller/example.js文件的hello函数 import { ipc } from '@/utils/ipcRenderer'; ipc.invoke(ipcApiRoute.hello, {name:'张三'}).then(r => { // r为返回的数据 conson.log(r); }) ~~~ 就上面这一段代码就真的看懵逼了,, “定义通信频道,即路由” 比如这个ipcApiRoute 是定义在哪里?? 前端 还是业务层?? 可能 对于使用过electron-egg 的老鸟很清楚,但是第一次使用这个框架的人,只能去demo代码里去搜。。 具体是: frontend/src/api/index.js 里定义: ~~~ const ipcApiRoute = { example: { test: 'controller/example/test', }, ~~~ 下面这段代码同样是,不知道在哪定义。 ~~~ # 发送请求 # 该请求会访问 controller/example.js文件的hello函数 import { ipc } from '@/utils/ipcRenderer'; ipc.invoke(ipcApiRoute.hello, {name:'张三'}).then(r => { // r为返回的数据 conson.log(r); }) ~~~ 这个是定义前端的vue文件里,比如: `frontend\src\views\framework\demo\test.vue` **但是上面的代码漏写了一行: `import { ipcApiRoute } from '@/api';` 同时 conson.log(r); 。。。眼神不好的,,都不知道问题出在哪,,console拼写错了!! 应该是:`console.log(r)`** 完整代码是: ~~~ <script setup> import { ipcApiRoute } from '@/api'; import { ipc } from '@/utils/ipcRenderer'; const showMessage = () => { ipc.invoke(ipcApiRoute.hello, {name:'张三'}).then(r => { // r为返回的数据 console.log(r); }) } </script> ~~~ 执行报错: >d Error: Error invoking remote method 'controller/example/hello': Error: No handler registered for 'controller/example/hello' 原因是:主进程(Main)中没有使用 ipcMain.handle 注册对应的处理函数 electron-egg的写法是: 在 electron\controller\example.js 的 ExampleController 中 添加 : ~~~ async hello () { return 'hello electron-egg'; } ~~~ 添加下面的代码看看弹窗的效果: ~~~ showMessageBox(message) { const { dialog } = require('electron') dialog.showMessageBox({ type: 'info', title: '提示', message: '来自渲染进程的消息', detail: message }) } /** * test */ async hello () { this.showMessageBox('hello electron-egg') return 'hello electron-egg'; } ~~~  ## 双向通信 官方文档里的代码: ~~~ # 定义通信频道,即路由 const ipcApiRoute = { ipcSendMsg: 'controller/example/ipcSendMsg', } // 避免重复监听,或者将 $ipc.on() 功能写到一个统一的地方,只加载一次 ipc.removeAllListeners(ipcApiRoute.ipcSendMsg); // 监听,接收 服务端 event.reply()发送的数据 ipc.on(ipcApiRoute.ipcSendMsg, (event, result) => { console.log('[ipcRenderer] [ipcSendMsg] result:', result); self.messageString = result; // 调用后端的另一个接口 event.sender.send(ipcApiRoute.hello, 'electron-egg'); }) // 发送请求到服务端 ipc.send(ipcApiRoute.ipcSendMsg, '参数') ~~~ 解析一下: 上面的代码的完整流程是这样的。。 下面的代码都是在 在前端的vue页面里。 第一步: 定义一个按钮的点击事件。执行下面的函数: ~~~ function sendMsgStart() { const params = { type: 'start', content: '开始' } ipc.send(ipcApiRoute.ipcSendMsg, params) } ~~~ ipcApiRoute.ipcSendMsg 这个是从api引用进来的,就不用多说了吧? 第二步: ~~~ onMounted(() => { init() }) ~~~ 执行一个初始化的方法。 ~~~ const messageString = ref(''); function init() { // 避免重复监听,或者将 on 功能写到一个统一的地方,只加载一次 ipc.removeAllListeners(ipcApiRoute.ipcSendMsg); ipc.on(ipcApiRoute.ipcSendMsg, (event, result) => { console.log('[ipcRenderer] [socketMsgStart] result:', result); messageString.value = result; // 调用后端的另一个接口 - 根据实际业务添加 // event.sender.send(ipcApiRoute.hello, 'electron-egg'); }) } ~~~ 第三步:注意一下,下面代码不是前端了。 而是在electron/controller/framework.js文件里,添加下面的方法: ~~~ /** * 双向异步通信 */ ipcSendMsg(args, event) { const { type, content } = args; const channel = 'controller/framework/ipcSendMsg'; if (type == 'start') { // 每隔1秒,向前端页面发送消息 // 用定时器模拟 this.myTimer = setInterval(function(e, c, msg) { let now = Date.now(); let data = msg + ':' + now; e.reply(c, data) }, 1000, event, channel, content) return '开始了' } else if (type == 'end') { clearInterval(this.myTimer); return '停止了' } else { return 'ohther' } // 这里建议把代码封装到service层 // const data = frameworkService.bothWayMessage(type, content, event); // return data; } ~~~ 这里的 myTimer 定义在全局,也就是 在 FrameworkController中。 但是myTimer好像定义了全局也没有用,定时器stop不了 ~~~ class FrameworkController { constructor() { // 在构造函数中初始化一些变量 this.myTimer = null; } ~~~
superadmin
2025年10月2日 21:29
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码