feat: add subscribe
This commit is contained in:
parent
e828a4c084
commit
9a378275e1
@ -31,7 +31,7 @@
|
|||||||
],
|
],
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@abearxiong/router": "0.0.1-alpha.32",
|
"@abearxiong/router": "0.0.1-alpha.33",
|
||||||
"@abearxiong/use-config": "^0.0.2",
|
"@abearxiong/use-config": "^0.0.2",
|
||||||
"@babel/core": "^7.25.2",
|
"@babel/core": "^7.25.2",
|
||||||
"@babel/preset-env": "^7.25.4",
|
"@babel/preset-env": "^7.25.4",
|
||||||
|
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@ -9,8 +9,8 @@ importers:
|
|||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@abearxiong/router':
|
'@abearxiong/router':
|
||||||
specifier: 0.0.1-alpha.32
|
specifier: 0.0.1-alpha.33
|
||||||
version: 0.0.1-alpha.32
|
version: 0.0.1-alpha.33
|
||||||
'@abearxiong/use-config':
|
'@abearxiong/use-config':
|
||||||
specifier: ^0.0.2
|
specifier: ^0.0.2
|
||||||
version: 0.0.2
|
version: 0.0.2
|
||||||
@ -147,8 +147,8 @@ importers:
|
|||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
'@abearxiong/router@0.0.1-alpha.32':
|
'@abearxiong/router@0.0.1-alpha.33':
|
||||||
resolution: {integrity: sha512-ZbGSV7RjKQGQ650Oe6HJBT12SmY7UjaWgSwRVxCF0GdQXxeAlVm0w95tupZvvUXU6+wunozB/IH+YdYqK+64jQ==, tarball: https://npm.pkg.github.com/download/@abearxiong/router/0.0.1-alpha.32/bb54dcffda24b6c7af8caf6016c61391c2aaff1b}
|
resolution: {integrity: sha512-e2ownDhKsRfyjeuxtuThkRWys7cMLN3aLNdMOZKY3XVy2CYy1dZNzI1Mg3z2OY/hdmBtwovASUwJd1peRDPiiQ==, tarball: https://npm.pkg.github.com/download/@abearxiong/router/0.0.1-alpha.33/a36a6d5b5a4d0b28094854a048c438f274a82e47}
|
||||||
|
|
||||||
'@abearxiong/use-config@0.0.2':
|
'@abearxiong/use-config@0.0.2':
|
||||||
resolution: {integrity: sha512-IBOmeP46ykbDlkplFS65UsAHjyPDKnvS2oqbkpLWhbSwDbF5zhBnD4ibsFZKPCyc3lMlPeRqYva4x6puX3E/qQ==, tarball: https://npm.pkg.github.com/download/@abearxiong/use-config/0.0.2/59fbeec8c8e086ec48e55024fe39020b079e6fa5}
|
resolution: {integrity: sha512-IBOmeP46ykbDlkplFS65UsAHjyPDKnvS2oqbkpLWhbSwDbF5zhBnD4ibsFZKPCyc3lMlPeRqYva4x6puX3E/qQ==, tarball: https://npm.pkg.github.com/download/@abearxiong/use-config/0.0.2/59fbeec8c8e086ec48e55024fe39020b079e6fa5}
|
||||||
@ -3095,7 +3095,7 @@ packages:
|
|||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@abearxiong/router@0.0.1-alpha.32':
|
'@abearxiong/router@0.0.1-alpha.33':
|
||||||
dependencies:
|
dependencies:
|
||||||
ws: 8.18.0
|
ws: 8.18.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
69
src/app.ts
69
src/app.ts
@ -1,21 +1,82 @@
|
|||||||
import { App } from '@abearxiong/router';
|
import { App } from '@abearxiong/router';
|
||||||
import { useConfig } from '@abearxiong/use-config';
|
import { useConfig } from '@abearxiong/use-config';
|
||||||
import { dynamicImport } from './lib/dynamic-import.ts';
|
import { dynamicImport } from './lib/dynamic-import.ts';
|
||||||
import { redisPublisher } from './modules/redis.ts';
|
import { redisPublisher, redisSubscriber } from './modules/redis.ts';
|
||||||
|
|
||||||
useConfig();
|
useConfig();
|
||||||
export const emit = (channel: string, message: string) => {
|
export const emit = (channel: string, message?: any) => {
|
||||||
redisPublisher.publish(channel, message);
|
redisPublisher.publish(channel, JSON.stringify(message));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const app = new App<{ import: any, emit: typeof emit }>({
|
export const app = new App<{ import: any; emit: typeof emit }>({
|
||||||
serverOptions: {
|
serverOptions: {
|
||||||
cors: {
|
cors: {
|
||||||
origin: '*',
|
origin: '*',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
io: true,
|
||||||
routerContext: {
|
routerContext: {
|
||||||
import: dynamicImport,
|
import: dynamicImport,
|
||||||
emit,
|
emit,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const clients = [];
|
||||||
|
// 订阅频道 pageEdit, container 单个页面预览 container 整个页面预览
|
||||||
|
type ClientData = {
|
||||||
|
cid?: string; // container id
|
||||||
|
pid?: string[]; // page id
|
||||||
|
cids?: string[]; // container id
|
||||||
|
type: 'page' | 'container' | 'flow';
|
||||||
|
};
|
||||||
|
type MessageData = {
|
||||||
|
source: 'container';
|
||||||
|
data: any;
|
||||||
|
operation?: 'edit';
|
||||||
|
};
|
||||||
|
redisSubscriber.subscribe('pageEdit', () => {
|
||||||
|
console.log('Subscribed to Redis data-updates channel');
|
||||||
|
});
|
||||||
|
redisSubscriber.on('message', (channel, message) => {
|
||||||
|
if (channel !== 'pageEdit') return;
|
||||||
|
const m = JSON.parse(message) as MessageData;
|
||||||
|
clients.forEach((client) => {
|
||||||
|
const data = client.data as any;
|
||||||
|
const { cid, cids = [] } = data || {};
|
||||||
|
const wrapper = (data: any) => {
|
||||||
|
const res = {
|
||||||
|
type: 'pageEdit',
|
||||||
|
source: 'container',
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
return JSON.stringify(res);
|
||||||
|
};
|
||||||
|
const { source, data: mData } = m; // 拆包
|
||||||
|
if (source === 'container') {
|
||||||
|
if (cid === mData?.id) {
|
||||||
|
client.ws.send(wrapper(mData));
|
||||||
|
} else if (cids.includes(mData?.id)) {
|
||||||
|
client.ws.send(wrapper(mData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 其他操作 暂时 不处理
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
});
|
||||||
|
app.io.addListener('subscribe', async ({ data, end, ws }) => {
|
||||||
|
const { type } = data || {};
|
||||||
|
if (type === 'pageEdit') {
|
||||||
|
clients.push({ ws, data: data.data }); // 拆包,里面包含的type信息,去掉
|
||||||
|
end({ code: 200, data: 'subscribe success' });
|
||||||
|
} else if (type === 'unsubscribe') {
|
||||||
|
const index = clients.findIndex((client) => client.ws === ws);
|
||||||
|
clients.splice(index, 1);
|
||||||
|
end({ code: 200, data: 'unsubscribe success' });
|
||||||
|
} else {
|
||||||
|
end({ code: 404, data: 'subscribe fail' });
|
||||||
|
}
|
||||||
|
ws.on('close', () => {
|
||||||
|
const index = clients.findIndex((client) => client.ws === ws);
|
||||||
|
clients.splice(index, 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -61,7 +61,12 @@ add.run = async (ctx) => {
|
|||||||
containerModel = await ContainerModel.findByPk(container.id);
|
containerModel = await ContainerModel.findByPk(container.id);
|
||||||
if (containerModel) {
|
if (containerModel) {
|
||||||
containerModel.update(container);
|
containerModel.update(container);
|
||||||
containerModel.save();
|
await containerModel.save();
|
||||||
|
ctx.emit?.('pageEdit', {
|
||||||
|
source: 'container',
|
||||||
|
data: containerModel.toJSON(),
|
||||||
|
operation: 'edit',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@ -94,13 +99,12 @@ deleteRoute.run = async (ctx) => {
|
|||||||
};
|
};
|
||||||
deleteRoute.addTo(app);
|
deleteRoute.addTo(app);
|
||||||
|
|
||||||
const publish = app.route({
|
app
|
||||||
path: 'container',
|
.route({
|
||||||
key: 'publish',
|
path: 'container',
|
||||||
});
|
key: 'publish',
|
||||||
publish.nextRoute = { path: 'resource', key: 'publishContainer' };
|
nextRoute: { path: 'resource', key: 'publishContainer' },
|
||||||
|
})
|
||||||
publish
|
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
const { data } = ctx.query;
|
const { data } = ctx.query;
|
||||||
const { id, publish, type = 'patch', beta = false } = data;
|
const { id, publish, type = 'patch', beta = false } = data;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user