electron + go 如何从sqlite获取数据
我现在的数据在sqlite中,保存在mac本地的一个文件中。用了electron+vue搭建了一个客户端。
我大概希望是这样的逻辑,先加载本地db文件,然后再获取数据。
这里就有一个问题,我怎么获取sqlite中的数据呢?从哪里加载呢?
思考
electron的进程分为master Process 和 renderer Process。这个事情是哪个Process来做呢?
我觉得这里可能有好几种方案。
首先第一种,直接从RendererProcess来,这就和浏览器要直接访问本地文件的逻辑一样了。肯定可以做,不过感觉会很不安全。
第二种,就是MainProcess来读取本地文件,然后传递到Renderer来显示。这个其实是更符合electron的设计思路。因为mainProcess就是用来处理和本机的连接的。
其实还有第三种,就是启动一个本地服务器,来读取sqlite,提供接口出来给RendererProcess。然后RendererProcess就和正常的js调用接口一样,调用这个本地服务器。这个的好处就是这个本地服务器可以用其他语言来做,这里我非常希望用golang来实现。其次,这个本地服务器其实很容易修改为远端服务器。
所以我想尝试一下第三种方式来实现。
尝试eletron+go
这个方案和hade的设计思路是一致的,hade可以构建前端eletron,再构建一个后端go的二进制文件,然后eletron打包的时候把后端go的二进制文件打包进去。
那么这里就遇到第一个问题,如何在eletron中打包一个二进制文件,并且启动它呢?
如何在eletron中打包二进制文件?
找了一些资料,特别是这篇文章:
尝试了一下,真的是可行的。
首先我用golang编译出二进制文件叫toolbox-server
然后存放的目录是resources/mac/toolbox-server:
接着修改vue.config.js文件(这个修改的文件如果你没有使用vue来编译electron的话,你就修改package.json)
package.json增加字段:
"extraFiles": [
{
"from": "resources/${os}",
"to": "Resources/bin",
"filter": [
"**/*"
]
}
]
vue.config.js修改字段:
...
module.exports = defineConfig({
...
pluginOptions: {
electronBuilder: {
builderOptions: {
extraFiles: [
{
"from": "resources/${os}",
"to": "Resources/bin",
"filter": [
"**/*"
]
}
],
}
}
}
})
不管是在vue.config.js还是在package.json中修改,都以为着告诉electron打包程序,我需要把resources/${os}/下的所有文件放到打包后的Resources/bin文件下。
然后在我们的electron的main.js(在我项目中是background.js)。都是代表electron的主进程。
在app的ready事件中,我注入了以下代码:
import appRootDir from 'app-root-dir';
const log = require('electron-log');
...
app.on('ready', async () => {
if (isDevelopment && !process.env.IS_TEST) {
// Install Vue Devtools
try {
await installExtension(VUEJS3_DEVTOOLS)
} catch (e) {
log.error('Vue Devtools failed to install:', e.toString())
}
}
createWindow()
const execPath = (!isDevelopment) ?
joinPath(appRootDir.get(), 'bin') :
joinPath(appRootDir.get(), 'resources', getPlatform());
const cmd = `${joinPath(execPath, 'toolbox-server')}` + ' app start';
log.info(cmd);
exec(cmd, (err, stdout, stderr) => {
if (err != null) {
log.error('run error' + err.toString());
}
log.log('stdout:' + stdout.toString());
log.error('stderr:' + stderr.toString());
});
})
其中的log包我使用的是 electron-log。这样才能最后在编译的时候,把日志打印到
~/Library/Logs/{app_name}/
对于execPath我们可以再看下,这里使用了 app-root-dir 包,它对应的 appRootDir.get() 方法在运行的时候,对应的目录为:
/Applications/{app_name}.app/Contents/Resources/
其实这里我琢磨可能不用app-root-dir包也行,直接用electron的app带的各种路径方法(https://www.electronjs.org/zh/docs/latest/api/app),不过这里我没有继续尝试了。
然后使用npm run electron:build
就可以看到生成打包文件。
安装打包文件,通过应用程序-{app_name}-Content可以看到二进制的Golang文件就在这里面了。
同时如果你在调试模式下使用 npm run electron:serve
, 可以看到在electron启动的同时,这个进程也就起来了。
![image-20230101165421154](../../../Library/Application Support/typora-user-images/image-20230101165421154.png)
且端口在localhost中可用
打包二进制文件进electron完成。
ps: 研究这个过程中,这篇(https://ld246.com/article/1547556984481)对我的帮助很大,mark下。
golang实现的http接口
剩下的就很简单了,golang写一个http接口,读取sqlite。
我使用hade框架,
很快就可以完成类似的接口
http://127.0.0.1:8070/essay/list
这里就没有什么好说的了。
electron的renderer调用server获取数据展示
这个也没有什么好说的了,就是基本的vue来调用http获取数据。
fetchData() {
request({
url: "/essay/list?page=" + this.next_page + "&size=" + this.size,
method: "get",
}).then((res) => {
console.log(res);
if (res.status === 200) {
if (res.data.list.length === 0) {
this.noMore = true;
return;
}
for (let i= 0; i < res.data.list.length; i++) {
this.data.push(res.data.list[i])
}
this.page = this.next_page;
this.next_page = this.next_page + 1;
this.loading = false;
}
});
},
二进制打包还有一些问题
二进制打包这里还有一些问题,在打包的时候,需要配置文件,但是我目前是没有的。这个怎么办呢?
还有就是toolbox-server会生成运行时文件,都在storage里面,这个怎么办呢?
打包配置文件
首先我把配置文件也都复制到resources中。
![image-20230102125854304](../../../Library/Application Support/typora-user-images/image-20230102125854304.png)
这样vue.config.js中复制的时候也会把整个目录进行拷贝。
接着由于我的程序运行的时候需要在toolbox-server同级目录运行,所以我修改了一下启动toolbox-server 的程序;
async function startToolboxServer() {
const execPath = (!isDevelopment) ?
joinPath(appRootDir.get(), 'bin', 'toolbox-server') :
joinPath(appRootDir.get());
const cmd = `cd ${execPath} && ${joinPath(execPath, 'toolbox-server')}` + ' app start';
log.info(cmd);
exec(cmd, (err, stdout, stderr) => {
if (err != null) {
log.error('run error' + err.toString());
}
log.log('stdout:' + stdout.toString());
log.error('stderr:' + stderr.toString());
});
}
这里主要加上了cd ${execPath}
目录。
运行日志放在应用对应的日志目录中
eletron对应的日志目录为:~/Library/Logs/{app_name}/
我们希望在这个目录下能创建一个子目录toolbox-server,把toolbox-server的运行日志放在里面。即(~/Library/Logs/toolbox/toolbox-server/)
这里就首先需要 toolbox-server 这个程序是支持修改运行日志的。
所幸hade框架是支持环境变量设置运行日志:
http://hade.funaio.cn/guide/app.html#进程运行基础配置
STORAGE_FOLDER=/Users/jianfengye/Documents/workspace/gohade/hade/teststorage ./hade app start
所以我可以通过在electron的主进程启动toolbox-server的地方设置环境变量来达到这个目的。
我修改了一下startToolboxServer 启动toolbox-server的函数
async function startToolboxServer() {
const execPath = (!isDevelopment) ?
joinPath(appRootDir.get(), 'bin', 'toolbox-server') :
joinPath(appRootDir.get());
const cmd = `cd ${execPath} && ${joinPath(execPath, 'toolbox-server')}` + ' app start';
let logFolder = joinPath(app.getPath("logs"), "toolbox-server");
let envVars = {...process.env}
if (!isDevelopment) {
envVars = { ...process.env, STORAGE_FOLDER: logFolder}
}
log.info("cmd: " + cmd + ", env: " + JSON.stringify({STORAGE_FOLDER : logFolder}));
exec(cmd, {env: envVars}, (err, stdout, stderr) => {
if (err != null) {
log.error('run error' + err.toString());
}
log.log('stdout:' + stdout.toString());
log.error('stderr:' + stderr.toString());
});
}
主要是在正式环境中把STORAGE_FOLDER的环境变量设置为 joinPath(app.getPath("logs"), "toolbox-server")
这里的exec是child_prcess包的函数,增加env的方法可以参考:https://nodejs.org/api/child_process.html
这里的app.getPath("logs") 是electron自带的方法,具体可以参考:https://www.electronjs.org/zh/docs/latest/api/app
于是这样设置之后,hade框架生成的strorage运行产生文件就放在了 ~/Library/Logs/toolbox 中了,完美。
electron + go 如何从sqlite获取数据的更多相关文章
- 从SQLite获取数据完成一个产品信息展示
在ios实际开发当中,我们常常用到Core Data做为数据储存首选.但在处理一些大量复杂的数据值且数据之间相互关联的时候,这就不得不使用关系型数据库来实现.例如一个导航程序,自身应该包含大量的地图自 ...
- Python读取和处理文件后缀为".sqlite"的数据文件
最近在弄一个项目分析的时候,看到有一个后缀为”.sqlite”的数据文件,由于以前没怎么接触过,就想着怎么用python来打开并进行数据分析与处理,于是稍微研究了一下. SQLite是一款非常流行的关 ...
- Android开发之利用SQLite进行数据存储
Android开发之利用SQLite进行数据存储 Android开发之利用SQLite进行数据存储 SQLite数据库简单介绍 Android中怎样使用SQLite 1 创建SQLiteOpenHel ...
- WCF+Restfull服务 提交或获取数据时数据大小限制问题解决方案
近日在使用wcf的restfull架构服务时遭遇到了提交大数据的问题. 大数据包含两种情形: 1)单条数据量过大. 2)提交或获取的数据条数过多. 在测试时发现,默认设置下当单条JSON数据大于30K ...
- python httplib get和post获取数据
httplib 下的 status http请求的状态 200 404 500... reason 返回答复 OK或者 FAULRE read() 读取内容 get方法: #!/usr/bin/e ...
- MySQL随机获取数据的方法,支持大数据量
最近做项目,需要做一个从mysql数据库中随机取几条数据出来. 总所周知,order by rand 会死人的..因为本人对大数据量方面的只是了解的很少,无解,去找百度老师..搜索结果千篇一律.特发到 ...
- AngularJS SQL 获取数据
使用PHP从MySQL中获取数据: <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...
- React使用jquery方式动态获取数据
好久没写react了,今天有空写一下来react实现实时请求数据,并刷新数据的小demo. 首先我还是选择了jquery方式中自带的ajax获取数据,首先要引用所需的js包 接下来要写一个自定义的js ...
- vue 中使用 AJAX获取数据的方法
在VUE开发时,数据可以使用jquery和vue-resource来获取数据.在获取数据时,一定需要给一个数据初始值. 看下例: <script type="text/javascri ...
- Thymeleaf+SpringMVC,如何从模板中获取数据
Thymeleaf+SpringMVC,如何从模板中获取数据 在一个典型的SpringMVC应用中,带@Controller注解的类负责准备数据模型Map的数据和选择一个视图进行渲染.这个模型Map对 ...
随机推荐
- 关于history.back()、history.go()回退但无法刷新页面的问题
window.history.back(); 这样确实可以做到后退的功能,但是项目中,常常并不只是后退就能完成需求,往往需要在后退的同时,刷新后退的页面信息,比如后退到首页同时刷新首页的最新数据,这样 ...
- Oracle导出和导入
导出 exp exp 用户名/密码@实例名 file=导出的dmp文件存放路径 l og=导出日志存放路径 exp hr/123456@orcl file= C:\Users\Administrato ...
- NOI2011阿狸的打字机
题目链接 昨天晚上yy出了一个做法后,感觉...好难打啊...,于是先回去休息.今天来打时,还是感觉细节好多,于是就打了两个小时.打完过了编译后,居然过了样例,直接交,尼玛居然过了???......还 ...
- Java I/O(4):AIO和NIO中的Selector
您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 在Java NIO的三大核心中,除了Channel和Buffer,剩下的就是Selector了.有的地方叫它选择器,也有叫多路复用器的(比如Ne ...
- 记录一次成功反混淆脱壳及抓包激活app全过程
记录一次成功反混淆脱壳及抓包激活app全过程 前言 近期接到一个需求,要对公司之前开发的一款app进行脱壳.因为该app是两年前开发的,源代码文件已经丢失,只有加壳后的apk文件,近期要查看其中一 ...
- win10+ubuntu双系统的坑
1.把U盘里\EFI\BOOT\grubx64.efi文件重命名为mmx64.efi,避免系统提示缺少文件而退出安装: 2.如果电脑显卡为N卡,则在install Ubuntu时,按e进入编辑,在qu ...
- Nginx四层负载均衡1
1.Nginx负载均衡Redis 服务器 IP地址 作用 系统版本 Nginx代理服务器 10.0.0.38 负载均衡服务器 Rocky8.6 Redis服务器1 10.0.0.18 Redis服务器 ...
- Jmeter——请求响应内容乱码解决办法
前段时间,换过一次设备,重新下载了Jmeter.有一次在编写脚本时,响应内容中的中文一直显示乱码. 遇到乱码不要慌,肯定是有办法来解决的.具体解决办法,可以参考之前的博文,Jmeter--BeanSh ...
- 使用@Transactional注解的方法所在的类获取不到注解的解决方案
前段时间遇到一个问题,一个service叫做A吧,有多个实现类分别是B,C,D,需要根据前端传的不同参数去匹配不同的实现类,我就自定义了一个注解@OrderDeal放在B,C,D上面,然后匹配前端传的 ...
- 洛谷 P4135 作诗 题解
题面. 之前做过一道很类似的题目 洛谷P4168蒲公英 ,然后看到这题很快就想到了解法,做完这题可以对比一下,真的很像. 题目要求区间内出现次数为正偶数的数字的数量. 数据范围1e5,可以分块. 我们 ...