electronjs入门-聊天应用程序,与Electron.js通信
随着第一章中构建的应用程序,我们将开始将其与Electron框架中的模块集成,并以此为基础,以更实用的方式了解它们。
过程之间的通信
根据第二章中的解释,我们将发送每个进程之间的消息;具体来说联系人和聊天;这些数据将在主过程中定义,因为这是负责处理这些数据的过程我们之前已经将其与中使用的客户端-服务器体系结构进行了比较web编程,主要过程已经是服务器和网页一直是客户端,它是从我们可以管理所有这些数据,正如我们将在整本书中看到的那样第一次联系,我们将了解如何从主进程处理到网页。
上传联系人和聊天
为了传递主流程中定义的数据,我们将使用以下结构;数据将从主进程中获得,为了模拟数据库等外部结构,我们将创建一个单独的文件到index.js,该文件将负责提供数据,我们将使用数据创建几个模块,使其易于使用:data.js
const contacts = [{name: "Alex Alexis",image: "https://randomuser.me/api/portraits/women/56.jpg",last_chat: [{date: "9:15 AM",message: "Lorem ipsum dolor sit amet",},],},{name: "Eli Barrett",image: "https://randomuser.me/api/portraits/women/96.jpg",last_chat: [{date: "8:30 PM",message: "Lorem ipsum dolor sit amet",},],},{name: "Kylie Young",image: "https://randomuser.me/api/portraits/women/45.jpg",last_chat: [{date: "8:30 PM",message: "Lorem ipsum dolor sit amet",},],},{name: "Kylie Young",image: "https://randomuser.me/api/portraits/women/45.jpg",last_chat: [{date: "8:30 PM",message: "Lorem ipsum dolor sit amet",},],},
];
const chats = [{user: {name: "Alex Alexis",image: "https://randomuser.me/api/portraits/women/56.jpg",},chat: {date: "9:15 AM",message:"Lorem ipsum dolor sit amet consectetur adipisicing elit.Doloribus reprehenderit voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque? Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?",},},{user: {name: "Eli Barrett",image: "https://randomuser.me/api/portraits/women/58.jpg",},chat: {date: "9:50 AM",message:"Lorem ipsum dolor sit amet consectetur adipisicing elit.Doloribus reprehenderit voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque? Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?",},},
];module.exports.contacts = contacts;
module.exports.chats = chats;
从“index.js”,我们激活与Node的集成并消费它们;我们定义了一个事件,在该事件中,当通过“did-finish-load”事件加载窗口(网页)时,我们通过消息传输数据:
const { app, BrowserWindow, Menu, shell } = require("electron");
const { chats, contacts } = require("./data");function createWindow() {let win = new BrowserWindow({width: 800,height: 600,webPreferences: {nodeIntegration: true,contextIsolation: false,},});win.loadFile("index.html");win.webContents.openDevTools();win.webContents.on("did-finish-load", () => {win.webContents.send("pr-chats", chats);win.webContents.send("pr-contacts", contacts);});
}
app.whenReady().then(createWindow);
从网页上,由于我们激活了与Node的集成,我们可以导入ipcRenderer模块,以便能够与主进程通信,特别是,我们有兴趣创建一个侦听器来接收主进程发送的数据:
index.html
<script>function createChats(chats) {var lis = ''chats.forEach((c) => {lis += ` <div class="d-flex chat"><div class="w-75 "><div class="card bg-dark"><div class="card-body text-light">${c.chat.message}</div></div><p class="small text-muted float-end">${c.chat.date}</p></div><div class="w-25 d-flex align-items-end"><img class="rounded-pill ms-3 avatar" src="${c.user.image}"/></div></div>`})document.querySelector('.chats').innerHTML = lis;}function createContacts(contacts) {var lis = ''contacts.forEach((c) => {lis += `<li class="p-2 card mt-2"><div class="card-body"><div class="d-flex"><div><img class="rounded-pill me-3" width="60"src="${c.image}"></div><div><p class="fw-bold mb-0 text-light">${c.name}</p><p class="small text-muted">${c.last_chat[0]['message']}
</p></div><div><p class="small text-muted">${c.last_chat[0]['date']}</p><span class="badge bg-danger rounded-pill float-end">1</span></div></div></div></li>`})document.querySelector('.contact').innerHTML = lis;}const { ipcRenderer } = require('electron')ipcRenderer.on('pr-chats', (event, chats) => {createChats(chats)})ipcRenderer.on('pr-contacts', (event, contacts) => {createContacts(contacts)})
</script>

根据具体情况,我们稍微更改函数的签名,在该签名中,我们接收图表或联系人作为参数。我们调用这些函数来从先前定义的侦听器构建列表;最后,我们将得到相同的结果,但现在数据从主进程进入渲染进程。
按选择加载联系人
在本节中,我们将实现以下功能:通过单击其中一个联系人,加载与所述联系人对应的聊天或消息;为了模拟这种行为,我们将使用联系人数组索引,就好像它是我们有兴趣获得聊天记录的联系人的ID一样;为此,我们实现了一个点击事件:

以及函数,我们调用主进程来提供基于ID的聊天:
function changeContact(index) {ipcRenderer.send('pp-get-chat', index)}
在数据拉取中,我们将稍微改变结构,我们将有一个数组,其中数组的每个位置都将由上一条消息中提供的联系人索引访问:
const contacts = [{name: "Alex Alexis",image: "https://randomuser.me/api/portraits/women/56.jpg",last_chat: [{date: "9:15 AM",message: "Lorem ipsum dolor sit amet consectetur adipisicing elit",},],},{name: "Ramon Reed",image: "https://randomuser.me/api/portraits/women/59.jpg",last_chat: [{date: "9:15 AM",message: "Lorem Hello!",},],},{name: "Eli Barrett",image: "https://randomuser.me/api/portraits/women/58.jpg",last_chat: [{date: "8:55 PM",message: "Lorem ipsum dolor sit ...",},],},
];
const chats = [[{user: {name: "Alex Alexis",image: "https://randomuser.me/api/portraits/women/56.jpg",},chat: {date: "9:15 AM",message:"Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus reprehenderit voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque? Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?",},},{user: {name: "Luis Perez",image: "https://randomuser.me/api/portraits/women/58.jpg",},chat: {date: "9:50 AM",message:"Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus reprehenderit voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque? Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?",},},],[],[{user: {name: "Anselmo Perez",image: "https://randomuser.me/api/portraits/women/1.jpg",},chat: {date: "10:45 PM",message:"Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus reprehenderit voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque? Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?",},},],
];module.exports.contacts = contacts;
module.exports.chats = chats;
我们实现了从ipcRenderer发送的事件,其中,将接收到的索引作为参数,返回相应的聊天:
index.js
const { ipcMain } = require("electron");
win.webContents.on("did-finish-load", () => {//win.webContents.send("pr-chats", chats);win.webContents.send("pr-contacts", contacts);
});
ipcMain.on('pp-get-chat', (event, index) => {win.webContents.send('pr-chats', chats[index])
})
当所选联系人没有聊天时,我们还会显示一个默认窗口:
function createChats(chats) {var lis = ''if (chats.length == 0) {lis += ` <div class="d-flex chat"><div class="w-75 "><div class="card bg-dark"><div class="card-body text-light"><h3 class='text-center'>No message</h3></div></div></div></div>`}else {chats.forEach((c) => {lis += ` <div class="d-flex chat"><div class="w-75 "><div class="card bg-dark"><div class="card-body text-light">${c.chat.message}</div></div><p class="small text-muted float-end">${c.chat.date}</p></div><div class="w-25 d-flex align-items-end"><img class="rounded-pill ms-3 avatar" src="${c.user.image}"/></div></div>`})}document.querySelector('.chats').innerHTML = lis;}
这样,在选择联系人时,我们会改变显示的消息或聊天,并完成骨架应用程序;您可以在以下位置找到源代码:
https://github.com/libredesarrollo/electron-chat-app/releases/tag/v0.1
相关文章:
electronjs入门-聊天应用程序,与Electron.js通信
随着第一章中构建的应用程序,我们将开始将其与Electron框架中的模块集成,并以此为基础,以更实用的方式了解它们。 过程之间的通信 根据第二章中的解释,我们将发送每个进程之间的消息;具体来说联系人和聊天࿱…...
【自用】ubuntu 18.04 LTS安装opencv 3.4.16 + opencv_contrib 3.4.16
1.下载 opencv 3.4.16 opencv_contrib 3.4.16 其中,opencv_contrib解压后的多个文件夹复制到opencv内、合并 声明:尚未验证该方式是否可行 2.安装 参考博文: https://zhuanlan.zhihu.com/p/650792342 https://zhuanlan.zhihu.com/p/8719780…...
递归解析Json,实现生成可视化Tree+快速获取JsonPath | 京东云技术团队
内部平台的一个小功能点的实现过程,分享给大家: 递归解析Json,可以实现生成可视化Tree快速获取JsonPath。 步骤: 1.利用JsonPath读取根,获取JsonObject 2.递归层次遍历JsonObjec,保存结点信息 3.利用z…...
GraceUI相关的 知识
调试工具:UniApp提供了一些调试工具和插件,如uni-app-cli、调试器等,可以帮助你更好地定位和解决问题。同时,使用浏览器的开发者工具或模拟器的调试功能,可以更直观地观察页面效果和调试代码。 对于 GraceUI 的普通版本…...
三十二、【进阶】hash索引结构
1、hash索引结构 (1)简述: hash索引,就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中。 (2)图示: 2、hash索引结构…...
如果有一天AI能自主编程了,程序员还有前途吗?
人们一直想知道人工智能(AI)等新技术将如何影响就业。如今的一个大问题是:人工智能会接管程序员的角色吗? 编程主要是关于人们学习计算机语言,这需要大量的时间和努力。但人工智能正在改变这一点。像 GPT-4 这样的系统…...
网络安全:个人信息保护,企业信息安全,国家网络安全的重要性
在当前的数字化时代,无论是个人,企业,还是国家,都会面临严重的网络安全威胁。网络安全不仅涉及我们的日常生活,也涉及到社会的稳定和国家的安全。这就需要我们高度重视网络安全,强化个人信息保护࿰…...
自动驾驶学习笔记(二)——Apollo入门
#Apollo开发者# 学习课程的传送门如下,当您也准备学习自动驾驶时,可以和我一同前往: 《自动驾驶新人之旅》免费课程—> 传送门 《2023星火培训【感知专项营】》免费课程—>传送门 文章目录 前言 Ubuntu Linux文件系统 Linux指令…...
Flask 进行 Web 开发时,常见的错误
ImportError: No module named ‘flask’ 错误描述: 这个错误表示 Python 找不到 Flask 模块。解决方法: 确保已经正确安装了 Flask 模块。你可以使用以下命令来安装 Flask:pip install flaskAttributeError: ‘module’ object has no attri…...
【项目】5.1阻塞和非阻塞、同步和异步 5.2Unix、Linux上的五种IO模型
5.1阻塞和非阻塞、同步和异步(网络IO) 典型的一次IO的两个阶段是什么?数据就绪和数据读写 数据就绪:根据IO操作的就绪状态 阻塞非阻塞 数据读写:根据应用程序和内核的交互方式 同步异步 陈硕:在处理IO的…...
Unity可视化Shader工具ASE介绍——3、ASE的Shader类型介绍
大家好,我是阿赵。这里继续介绍Unity可视化Shader编辑插件ASE的用法。 上一篇介绍了节点的输入输出节点。这一篇来介绍一下不同的Shader类型的区别。 一、修改Shader类型 之前介绍创建Shader的时候,曾经说过可以选择Shader的类型。 其实这个类型是…...
国内手机安装 Google Play 服务 (GMS/Google Mobile Services)
目录 1. 国内手机安装 Google Play 服务 (GMS/Google Mobile Services)1.1. 什么是 GMS1.2. 国内手机只需要安装 3 个 APP1.2.1. Google Services Framework 服务框架1.2.2. Google Play Services1.2.3. Google Play Store 应用商店 1.3. 问题1.3.1. 谷歌地图闪退 2. 小米手机 …...
数据结构与算法-(7)---栈的应用-(4)后缀表达式求值
🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如…...
[VIM]spcaevim
Home | SpaceVim SpaceVim - 知乎 关于Vim/Neovim/SpaceVim的一些思考 - 知乎 vim高配版(1) – SpaceVim 简介 SpaceVim 是国内的一个大佬将一些NB的插件整合到一起的一个插件包. 一键式安装, 功能强大. 官网参见 Home | SpaceVim vim高配版(2) – vimplus 简介 vimplu…...
Android中的RxJava入门及常用操作符
文章目录 1.定义2.作用3.特点4.使用4.1创建被观察者(Observable)4.2创建观察者(Observer)4.3订阅(Subscribe)4.4Dispose 5.操作符5.1操作符类型5.2just操作符5.2链式调用5.3 fromArray操作符5.4 fromIterab…...
【数字化转型】10大数字化转型能力成熟度模型03
一、前言 数字化转型是数据化能力建设的目标和价值,作为一个新兴的课题,目前为止并未出现一个统一的数字化转型成熟度模型。不同的企业和机构,根据自身的发展和认知,推出了自己的企业级或者准行业级标准。这些标准具有很强的参考意义,作者收集和整理了相关的标准和规范,整…...
【算法与数据结构】--前言
欢迎来到《算法与数据结构》专栏!这个专栏将引领您进入计算机科学领域中最重要、最精彩的领域之一:算法与数据结构。不管您是一名初学者,还是已经拥有一定编程经验的开发者,都可以从这里找到有益的知识和实践。 在计算机科学的世…...
R²决定系数
R 2 R^2 R2(决定系数)是一个用于衡量统计模型拟合数据的指标,通常用于线性回归分析。它表示模型所解释的因变量(目标变量)方差的比例,范围从0到1。 更具体地说, R 2 R^2 R2告诉我们模型能够解释…...
软件工程与计算总结(一)软件工程基础
国庆快乐,今天开始更新《软件工程与计算(卷二)》的重要知识点内容~ 一.软件 1.软件独立于硬件 早期的软件是为了计算机硬件在研究型项目中而开发制造的,人们使用专门针对于硬件的指令码和汇编语言编写,这也是最早软件…...
SpringBoot-黑马程序员-学习笔记(一)
8.pom文件中的parent 我们使用普通maven项目导入依赖时,通常需要在导入依赖的时候指定版本号,而springboot项目不需要指定版本号,会根据当前springboot的版本来下载对应的最稳定的依赖版本。 点开pom文件会看到这个: 继承了一个…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
