个人记录备份一下vue+electron+vue-cli-plugin-electron-builder/lib 桌面项目 同时启动web服务器让和WebSocket服务器

项目需求:

2台设备,一个触摸windows大屏,一个移动设备pad或手机,展示同一个模型内容,通过pad遥控操作windows屏幕内容,同步点击,移动,等操作
 

项目方案

1:vue项目 使用nodejs后台,启动WebSocket,pad和大屏通过WebSocket通讯,项目部署到触摸大屏上,pad访问局域网,两台设备都需要通过浏览器来访问,需要现场操作部署
2:vue+electron,electron中集成web服务器给pad通过局域网访问,集成WebSocket服务器,直接大屏运行electron的exe文件,pad通过ip访问web服务器,不用部署,直接exe文件运行
 

2种方式,选择了第二种,作为一个桌面应用程序虽然展示效果一样 但是还是选择electron打包,正好electron集成了node环境 可以免除部署,基础的vue逻辑代码是一致的

pad发送 http接口信息给web服务器,web服务器接到信息通过WebSocket发送给pc端

项目

通过vue建立项目 

yarn add  electron
vue add electron-builder

vue.config.js 配置文件

不启用asar
路径设置为 ./ 供web服务器使用

const path = require('path')

const resolve = dir => {
  return path.join(__dirname, dir)
}

module.exports = {
  baseUrl: BASE_URL,
  lintOnSave: false,
  chainWebpack: config => {
    config.resolve.alias
      .set('@', resolve('src'))
      .set('_c', resolve('src/components'))
  },
  // 设为false打包时不生成.map文件
  productionSourceMap: false,
  pluginOptions: {
      electronBuilder: {
          customFileProtocol: './',
          // removeElectronJunk: false,
          //preload: './src/preload.js',
          builderOptions: {
              "appId": "com.example.app",
              "productName": "智慧平台", //项目名,也是生成的安装文件名,即aDemo.exe
              "copyright": "Copyright © 2024", //版权信息
  
              "asar": false,
              "win": { //win相关配置
                  "icon": "./src/assets/icon.ico", //图标,当前图标在根目录下,注意这里有两个坑
                  "target": [{
                      "target": "nsis", //利用nsis制作安装程序
                      "arch": [
                          "x64", //64位
                      ]
                  }]
              },
              "nsis": {
                  "oneClick": false, // 是否一键安装
                  "allowElevation": true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
                  "allowToChangeInstallationDirectory": true, // 允许修改安装目录
                  "installerIcon": "./src/assets/icon.ico", // 安装图标
                  "uninstallerIcon": "./src/assets/icon.ico", //卸载图标
                  "installerHeaderIcon": "./src/assets/icon.ico", // 安装时头部图标
                  "createDesktopShortcut": true, // 创建桌面图标
                  "createStartMenuShortcut": true, // 创建开始菜单图标
                  "shortcutName": "mine", // 图标名称
              },
          }
      }
  }
}

background.js 配置

express模块
获取本机ip 
启动web服务器,把目录固定,路由返回electron打包后的app文件夹(打包配置不使用arsr),
web服务器监听3000端口
WebSocket监听 9080端口


const express = require('express');
const appex = express();


const http = require('http');
const fs = require('fs');
const os = require('os')
// const path = require('path');
let win
function getLocalIP() {

  const interfaces = os.networkInterfaces()
  let locatIp = '127.0.0.1'
  // console.log('ifaces:', interfaces)
  for (let devName in interfaces) {
    let iface = interfaces[devName];
    for (let i = 0; i < iface.length; i++) {
      let alias = iface[i];
      if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
        console.log('ifaces:', alias.address)
        return alias.address;
      }
    }
  }

  return locatIp
}
getLocalIP()
let SERVER_IP = getLocalIP();

// 提供静态文件服务
appex.use(express.static(path.join(__dirname, '')));

appex.use(function(req,res,next){
            // req:表示请求对象
            // res:表示响应对象
            // next:表示下一步
            // *:通配符
            res.setHeader('Access-Control-Allow-Origin','*')//允许哪些域名请求我
            res.setHeader('Access-Control-Request-Methods','GET,POST,PUT,DELETE,OPTIONS')//允许哪些请求方式可以请求我
            res.setHeader('Access-Control-Allow-Headers','x-requested-with,content-type')//允许携带哪些请求头信息

            // **************上面的代码一写那么就等于这个服务器开启了跨域资源共享
            next()
        })


console.log(process.env.WEBPACK_DEV_SERVER_URL)
// 设置路由处理
appex.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'index.html'));
});
// appex.get('/send',(req, res) => {

//   console.log('/send',req)
//   // res.sendFile(path.join(__dirname, 'index.html'));
// });

appex.listen(3000, () => {
  console.log('Server running at'+SERVER_IP);
});

const WebSocket = require('ws')
const WebSocketserver = new WebSocket.Server({port:9080})

 WebSocketserver.on('open',function open(){
     console.log('connected')
 })

 WebSocketserver.on('close',function close(){
     console.log('disconnected')
 })

 WebSocketserver.on('connection',function connection(ws,req){
     const ip = req.socket.remoteAddress
     const port = req.socket.remotePort
     const clientName = ip + port

     // console.log('111connected ',req)

     ws.send('222Welcome ' + clientName)

     ws.on('message',function incoming(message){
         console.log('3333received:',message,clientName)
         // WebSocketserver.clients.forEach(function each(client){
         //     if(client.readyState === WebSocket.OPEN){
         //         client.send(clientName +" -> " + message)
         //     }
         // })
     })
 })

appex.get('/send',(req, res) => {
  console.log(req.query)
  console.log('/sendreqreqreqreqreqreqreq----------',JSON.stringify(req.query) )
// let xxx = {
//   code:1,
//   msg:"访问send接口成功上传数据ok",
//   data:req.query,
//   clients:WebSocketserver.clients
// }
//   res.send(xxx)
  // WebSocketserver.send(req.query)

  WebSocketserver.clients.forEach(function each(client){
      if(client.readyState === WebSocket.OPEN){
          client.send(JSON.stringify(req.query))
      }
  })
   // ws.send('/send',req)
  // res.sendFile(path.join(__dirname, 'index.html'));
});

开机启动 exe pad访问 ip:3000/#/pad页面,内部逻辑,所有的操作状态都发送给websocket,然后接收信息,同步到大屏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值