feat: [ui] ipc socket

This commit is contained in:
gaoshuaixing
2024-12-25 17:46:35 +08:00
parent 15bd88613b
commit 652c42eacd
5 changed files with 211 additions and 178 deletions

View File

@@ -4,11 +4,12 @@ const _ = require('lodash');
const path = require('path');
const {
app: electronApp, dialog, shell, Notification,
powerMonitor, screen, nativeTheme, BrowserWindow
powerMonitor, screen, nativeTheme
} = require('electron');
const { isProd, getBaseDir } = require('ee-core/ps');
const { getConfig } = require('ee-core/config');
const { isFileProtocol } = require('ee-core/utils/is');
// const { isProd, getBaseDir } = require('ee-core/ps');
// const { getConfig } = require('ee-core/config');
// const { isFileProtocol } = require('ee-core/utils/is');
const { windowService } = require('../service/os/window');
/**
* example
@@ -133,21 +134,32 @@ class OsController {
* 打开新窗口
*/
createWindow(args) {
const { type, content, windowName, windowTitle } = args;
return winContentsId;
const wcid = windowService.createWindow(args);
return wcid;
}
/**
* 获取窗口contents id
* Get Window contents id
*/
getWCid(args) {
// 主窗口的name默认是main其它窗口name开发者自己定义
const name = args;
const id = Addon.get('window').getWCid(name);
const wcid = windowService.getWCid(args);
return wcid;
}
return id;
/**
* Realize communication between two windows through the transfer of the main process
*/
window1ToWindow2(args, event) {
windowService.communicate(args, event);
return;
}
/**
* Realize communication between two windows through the transfer of the main process
*/
window2ToWindow1(args, event) {
windowService.communicate(args, event);
return;
}
/**

View File

@@ -1,7 +1,10 @@
'use strict';
const { BrowserView, Notification } = require('electron');
const path = require('path');
const { app: electronApp } = require('electron');
const { BrowserWindow, BrowserView, Notification } = require('electron');
const { getMainWindow } = require('ee-core/electron/window');
const { isProd, getBaseDir } = require('ee-core/ps');
/**
* Window
@@ -12,16 +15,17 @@ class WindowService {
constructor() {
this.myBrowserView = null;
this.myNotification = null;
this.windows = {}
}
/**
* createWindow
* Create a new window
*/
createWindow(args) {
const { type, content, windowName, windowTitle } = args;
let contentUrl = null;
if (type == 'html') {
contentUrl = path.join('file://', electronApp.getAppPath(), content)
contentUrl = path.join('file://', getBaseDir(), content)
} else if (type == 'web') {
contentUrl = content;
} else if (type == 'vue') {
@@ -54,9 +58,9 @@ class WindowService {
}
const win = new BrowserWindow(opt);
const winContentsId = win.webContents.id;
// load page
win.loadURL(contentUrl);
win.webContents.openDevTools();
this.windows[windowName] = win;
return winContentsId;
}
@@ -65,13 +69,31 @@ class WindowService {
* 获取窗口contents id
*/
getWCid(args) {
// 主窗口的name默认是main其它窗口name开发者自己定义
const name = args;
const id = Addon.get('window').getWCid(name);
return id;
const { windowName } = args;
let win;
if (windowName == 'main') {
win = getMainWindow();
} else {
win = this.windows[windowName];
}
return win.webContents.id;
}
/**
* Realize communication between two windows through the transfer of the main process
*/
communicate(args) {
const { receiver, content } = args;
if (receiver == 'main') {
const win = getMainWindow();
win.webContents.send('controller.os.window2ToWindow1', content);
} else if (receiver == 'window2') {
const win = this.windows[receiver];
win.webContents.send('controller.os.window1ToWindow2', content);
}
}
}
WindowService.toString = () => '[class WindowService]';

View File

@@ -1,7 +1,7 @@
/**
* 主进程与渲染进程通信频道定义
* 格式:控制器.文件名.方法
* Definition of communication channel between main process and rendering process
* formatcontroller.filename.method
* Definition of communication channels between main process and rendering process
*/
const ipcApiRoute = {
@@ -48,6 +48,8 @@ const ipcApiRoute = {
autoLaunch: 'controller.os.autoLaunch',
setTheme: 'controller.os.setTheme',
getTheme: 'controller.os.getTheme',
window1ToWindow2: 'controller.os.window1ToWindow2',
window2ToWindow1: 'controller.os.window2ToWindow1',
},
// hardware
@@ -75,14 +77,11 @@ const ipcApiRoute = {
}
/**
* 自定义频道
* 格式:自定义(推荐添加一个前缀)
* custom chennel
* Customize Channel
* Format: Custom (recommended to add a prefix)
*/
const specialIpcRoute = {
appUpdater: 'custom.app.updater', // updater channel
window1ToWindow2: 'custom.window1-to-window2', // windows channel
window2ToWindow1: 'custom.window2-to-window1', // windows channel
}
export {

View File

@@ -47,97 +47,98 @@
</div>
<div class="one-block-2">
<a-space>
<a-button @click="createWindow(0)">打开新窗口2</a-button>
<a-button @click="createWindow()">打开新窗口2</a-button>
<a-button @click="sendTosubWindow()">向新窗口2发消息</a-button>
</a-space>
</div>
</div>
</template>
<script>
import { ipcApiRoute, specialIpcRoute } from '@/api';
<script setup>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
import { toRaw } from 'vue';
import { ref, onMounted } from 'vue';
import { message } from 'ant-design-vue';
export default {
data() {
return {
messageString: '',
message1: '',
message2: '',
message3: '',
windowName: 'window-ipc',
newWcId: 0,
views: [
{
type: 'vue',
content: '#/special/subwindow',
windowName: 'window-ipc',
windowTitle: 'ipc window'
},
],
}
},
mounted () {
this.init();
},
methods: {
init () {
// 避免重复监听,或者将 on 功能写到一个统一的地方,只加载一次
ipc.removeAllListeners(ipcApiRoute.framework.ipcSendMsg);
ipc.on(ipcApiRoute.framework.ipcSendMsg, (event, result) => {
console.log('[ipcRenderer] [socketMsgStart] result:', result);
const messageString = ref('');
const message1 = ref('');
const message2 = ref('');
const message3 = ref('');
this.messageString = result;
// 调用后端的另一个接口
event.sender.send(ipcApiRoute.framework.hello, 'electron-egg');
})
const vueItem = {
type: 'vue',
content: '#/special/subwindow',
windowName: 'window2', // unique name
windowTitle: 'ipc window'
};
// 监听 窗口2 发来的消息
ipc.removeAllListeners(specialIpcRoute.window2ToWindow1);
ipc.on(specialIpcRoute.window2ToWindow1, (event, arg) => {
this.$message.info(arg);
})
},
sendMsgStart() {
const params = {
type: 'start',
content: '开始'
}
ipc.send(ipcApiRoute.framework.ipcSendMsg, params)
},
sendMsgStop() {
const params = {
type: 'end',
content: ''
}
ipc.send(ipcApiRoute.framework.ipcSendMsg, params)
},
handleInvoke() {
ipc.invoke(ipcApiRoute.framework.ipcInvokeMsg, '异步-回调').then(r => {
console.log('r:', r);
this.message1 = r;
});
},
async handleInvoke2() {
const msg = await ipc.invoke(ipcApiRoute.framework.ipcInvokeMsg, '异步');
console.log('msg:', msg);
this.message2 = msg;
},
handleSendSync() {
const msg = ipc.sendSync(ipcApiRoute.framework.ipcSendSyncMsg, '同步');
this.message3 = msg;
},
createWindow(index) {
ipc.invoke(ipcApiRoute.os.createWindow, toRaw(this.views[index])).then(id => {
console.log('[createWindow] id:', id);
})
},
async sendTosubWindow() {
// 新窗口id
this.newWcId = await ipc.invoke(ipcApiRoute.os.getWCid, this.windowName);
ipc.sendTo(this.newWcId, specialIpcRoute.window1ToWindow2, '窗口1通过 sendTo 给窗口2发送消息');
},
onMounted(() => {
init()
})
function init() {
// 避免重复监听,或者将 on 功能写到一个统一的地方,只加载一次
ipc.removeAllListeners(ipcApiRoute.framework.ipcSendMsg);
ipc.on(ipcApiRoute.framework.ipcSendMsg, (event, result) => {
console.log('[ipcRenderer] [socketMsgStart] result:', result);
messageString.value = result;
// 调用后端的另一个接口
event.sender.send(ipcApiRoute.framework.hello, 'electron-egg');
})
// 监听 窗口2 发来的消息
ipc.removeAllListeners(ipcApiRoute.os.window2ToWindow1);
ipc.on(ipcApiRoute.os.window2ToWindow1, (event, arg) => {
message.info(arg);
})
}
function sendMsgStart() {
const params = {
type: 'start',
content: '开始'
}
ipc.send(ipcApiRoute.framework.ipcSendMsg, params)
}
function sendMsgStop() {
const params = {
type: 'end',
content: ''
}
ipc.send(ipcApiRoute.framework.ipcSendMsg, params)
}
function handleInvoke() {
ipc.invoke(ipcApiRoute.framework.ipcInvokeMsg, '异步-回调').then(r => {
console.log('r:', r);
message1.value = r;
});
}
async function handleInvoke2() {
const msg = await ipc.invoke(ipcApiRoute.framework.ipcInvokeMsg, '异步');
console.log('msg:', msg);
message2.value = msg;
}
function handleSendSync() {
const msg = ipc.sendSync(ipcApiRoute.framework.ipcSendSyncMsg, '同步');
message3.value = msg;
}
function createWindow() {
ipc.invoke(ipcApiRoute.os.createWindow, vueItem).then(wcid => {
console.log('[createWindow] wcid:', wcid);
})
}
async function sendTosubWindow() {
const params = {
receiver: 'window2',
content: '窗口1给窗口2发送消息'
}
ipc.invoke(ipcApiRoute.os.window1ToWindow2, params)
}
</script>
<style lang="less" scoped>

View File

@@ -52,78 +52,77 @@
</div>
</div>
</template>
<script>
import { ipcApiRoute, specialIpcRoute } from '@/api';
<script setup>
import { ref, onMounted } from 'vue';
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
import { message } from 'ant-design-vue';
export default {
data() {
return {
messageString: '',
message1: '',
message2: '',
message3: '',
mainWCid: 0,
}
},
mounted () {
this.init();
},
methods: {
init () {
// 避免重复监听,或者将 on 功能写到一个统一的地方,只加载一次
ipc.removeAllListeners(ipcApiRoute.framework.ipcSendMsg);
ipc.on(ipcApiRoute.framework.ipcSendMsg, (event, result) => {
console.log('[ipcRenderer] [socketMsgStart] result:', result);
const messageString = ref('');
const message1 = ref('');
const message2 = ref('');
const message3 = ref('');
this.messageString = result;
// 调用后端的另一个接口
event.sender.send(ipcApiRoute.framework.hello, 'electron-egg');
})
onMounted(() => {
init()
})
// 监听主窗口发来的消息
ipc.removeAllListeners(specialIpcRoute.window1ToWindow2);
ipc.on(specialIpcRoute.window1ToWindow2, (event, arg) => {
this.$message.info(arg);
})
},
sendMsgStart() {
const params = {
type: 'start',
content: '开始'
}
ipc.send(ipcApiRoute.framework.ipcSendMsg, params)
},
sendMsgStop() {
const params = {
type: 'end',
content: ''
}
ipc.send(ipcApiRoute.framework.ipcSendMsg, params)
},
handleInvoke () {
ipc.invoke(ipcApiRoute.framework.ipcInvokeMsg, '异步-回调').then(r => {
console.log('r:', r);
this.message1 = r;
});
},
async handleInvoke2 () {
const msg = await ipc.invoke(ipcApiRoute.framework.ipcInvokeMsg, '异步');
console.log('msg:', msg);
this.message2 = msg;
},
handleSendSync () {
const msg = ipc.sendSync(ipcApiRoute.framework.ipcSendSyncMsg, '同步');
this.message3 = msg;
},
sendTosubWindow () {
// 获取主窗口id
ipc.invoke(ipcApiRoute.os.getWCid, 'main').then(id => {
this.mainWCid = id;
ipc.sendTo(this.mainWCid, specialIpcRoute.window2ToWindow1, '窗口2 通过 sendTo 给主窗口发送消息');
});
},
function init() {
ipc.on(ipcApiRoute.framework.ipcSendMsg, (event, result) => {
console.log('[ipcRenderer] [socketMsgStart] result:', result);
messageString.value = result;
// 调用后端的另一个接口
event.sender.send(ipcApiRoute.framework.hello, 'electron-egg');
})
// 监听主窗口发来的消息
ipc.removeAllListeners(ipcApiRoute.os.window1ToWindow2);
ipc.on(ipcApiRoute.os.window1ToWindow2, (event, arg) => {
message.info(arg);
})
}
function sendMsgStart() {
const params = {
type: 'start',
content: '开始'
}
ipc.send(ipcApiRoute.framework.ipcSendMsg, params)
}
function sendMsgStop() {
const params = {
type: 'end',
content: ''
}
ipc.send(ipcApiRoute.framework.ipcSendMsg, params)
}
function handleInvoke () {
ipc.invoke(ipcApiRoute.framework.ipcInvokeMsg, '异步-回调').then(r => {
console.log('r:', r);
message1.value = r;
});
}
async function handleInvoke2 () {
const msg = await ipc.invoke(ipcApiRoute.framework.ipcInvokeMsg, '异步');
console.log('msg:', msg);
message2.value = msg;
}
function handleSendSync () {
const msg = ipc.sendSync(ipcApiRoute.framework.ipcSendSyncMsg, '同步');
message3.value = msg;
}
function sendTosubWindow () {
const params = {
receiver: 'main',
content: '窗口2给主窗口发送消息'
}
ipc.invoke(ipcApiRoute.os.window1ToWindow2, params)
}
</script>
<style lang="less" scoped>