Electron+Vue+Thrift实现PC客户端开发

尽管web应用有着不可比拟的优势,但在一些应用场景里,考虑到某些因素(安全、客户需求、通信效率等)不得不使用客户端。然而,要达到同样的视觉效果,相比于web,客户端程序的界面设计及制作十分繁杂。因此,将web前端和客户端开发结合起来是个不错的想法。

而web前端中,作为三大主流框架之一,vue能大大降低开发成本,节省开发时间,并在页面渲染和交互上有着良好表现,因此本文选用Vue作为web前端开发框架。

Electron是当前一个比较成熟的将web程序打包的框架,应用广泛,其实现也方便简单。因此,本文使用Electron作为打包工具。

Thrift是Facebook公布的一款开源跨语言的RPC框架(选用RPC通信是出于安全考虑,其通信原理见博客),在web程序和python之间通信表现良好。

本文参考了一篇博客,对其进行了复现的同时加入了Vue框架并补充了部分细节。

环境配置

本文开发使用的环境:

  • Windows 10
  • Sublime text 3
  • Python 3.7
  • Pip 20.2.2
  • Node 10.16.0
  • Npm 6.9.0
  1. 安装thrift:
pip install thrift
  1. 全局安装Electron
npm install electron -g

如果因网络不佳导致安装失败,可考虑换成cnpm进行安装,cnpm安装教程见博客,安装命令为:

cnpm install electron -g
  1. 全局安装vue-cli
npm install @vue/cli -g
  1. 找一个风水好的地方新建文件夹electronApp
  2. 进入该文件夹,执行命令vue init simulatedgreg/electron-vue,期间会出现一些输入项,选择打包工具时,有builderpackager两个选项,一个是打包成安装包,一个是打包成可直接运行的程序,根据需要选择即可,其他直接enter默认即可
  3. 在该文件夹执行命令安装本地环境:
npm install 
  1. 在文件夹src->rederer中新建文件夹lib,进入lib文件夹
    新建接口文件test.thrift,输入以下内容:
service userService {
    string test1(1:string name)
}
  1. 下载thrift.exe,并配置环境变量:
    重命名该文件为thrift.exe,在E盘(其他盘也可以)新建文件夹thrift,将该文件放进去
    右键单击计算机,选择属性,在弹框中,依次选择高级系统设置>环境变量,在Path中添加该文件地址
    在cmd窗口中输入thrift -version如能正常显示则配置成功
  2. 生成各自的接口文件:
thrift -out 存储路径 --gen 接口语言 thrift接口文件名

这里以当前路径,生成nodejs:

thrift -out ./ --gen js:node test.thrift

生成完之后文件夹内会多出两个js文件
同理,生成python:

thrift -out ./ --gen py test.thrift

在根目录新建文件夹py,将生成的文件夹test和文件_init_.py放入其中

代码编写

客户端代码

回到lib目录下,引入thrift
新建文件common.js,输入以下内容:

import Vue from 'vue'
class Api {
    static importThrift = () => {
    var thrift = require('thrift');
    var userService = require('./userService.js');
    var thriftConnection = thrift.createConnection('127.0.0.1', 8000);
    var thriftClient = thrift.createClient(userService,thriftConnection);

    thriftConnection.on("error",function(e){
      console.error(e);
    });
    return thriftClient;
  }
}
export default {
  install(Vue) {
    Vue.prototype.$api = Api;
    Vue.prototype.$thrift = Api.importThrift;
  }
}

新建文件index.js,输入以下内容:

import Vue from 'vue'

import common from './common'

export default {
  install(Vue) {
    Vue.use(common)
  }
}

编辑renderer文件夹内的main.js,添加以下内容:

import lib from './lib'
Vue.use(lib)

编辑src->main目录下的文件index.js,在末尾添加以下内容:

const path=require('path')

let pyProc = null
let pyPort = null

const createPyProc = () => {
  // let port = '4242'
  let script = path.join(__dirname, 'py', 'thrift_server.py')
  pyProc = require('child_process').spawn('python', [script])
  if (pyProc != null) {
    console.log('child process success')
  }
}

const exitPyProc = () => {
  pyProc.kill()
  pyProc = null
  pyPort = null
}

app.on('ready', createPyProc)
app.on('will-quit', exitPyProc)

调用

在任意Vue页面文件里的<script></script>标签内的函数里书写以下代码即可调用test1:

this.$thriftClient.test1(JSON.stringify(user), (error, res) => {
  if(error) {
    console.error(error)
  } else {
    console.log(res)
  }
})

服务端代码

进入py目录,新建文件thrift_server.py:

import json
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer

from test import userService


class Test:
    def test1(self, dic):
        print("one")
        dic = json.loads(dic)
        return f'Hello, {dic["name"]}!'


if __name__ == "__main__":
    port = 8000
    ip = "127.0.0.1"
    # 创建服务端
    handler = Test()  # 自定义类
    processor = userService.Processor(handler)  # userService为python接口文件自动生成
    # 监听端口
    transport = TSocket.TServerSocket(ip, port)  # ip与port位置不可交换
    # 选择传输层
    tfactory = TTransport.TBufferedTransportFactory()
    # 选择传输协议
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()
    # 创建服务端
    server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
    print("start server in python")
    server.serve()
    print("Done")

项目启动

py目录下执行命令python thrift-server.py
electronApp目录下执行命令npm run dev即可运行项目:

项目运行成功

项目打包

写好之后的项目需要打包成exe文件,便于移植

工具安装

安装打包工具:

pip install pyinstaller

在根目录运行命令安装Electron打包模块:

npm install electron-packager --save-dev

环境配置

package.jsonscripts中加入"build-python":"pyinstaller ./py/thrift_server.py --clean"
然后在根目录下运行npm run build-python编译一下。编译完了可以把根目录下生成的build文件夹和thrift_server.spec删了。
之前子进程是通过调用python命令运行的,现在我们要换成生成的可执行程序。修改src->main下的index.js

// let script = path.join(__dirname, 'py', 'thrift_server.py')
  // pyProc = require('child_process').spawn('python', [script])
  let script = path.join(__dirname, 'py', 'dist','thrift_server')
  pyProc = require('child_process').execFile(script)

然后将"pack-app": "./node_modules/.bin/electron-packager . --overwrite --ignore=py$"写入package.jsonscripts中。

打包程序

运行npm run pack-app打包程序,最后会生成可执行文件,复制到别的电脑也可以运行。
所有代码见Github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342