分类 知识 下的文章

什么是protobuf

Protobuf(Protocol Buffer)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。(参考链接

什么是protoc

protoc是protobuf文件(.proto)的编译器(参考链接),可以借助这个工具把 .proto 文件转译成各种编程语言对应的源码,包含数据类型定义、调用接口等。

采集失败,请手动处理

https://static.studygolang.com/180325/41775c725a2745e2e785f22bbd96a08c.png
 
通过查看protoc的源码(参见github库)可以知道,protoc在设计上把protobuf和不同的语言解耦了,底层用c++来实现protobuf结构的存储,然后通过插件的形式来生成不同语言的源码。可以把protoc的编译过程分成简单的两个步骤(如上图所示):1)解析.proto文件,转译成protobuf的原生数据结构在内存中保存;2)把protobuf相关的数据结构传递给相应语言的编译插件,由插件负责根据接收到的protobuf原生结构渲染输出特定语言的模板。
源码中(参见github库)包含的插件有 csharp、java、js、objectivec、php、python、ruby等多种。

什么是protoc-gen-go

protoc-gen-go是protobuf编译插件系列中的Go版本。从上一小节知道原生的protoc并不包含Go版本的插件,不过可以在github上发现专门的代码库(参见github库)。
由于protoc-gen-go是Go写的,所以安装它变得很简单,只需要运行 go get -u github.com/golang/protobuf/protoc-gen-go,便可以在$GOPATH/bin目录下发现这个工具。至此,就可以通过下面的命令来使用protoc-gen-go了。

protoc --go_out=output_directory input_directory/file.proto

其中"--go_out="表示生成Go文件,protoc会自动寻找PATH(系统执行路径)中的protoc-gen-go执行文件。

protoc-gen-go的源码

采集失败,请手动处理

https://static.studygolang.com/180325/fcfa10f6aa545027a3904783f0fd6ab5.png
 
按照Go的代码风格,protoc-gen-go源码主要包含六个包(package):

  • main包
    • doc.go 主要是说明。
    • link_grpc.go 显式引用protoc-gen-go/grpc包,触发grpc的init函数。
    • main.go 代码不到50行,初始化generator,并调用generator相应的方法输出protobuf的Go语言文件。
  • generator包
    • generator.go 包含了大部分由protobuf原生结构到Go语言文件的渲染方法,其中 func (g *Generator) P(str ...interface{}) 这个方法会把渲染输出到generator的output(generator匿名嵌套了bytes.Buffer,因此有Buffer的方法)。
    • name_test.go 测试,主要包含generator中名称相关方法的测试。
  • grpc包
    • grpc.go 与generator相似,但是包含了很多生成grpc相关方法的方法,比如渲染转译protobuf中定义的rpc方法(在generator中不包含,其默认不转译service的定义)
  • descriptor 包含protobuf的描述文件(.proto文件及其对应的Go编译文件),其中proto文件来自于proto库(参见这里
  • plugin 包含plugin的描述文件(.proto文件及其对应的Go编译文件),其中proto文件来自于proto库,参见这里

结语

从巴别塔的传说(参见这里)可以知道,欲要构建大系统,个体之间的沟通规范很重要。protobuf的出现,为不同系统之间的连接提供了一种语言规范,只要遵循了这个规范,各个系统之间就是解耦的,非常适合近年来流行的微服务架构。
如果吧protoc和protoc-gen-go看成两个微服务,可以发现这两个服务就是完全解耦的;两者完全负责不同的功能,可以分别编码、升级,串接这两个服务的就是proto规范。


您好,需要放行 80   443  5800等端口才可以
你可以试试下面命令安装nginx1.22版本(1.20 则是安装nginx1.20)

  1. bash /www/server/panel/install/install_soft.sh 0 install nginx 1.22
复制代码


在php中,执行异步任务是一种很常见的需求,如批量发邮箱,短信等等执行耗时任务时,需要程序异步执行,给用户带来好的体验。
在php异步执行代码就很尬尴,不像java 可以创建多线程,在php中也可以用pcntl_fork()实现创建子进程,来实现异步,但这样可能会产生很多僵尸进程。其他的方式借助框架实现,如优秀的swoole框架,本文介绍无需安装如何框架扩展,php自带的方式处理
下面直接上代码,我用的thinkphp6
在extend下创建一个util类,代码如下
<?php
namespace util;
class AsyncHook
{
private static $hook_list = array();
private static $hooked = false;
/**
* hook函数fastcgi_finish_request执行
*
* @param callback $callback
* @param array $params
*/
public static function hook($callback, $params = [])
{
self::$hook_list[] = array('callback' => $callback, 'params' => $params);
if (self::$hooked == false) {
self::$hooked = true;
register_shutdown_function(array(__CLASS__, '__run'));
}
}
/**
* 由系统调用
*
* @return void
*/
public static function __run()
{
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
}
if (empty(self::$hook_list)) {
return;
}
foreach (self::$hook_list as $hook) {
$callback = $hook['callback'];
$params = $hook['params'];
call_user_func_array($callback, $params);
}
}
}
调用方式
$namespaceClass = "app\\api\\task\\Test";
$classObj = app($namespaceClass);
\util\AsyncHook:hook([$classObj,"index"],['name'=>1]);
$this->success("");
执行结果,会先$this->success()返回数据,后执行hook中的Test index方法。很简单。


使用场景:
为了安全着想,存入数据库的密码是加密后存入的,但是现在需要从数据库中获取账号和密码来调用封装的第三方接口来获取关键参数,此时密码信息就需要是解密的,但是如果从每个调用的地方都来一次解密,又显得有点累赘。所以就重写Model的init方法来达到目的。
from django.db import models
class Company(models.Model):
name = models.CharField(u'公司名称', max_length=64, null=False)
account = models.CharField(u'登陆账号', max_length=64, null=False)
passwd = models.CharField(u'登陆密码', max_length=64, null=False)
address = models.CharField(u'住址', max_length=64, null=False)
phone = models.CharField(u'电话号码', max_length=11, null=False)
email = models.EmailField(u'邮箱', max_length=64, null=False)
class Meta:
verbose_name = "公司"
verbose_name = verbose_name
db_table = "business_company"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
改写方法:
from django.db import models
from utils import AESCipher # 自己定义的AES的加解密类
class Company(models.Model):
name = models.CharField(u'公司名称', max_length=64, null=False)
account = models.CharField(u'登陆账号', max_length=64, null=False)
passwd = models.CharField(u'登陆密码', max_length=64, null=False)
address = models.CharField(u'住址', max_length=64, null=False)
phone = models.CharField(u'电话号码', max_length=11, null=False)
email = models.EmailField(u'邮箱', max_length=64, null=False)
class Meta:
verbose_name = "公司"
verbose_name = verbose_name
db_table = "business_company"
# 重写此方法
def __init__(self, *args, **keargs):
fields_iter = iter(self._meta.concrete_fields)
new_args = list()
for val, field  in zip(args, fields_iter):
if field.attname == "passwd":
new_args.append(AESCipher().decrypt(val))
else:
new_args.append(val)
super(Company, self).__init__(*tuple(new_args), **kwargs)


概述

Nuxt.js 是一个基于 Vue.js 的服务端渲染应用框架,可以快速搭建一个 SSR(Server-Side Rendering)项目。而 Electron 是一个可以使用 HTML、CSS 和 JavaScript 构建跨平台桌面应用的开源框架。将这两个框架结合起来,可以很方便地构建跨平台桌面应用。

在使用 Nuxt3 和 Electron 构建桌面应用时,需要安装 electron-builder。electron-builder 是一个用于打包 Electron 应用的开源工具。它可以将应用程序打包成可执行文件,并生成安装包。

以下是构建基于 Nuxt3 和 Electron 的桌面应用的步骤。

构建步骤

在 Nuxt3 中配置 Electron 的步骤如下:

  1. 在 Nuxt3 项目中安装 electron 和 electron-builder:
npm install --save-dev electron electron-builder
  1. 在项目根目录下创建一个 build 目录,并在其中创建一个 electron.js 文件。在该文件中,可以进行一些 Electron 应用的相关配置,如窗口大小、位置、图标等。示例配置如下:
const { app, BrowserWindow } = require('electron')
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadURL('<http://localhost:3000>')
}
app.whenReady().then(() => {
createWindow()
}) 
  1. 在 package.json 文件中,添加以下配置项:
{
"build": {
"appId": "com.example.app",
"productName": "My App",
"directories": {
"output": "dist_electron"
},
"files": [
"build/**/*",
"nuxt.config.js",
"package.json"
],
"extraResources": [
{
"from": "public",
"to": "public"
}
],
"mac": {
"category": "public.app-category.developer-tools"
}
}
}
  1. 在 nuxt.config.js 文件中,添加以下配置项:
export default {
// ...
target: 'static',
ssr: false,
// ...
build: {
// ...
extend(config, { isClient }) {
if (isClient) {
config.target = 'electron-renderer'
}
}
}
}

其中,target 设置为 'static'ssr 设置为 falsebuild.extend 中的代码用于将客户端构建的目标设置为 electron-renderer

  1. 在 package.json 文件中,添加以下启动脚本:
{
"scripts": {
"electron:dev": "nuxt dev && electron .",
"electron:build": "nuxt build && electron-builder"
}
}

其中,electron:dev 用于在开发模式下启动 Electron,electron:build 用于构建 Electron 应用。

  1. 运行以下命令启动 Electron 应用:
 npm run electron:dev

在开发过程中,可以使用 electron-storeelectron-updaterelectron-log 等 Electron 的开源工具和库来提高开发效率和应用体验。

此外,如果需要在 Nuxt3 中使用 Electron API,可以使用 nuxt-electron 插件。这个插件可以让你在 Nuxt3 中直接使用 Node.js 和 Electron 的 API,例如 remoteipcMainipcRenderer 等。使用该插件的步骤如下:

  1. 在 Nuxt3 项目中安装 nuxt-electron 插件:
npm install --save-dev @nuxtjs/electron
  1. 在 nuxt.config.js 文件中,添加以下配置项:
export default {
// ...
buildModules: [
'@nuxtjs/electron'
],
electron: {
// ...
}
}

其中,buildModules 中添加 @nuxtjs/electronelectron 中可以添加一些 Electron 的配置项,例如 nodeIntegrationcontextIsolation 等。

  1. 在你的 Vue 组件中,可以通过 $electron 访问到 Electron 对象。例如:
<template>
<div>
<h1>{{ message }}</h1>
<button @click="openDialog">打开对话框</button>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello, Electron!'
}
},
methods: {
openDialog() {
const { dialog } = this.$electron.remote
dialog.showMessageBox({ message: 'Hello, Electron!' })
}
}
}
</script>

适配插件

此外,Nuxt3 还提供了一些特性来适配 Electron 应用,例如:

  • 使用 nuxt-start 来启动 Electron 应用。
  • 使用 nuxt-electron 插件来在 Nuxt3 中使用 Electron API。
  • 使用 nuxt-webdriverio 插件来进行端到端测试。

另外,Nuxt3 还支持 TypeScript,这意味着开发者可以使用 TypeScript 来开发基于 Nuxt3 和 Electron 的桌面应用,从而提高代码的可维护性和可读性。

在开发过程中,还可以使用一些 Electron 的开源工具和库,例如:

  • electron-store:轻松地在 Electron 应用中存储和读取数据。
  • electron-updater:自动更新 Electron 应用。
  • electron-log:在 Electron 应用中记录日志。

总之,基于 Nuxt3 和 Electron 构建桌面应用是一种非常具有前景的开发方式。它不仅可以让开发者使用熟悉的技术栈来开发跨平台的桌面应用,还可以为用户提供更好的使用体验。同时,Nuxt3 和 Electron 的不断更新也将为开发者带来更多的可能性。