项目需求:
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,然后接收信息,同步到大屏