electron 通过socket连接同一个nedb数据库

在主进程里打开一个数据库子进程, 所有的渲染进程网页都可以通过 Socket 访问此数据库

示例中采用的 nedb 数据库, 可用相同方法封装其他数据库
解决问题::如果多个渲染进程再同一时刻打开nedb数据库, 会报错"rename错误"

🍊🍊 原 nedb 停止维护, 但 @seald-io/nedb 克隆了它

在这里插入图片描述

@seald-io/nedb 数据库速度:

Insert: 10,680 ops/s
Find: 43,290 ops/s
Update: 8,000 ops/s
Remove: 11,750 ops/s

使用( 用 socket有点慢,建议用第二种(electron MessageChannelMain) )

1.主进程中
import { NeDB数据库_port客户端, NeDB数据库_Socket客户端  }      from  "path/to/服务端_nedb数据库.mjs"
let 脚本路径 = "path/to/服务端_nedb数据库.mjs"
let 数据库进程 =  await NeDB数据库_Socket客户端.创建服务端进程( 脚本路径 ) 

//-----------------------------------------------
2.渲染进程的预加载脚本中
import { NeDB数据库_port客户端, NeDB数据库_Socket客户端  }      from  "path/to/服务端_nedb数据库.mjs"
var 软件配置db, 缩略图db, 内存缩略图db 
try{
   [  软件配置db,    缩略图db , 内存缩略图db] = await Promise.all([
        NeDB数据库_Socket客户端.打开(  "path/to/数据库_软件配置.db"  ),
        NeDB数据库_Socket客户端.打开(  "path/to/数据库_缩略图.db"    ),
        NeDB数据库_Socket客户端.nedb新建内存数据库()
    ])     
}catch(err){ throw(`🍎 !!! >>> 读取数据库错误 >>> !!! ${err}`) }

//-----------------------------------------------
3.原有 nedb 接口和自定义的接口都可以使用 
let 查找 = await 软件配置db.findAsync({name:"test"})
let 查找 = await 软件配置db.查找({name:"test"})

核心文件 服务端_nedb数据库.mjs


  
import events from 'events'
import net from "net"
import fs from "fs"
import child_process from "child_process" 
import NeDB from '@seald-io/nedb'           //不能被打包,否则无法写入文件 ???
 
export {  NeDB数据库_port客户端, NeDB数据库_Socket客户端  }

  

//真实数据库所在, 封装nedb增加自定义接口
class NeDB数据库  {
    //私有属性 在原标准上增加一种规则, <匹配条件>  是字符串, 不处理数据,查找直接返回数据:: 用于保存唯一数据
    #自定义_匹配条件(传入匹配条件){         return typeof 传入匹配条件=="string" ?  {"_🌷":传入匹配条件} : 传入匹配条件  }
    #自定义_保存数据(传入匹配条件, 传入数据){return  typeof 传入匹配条件=="string" ? {"_🌷":传入匹配条件,"_🍊":传入数据 } : 传入数据 }
    #自定义_返回数据(传入匹配条件, 返回数据){return  typeof 传入匹配条件=="string" ?  返回数据?.["_🍊"] : 返回数据  }
    
    constructor(配置对象){
        this.数据库 = new NeDB(配置对象) 
        this.__proto__.__proto__ = this.数据库   //继承了NeDB所有方法后, 原有的nedb接口也可以用    
    }  
    static nedb新建内存数据库(){     return new NeDB数据库({ inMemoryOnly:true })  }
    static async nedb打开本地数据库(路径){  
        let 数据库 =  new NeDB数据库({ filename: 路径 ,corruptAlertThreshold:1 })     // autoload:true ,  
        await 数据库.loadDatabaseAsync()
        return 数据库
    }
    static 获取数据库操作keys(){
        let 自定义keys = Object.getOwnPropertyNames(NeDB数据库.prototype)
        let NeDBkeys  = Object.getOwnPropertyNames(NeDB.prototype)
        let keys=[]
        自定义keys.forEach(key=>  /constructor/g.test(key)        ? "" : keys.push(key)  )
        NeDBkeys.forEach( key=>  /(constructor)|(^_)/g.test(key) ? "" : keys.push(key)  )
        // console.log("数据库可用操作",keys)
        return keys
    }
    //新增自定义接口 
    async 保存(传入匹配条件, 传入数据){  //这个用于覆盖保存  ( 已经有就更新 updateAsync,没有就写入 insertAsync)
        try{
            let 结果 = await this.更新(传入匹配条件, 传入数据)
            if(结果.numAffected) return 结果
            else                return await this.数据库.insertAsync( this.#自定义_保存数据(传入匹配条件, 传入数据)  )
        }catch(err){            return await this.数据库.insertAsync( this.#自定义_保存数据(传入匹配条件, 传入数据)  )    }
    }
    async 查找单个(传入匹配条件){        //不再中断报错, 找不到返回 undefined/null
        try{
            let 结果 = await this.数据库.findOneAsync( this.#自定义_匹配条件(传入匹配条件)   ,{_id:0} )
            return this.#自定义_返回数据(传入匹配条件,结果)    //找不到可能返回 null
        }catch(err){ console.error(err); return undefined }
    }
    async 查找(传入匹配条件){           //不再中断报错, 找不到返回 undefined/[]
        try{
            let 结果数组 = await this.数据库.findAsync( this.#自定义_匹配条件(传入匹配条件)  ,{_id:0})
            return (typeof 传入匹配条件 != "string") ? 结果数组 : 结果数组.map(结果=> { return this.#自定义_返回数据(传入匹配条件, 结果) } )
        }catch(err){   console.error(err); return []  }
    }
    async 插入(传入数据){            return await this.数据库.insertAsync(传入数据)  } 
    async 更新(传入匹配条件, 传入数据){return await this.数据库.updateAsync(      this.#自定义_匹配条件(传入匹配条件)  ,this.#自定义_保存数据(传入匹配条件, 传入数据)  )  }
    async 删除单个(传入匹配条件){      return await this.数据库.removeAsync(      this.#自定义_匹配条件(传入匹配条件)  )}
    async 删除(传入匹配条件){          return await this.数据库.removeAsync(      this.#自定义_匹配条件(传入匹配条件)  ,{ multi: true }) }
    async 总数(传入匹配条件){          return await this.数据库.countAsync(       this.#自定义_匹配条件(传入匹配条件)  )}
    async 移除索引(fieldName){        return await this.数据库.removeIndexAsync( fieldName )}
    async 建立索引(Options){          return await this.数据库.ensureIndexAsync( Options  )}    
    //db.建立索引({ fieldName: 'smb路径', unique: true , sparse:true})    // 索引 唯一 sparse:true 在字段不存在时也可以建立索引,否则报错
    //索引只能用来加速基本查询以及使用$in, $lt, $lte, $gt 和 $gte运算符的查询
    压缩数据(){       this.数据库.compactDatafile() }
    定时压缩(毫秒){    this.数据库.setAutocompactionInterval(毫秒) }
    定时压缩_停止(){   this.数据库.stopAutocompaction() }
}
  
//------------------  客户端 ---------------------
class Socket信令码{
    constructor(){ 
        this.缓存
    }
    编码数据(发送对象){   return  "🌷"+ encodeURI(JSON.stringify(发送对象)) +"🍊" }                   //发送对象 --> 先转为字符串 --> 再转 Buffer
    解码数据(接收字符串){ return        JSON.parse(  decodeURI(接收字符串) )       }                   // Buffer数据 --> 先转为字符串 --> 再转对象
    获取信令数组(传入Buffer数据){
        //-----------拼接Buffer
        let 开头标志 = /^🌷/g.test(传入Buffer数据) , 结尾标志 = /🍊$/g.test(传入Buffer数据)
        if     (开头标志  && !结尾标志){   this.缓存 = 传入Buffer数据 ;return []   }                             //有开头  没有结尾
        else if(!开头标志 && !结尾标志){   this.缓存 = Buffer.concat([this.缓存, 传入Buffer数据]) ;return []   }  //没有开头也没有结尾
        else if(!开头标志 && 结尾标志) {   this.缓存 = Buffer.concat([this.缓存, 传入Buffer数据])  }              //没有开头   ,拼接
        else                             this.缓存 = 传入Buffer数据                                            //有开头 有结尾 完整
        //============拼接 验证完整性
        let 完整字符串 = this.缓存.toString()
        let 未解码信令数组 = 完整字符串.match(/(?<=🌷)[\s\S]*?(?=🍊)/g)                                          //有可能同时受到几条信令
        return 未解码信令数组.map(信令项=>{return this.解码数据(信令项) } )       
    }
}
 
const 数据库_socket文件 = '/dev/shm/文件浏览器nedb数据库.socket'           //linux 这个目录是在内存里
class NeDB数据库_Socket客户端 extends Socket信令码{
    constructor(数据库路径){
        super()
        this.注册_数据库操作()                        //所有自定义和原nedb的接口都可以使用
        this.数据库路径 = 数据库路径
        this.事件 = new events.EventEmitter();
        this.计数 = 1
        this.客户端 = net.connect(数据库_socket文件)
        this.监听_监听信令事件戳()
    }
    static async 打开(数据库路径){
        let 客户端 = new NeDB数据库_Socket客户端(数据库路径)
        let 结果 = await 客户端.数据库操作("打开数据库")
        console.log(结果)
        return 客户端
    }
    监听_监听信令事件戳(){
        this.客户端.on('data', Buffer数据 =>{  
            let 信令数组 = this.获取信令数组(Buffer数据)
            信令数组.forEach(信令=> this.事件.emit(信令.事件戳 ,信令.数据包))
        })
        this.客户端.on('end',    () =>{  console.log({类型:'net Socket客户端 断开连接'})      }) 
        this.客户端.on('error', err =>{  console.log({类型:'net Socket客户端 错误',err:err})  })
    }
    async 发送信令(数据对象){
        return new Promise((成功后回调,失败后回调)=>{
            let 信令 = { 事件戳: ++this.计数 ,  数据包:数据对象  }
            this.事件.once(信令.事件戳, 数据包=>{ (数据包.状态) ? 成功后回调(数据包.结果) :  失败后回调(数据包.结果)  })
            this.客户端.write( this.编码数据(信令)  )              // 开头和结尾 标记一条完整的信令
        })
    }
 
    async 数据库操作(函数名, 参数数组){  return await this.发送信令({数据库路径:this.数据库路径, 函数名:函数名, 参数数组:参数数组})  }
    注册_数据库操作(){
        let keys= NeDB数据库.获取数据库操作keys()
        keys?.forEach?.(key => this[key] = async (...参数数组)=>{return await this.数据库操作(key, 参数数组) }   )
    }
 
    //服务端   备用(这两个不用socket直接打开数据库)
    static nedb新建内存数据库(){           return       NeDB数据库.nedb新建内存数据库()      }
    static async nedb打开本地数据库(路径){  return await NeDB数据库.nedb打开本地数据库(路径)  }    // autoload:true ,   忽略数据损坏问题
    static async 创建服务端进程(服务端_进程脚本路径){
        //效率进程  轻量级的进程
        const { utilityProcess } = await import("electron")
        return new Promise((成功后回调,失败后回调)=>{ 
            let 数据库服务进程 =  utilityProcess.fork(服务端_进程脚本路径,  {stdio:"inherit"} )    
            数据库服务进程.结束 = function(){this.postMessage({类型:"kill"}) ; this.kill() }
            数据库服务进程.once('exit',    (err)     => {  console.log("❄❄数据库服务进程退出❄❄",err) ; 失败后回调(err) })
            数据库服务进程.once('message', (message) => {  
                if(message==="💓💓_启动完成"){  
                    数据库服务进程.postMessage({ 类型:"🍍🍍_打开数据库Socket端口"})
                    成功后回调(数据库服务进程)   
                }})            
        })   

        return new Promise((成功后回调,失败后回调)=>{ 
            let 数据库服务进程 =  child_process.fork(服务端_进程脚本路径,{stdio:"inherit"} )                                 //
            数据库服务进程.once('message',    (message) => {  if(message==="💓💓_启动完成") 成功后回调(数据库服务进程)  })
            数据库服务进程.once('disconnect', (err) => {   console.log("❄❄数据库服务进程退出❄❄",err) ; 失败后回调(err)  })
            数据库服务进程.once('exit',       (err) => {   console.log("❄❄数据库服务进程退出❄❄",err) ; 失败后回调(err)  })
            数据库服务进程.once('error',      (err) => {   console.log("❄❄数据库服务进程退出❄❄",err) ; 失败后回调(err)  })
            数据库服务进程.once('close',      (err) => {   console.log("❄❄数据库服务进程退出❄❄",err) ; 失败后回调(err)  })
            数据库服务进程.结束 = function(){ this.send({类型:"kill"}) ; this.kill() }
        })   
    }
}

/*
1. 服务进程启动完成   "💓💓_启动完成"
2. 将 MessageChannel 端口注入到 子进程
    2.1 客户端发信令 "🍍🍍_打开数据库port端口"   --->        主进程发送  "🍍🍍_打开数据库port端口"
    2.2 子进程收到   "🍍🍍_打开数据库port端口"   ----- 端口port发送标志   "🌈🌈_远程port已经启动"

*/
class NeDB数据库_port客户端 extends Socket信令码{
   
    constructor(数据库路径,本地port,远程port){
        super()
        this.注册_数据库操作()                        //所有自定义和原nedb的接口都可以使用
        this.数据库路径 = 数据库路径
        this.事件 = new events.EventEmitter();
        this.计数 = 1
        this.本地port = 本地port
        this.远程port = 远程port
        this.监听_监听信令事件戳()                               //正式开始
    }
    //配合主进程  
    static async 打开(数据库路径){  
        const 生成端口后_让主进程发送子进程 = async ()=>{
            const { ipcRenderer,ipcMain,MessageChannelMain } = await import("electron")  
            return new Promise((成功后回调,失败后回调)=>{
                if(process.type =="renderer"){
                    const { port1:本地port, port2:远程port } = new MessageChannel()
                    本地port.onmessage = messageEvent =>{  if(messageEvent.data==="🌈🌈_远程port已经启动") 成功后回调({本地port:本地port,远程port:远程port}) } 
                    本地port.start()
                    ipcRenderer.postMessage("🍍🍍_打开数据库port端口", null, [远程port])
                }     
                else if(process.type=="browser"){
                    const { port1:本地port, port2:远程port } = new MessageChannelMain()
                    本地port.on("message" , messageEvent =>{  if(messageEvent.data==="🌈🌈_远程port已经启动") 成功后回调({本地port:本地port,远程port:远程port}) } )
                    本地port.start()
                    ipcMain.emit("🍍🍍_打开数据库port端口", { ports:[远程port] } )
                } 
            })
        }
        const { 本地port , 远程port } = await 生成端口后_让主进程发送子进程()                //端口写入 数据库子进程
        const 客户端 = new NeDB数据库_port客户端(数据库路径, 本地port, 远程port)
        const 结果 = await 客户端.数据库操作("打开数据库")
        console.log(结果)
        return 客户端
    }
    监听_监听信令事件戳(){  
        if(process.type =="renderer"){
            this.本地port.onmessage =   messageEvent =>{   let 信令 = messageEvent.data ; this.事件.emit(信令.事件戳 ,信令.数据包)  }
            this.本地port.start()
            this.本地port.onclose = err=> console.log(err) 
            this.本地port.onmessageerror =  err=> console.log(err) 
        }else if(process.type=="browser"){
            this.本地port.on("message" ,messageEvent =>{   let 信令 = messageEvent.data ; this.事件.emit(信令.事件戳 ,信令.数据包)  } )
            this.本地port.start()
            this.本地port.on("close", err=> console.log(err) )
        }
    }
    async 发送信令(数据对象){
        return new Promise((成功后回调,失败后回调)=>{
            let 信令 = { 事件戳: ++this.计数 ,  数据包:数据对象  }
            this.事件.once(信令.事件戳, 数据包=>{ (数据包.状态) ? 成功后回调(数据包.结果) :  失败后回调(数据包.结果)  })
            this.本地port.postMessage( 信令  )              // 开头和结尾 标记一条完整的信令
        })
    }
 
    async 数据库操作(函数名, 参数数组){  return await this.发送信令({数据库路径:this.数据库路径, 函数名:函数名, 参数数组:参数数组})  }
    注册_数据库操作(){
        let keys= NeDB数据库.获取数据库操作keys()
        keys?.forEach?.(key => this[key] = async (...参数数组)=>{return await this.数据库操作(key, 参数数组) }   )
    }
 
    //服务端   备用(这两个不用socket直接打开数据库)
    static nedb新建内存数据库(){           return       NeDB数据库.nedb新建内存数据库()      }
    static async nedb打开本地数据库(路径){  return await NeDB数据库.nedb打开本地数据库(路径)  }    // autoload:true ,   忽略数据损坏问题
    static async 创建服务端进程(服务端_进程脚本路径){
        //效率进程  轻量级的进程
        const { utilityProcess, ipcMain } = await import("electron")
        return  new Promise((成功后回调,失败后回调)=>{        //此脚本vite打包后,无法被启动
            let 数据库服务进程 =  utilityProcess.fork(服务端_进程脚本路径 ,  {stdio:"inherit" } )  
            数据库服务进程.once('message',  (message) => {  if(message==="💓💓_启动完成"){  成功后回调(数据库服务进程)   }})
            数据库服务进程.once('exit',     (err)     => {  console.log("❄❄数据库服务进程退出❄❄",err) ; 失败后回调(err)  })   
            数据库服务进程.结束 = function(){this.postMessage({类型:"kill"}) ; this.kill() }
            //主进程监听
            ipcMain.on("🍍🍍_打开数据库port端口", (event)=>{ 数据库服务进程.postMessage({类型:"🍍🍍_打开数据库port端口"}, event.ports )   })
        })   
    }
}


//------------------  服务端 ----------------------
var 数据库列表 = {}
class 服务进程Socket_nedb数据库类 {         //由主进程启动一次,  渲染进程无限次连接
    constructor(){
        this.服务器 = null
 
        this.创建一个net服务器()
        this.监听主进程消息()
    }
    async 监听socket连接_接收处理信令(socket连接,信令){
        let 数据包 = 信令.数据包  
        if(数据包.函数名 == "打开数据库"){
            let 数据库名称 = /[^\\\/]+$/g.exec(数据包.数据库路径)?.[0]
            if(! 数据库列表?.[数据包.数据库路径] ){
                try{
                              数据库列表[数据包.数据库路径] = await NeDB数据库.nedb打开本地数据库(数据包.数据库路径)
                              socket连接.发送信令({事件戳:信令.事件戳  ,数据包:{状态:true  ,结果:{状态:`🍍子进程消息: 新打开 ${数据库名称}`,    数据库表:Object.keys(数据库列表) } }})
                }catch(err){  socket连接.发送信令({事件戳:信令.事件戳  ,数据包:{状态:false ,结果:{状态:`🍎子进程消息: 新打开失败 ${数据库名称}`, 数据库表:Object.keys(数据库列表), err:err}}    })    }
            } 
            else              socket连接.发送信令({事件戳:信令.事件戳  ,数据包:{状态:true  ,结果:{状态:`🍍子进程消息: 已存在 ${数据库名称}`,    数据库表:Object.keys(数据库列表) } }})
        }
        else{
            try{
                let 返回数据 = await 数据库列表[数据包.数据库路径][数据包.函数名](...数据包.参数数组)
                socket连接.发送信令({事件戳:信令.事件戳     ,数据包: {状态:true ,结果: 返回数据}  })
            }catch(err){
                socket连接.发送信令({事件戳:信令.事件戳     ,数据包: {状态:false ,结果: err   }  })
            } 
        }
    }

    创建一个net服务器(){
        const 信令码 = new Socket信令码()
        this.服务器 = net.createServer({keepAlive:true,noDelay:true})  // 创建一个 服务器 
        this.服务器.maxConnections = 1000
        try{ fs.unlinkSync(数据库_socket文件) }catch(err){ }
        this.服务器.listen(数据库_socket文件)
        //this.服务器.unref()                               //调用 unref() 后,则当所有客户端连接关闭后,将关闭服务器。 

        this.服务器.on("connection",socket连接=>{ 
            socket连接.setKeepAlive(true)
            socket连接.发送信令=(信令) =>   { socket连接.write(   信令码.编码数据(信令)  )}
            socket连接.on('close', () =>  { socket连接.发送信令('🍎子进程消息:close断开连接')                    })
            socket连接.on('error', err => { socket连接.发送信令(`🍎子进程消息:error ${err.message}`)           })
            socket连接.on('data', Buffer数据 => {
                let 信令数组 = 信令码.获取信令数组(Buffer数据)
                for(let 信令 of 信令数组){ this.监听socket连接_接收处理信令(socket连接, 信令)   }
            })
        })
    }
 
    监听主进程消息(){
        const 同步信令处理表={
            "kill":信令=>{
                this.服务器.close()
                // parentPort?.close?.()
                process.exit()
            }
        }
        process?.on?.("message", 信令=>{  同步信令处理表[信令.类型]?.(信令)  })                // child_process
        // parentPort.on?.("message", 信令=>{  同步信令处理表[信令.类型]?.(信令?.数据包)  })   // worker_threads 线程
        process?.parentPort?.on?.("message", 信令=>{  同步信令处理表[信令.类型]?.(信令)  })   // electron UtilityProcess
    }
}

class 服务进程port_nedb数据库类 {         //由主进程启动一次,  渲染进程无限次连接
    constructor(MessagePort){
        this.MessagePort = MessagePort
        this.发送信令 = (...参数)=> this.MessagePort.postMessage(...参数)
 
        this.监听MessagePort消息() 
    }
    async 监听port连接_接收处理信令(信令){
        let 数据包 = 信令.数据包  
        if(数据包.函数名 == "打开数据库"){ 
            let 数据库名称 = /[^\\\/]+$/g.exec(数据包.数据库路径)?.[0]
            if(! 数据库列表?.[数据包.数据库路径] ){
                try{
                              数据库列表[数据包.数据库路径] = await NeDB数据库.nedb打开本地数据库(数据包.数据库路径)
                              this.发送信令({事件戳:信令.事件戳  ,数据包:{状态:true  ,结果:{状态:`🍍子进程消息: 新打开 ${数据库名称}`,    数据库表:Object.keys(数据库列表) } }})
                }catch(err){  this.发送信令({事件戳:信令.事件戳  ,数据包:{状态:false ,结果:{状态:`🍎子进程消息: 新打开失败 ${数据库名称}`, 数据库表:Object.keys(数据库列表), err:err}}    })    }
            } 
            else              this.发送信令({事件戳:信令.事件戳  ,数据包:{状态:true  ,结果:{状态:`🍍子进程消息: 已存在 ${数据库名称}`,    数据库表:Object.keys(数据库列表) } }})
        }
        else{
            try{
                let 返回数据 = await 数据库列表[数据包.数据库路径][数据包.函数名](...数据包.参数数组)
                this.发送信令({事件戳:信令.事件戳     ,数据包: {状态:true ,结果: 返回数据}  })
            }catch(err){
                this.发送信令({事件戳:信令.事件戳     ,数据包: {状态:false ,结果: err   }  })
            } 
        }
    }
 
    监听MessagePort消息(){
        this.MessagePort.on("message",(messageEvent)=>{ 
            let 信令 = messageEvent.data  
            this.监听port连接_接收处理信令(信令)
        })
        this.MessagePort.start()
        this.MessagePort.postMessage("🌈🌈_远程port已经启动")   //传递启动消息

        this.MessagePort.on("close" , ()=>{  console.log("数据库 MessagePort 端口关闭")   })    //窗口销毁后会触发
    }

    static 监听Process消息(){
        const 同步信令处理表={
            "kill":信令=>{
                this.服务器?.close?.()
                // parentPort?.close?.()
                process.exit()
            } 
        }
        process?.on?.("message", 信令=>{  同步信令处理表[信令.类型]?.(信令)  })                // child_process
        // parentPort.on?.("message", 信令=>{  同步信令处理表[信令.类型]?.(信令?.数据包)  })    // worker_threads 线程
        process?.parentPort?.on?.("message", 信令=>{ 同步信令处理表[信令.data.类型]?.(信令.data)      })      // electron UtilityProcess
    }
   
}
 
//================ 如果是子进程 运行服务端 ================== 
if(process?.send || process?.parentPort ){                               //child_process  -  electron UtilityProcess
    let 已启动标志 = false
    process?.parentPort?.on?.("message", message=>{                      //electron UtilityProcess
        let 信令 = message?.data
        if(信令.类型==="🍍🍍_打开数据库port端口"){   
            let MessagePort = message.ports[0]  
            new 服务进程port_nedb数据库类(MessagePort)
            console.log("-------nedb数据库服务 新打开 MessagePort-------")
            if(!已启动标志) 服务进程port_nedb数据库类.监听Process消息()
            已启动标志 = true
        } 
        else if(信令.类型==="🍍🍍_打开数据库Socket端口"){    
            new 服务进程Socket_nedb数据库类()
        }
    })                                                                  
  
    process?.send?.("💓💓_启动完成")                                      // child_process
    // parentPort?.postMessage?.("启动完成")                              // worker_threads 线程
    process?.parentPort?.postMessage?.("💓💓_启动完成")                   // electron UtilityProcess
  
 
    // console.log(process.argv)
    console.log("-------唯一nedb数据库服务-------")
}

































  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值