diff --git a/packages/apps/artusx-koa/src/controller/home.ts b/packages/apps/artusx-koa/src/controller/home.ts index cd05dd3..6c7928c 100644 --- a/packages/apps/artusx-koa/src/controller/home.ts +++ b/packages/apps/artusx-koa/src/controller/home.ts @@ -1,3 +1,5 @@ +import { PassThrough } from 'stream'; + import { ArtusXErrorEnum, ArtusXInjectEnum, @@ -10,10 +12,14 @@ import { StatusCode, } from '@artusx/core'; +import EventEmitterService, { EventMessage } from '../module-events/eventEmitter.service'; import type { ArtusXContext, Log4jsClient, NunjucksClient } from '@artusx/core'; @Controller() export default class HomeController { + @Inject(EventEmitterService) + eventEmitterService: EventEmitterService; + @Inject(ArtusXInjectEnum.Application) app: ArtusApplication; @@ -50,6 +56,35 @@ export default class HomeController { return this.nunjucks.render('index.html', { title: 'ArtusX', message: 'Post method' }); } + @GET('/stream') + async stream(ctx: ArtusXContext) { + ctx.set({ + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache', + Connection: 'keep-alive', + 'Access-Control-Allow-Origin': '*', + }); + + const stream = new PassThrough(); + + ctx.respond = false; + ctx.res.statusCode = 200; + stream.pipe(ctx.res); + + const listener = (msg: EventMessage) => { + console.log('listener', msg); + stream.write(`data: ${msg.data}\n\n`); + }; + + // handle message + this.eventEmitterService.on('stream', listener); + + // init message + this.eventEmitterService.emit('stream', { + data: '/stream: init', + }); + } + @GET('/error') @StatusCode(403) async error(ctx: ArtusXContext) { diff --git a/packages/apps/artusx-koa/src/module-events/eventEmitter.service.ts b/packages/apps/artusx-koa/src/module-events/eventEmitter.service.ts new file mode 100644 index 0000000..99e19e9 --- /dev/null +++ b/packages/apps/artusx-koa/src/module-events/eventEmitter.service.ts @@ -0,0 +1,18 @@ +import { EventEmitter } from 'events'; +import { ArtusApplication, ArtusXInjectEnum, Inject, Injectable, ScopeEnum } from '@artusx/core'; + +@Injectable({ + scope: ScopeEnum.SINGLETON, +}) +export default class EventEmitterService extends EventEmitter { + @Inject(ArtusXInjectEnum.Application) + app: ArtusApplication; + + constructor() { + super(); + } +} + +export type EventMessage = { + data: any; +}; diff --git a/packages/apps/artusx-koa/src/module-events/stream.schedule.ts b/packages/apps/artusx-koa/src/module-events/stream.schedule.ts new file mode 100644 index 0000000..40d594a --- /dev/null +++ b/packages/apps/artusx-koa/src/module-events/stream.schedule.ts @@ -0,0 +1,22 @@ +import dayjs from 'dayjs'; +import { Inject, Schedule } from '@artusx/core'; + +import EventEmitterService from './eventEmitter.service'; +import type { ArtusXSchedule } from '@artusx/core'; + +@Schedule({ + enable: true, + cron: '*/5 * * * * *', + runOnInit: false, +}) +export default class StreamSchedule implements ArtusXSchedule { + @Inject(EventEmitterService) + eventEmitterService: EventEmitterService; + + async run() { + this.eventEmitterService.emit('stream', { + data: `StreamSchedule: ${dayjs().format('YYYY-MM-DD HH:mm:ss')}`, + }); + console.log('StreamSchedule.run', dayjs().format('YYYY-MM-DD HH:mm:ss')); + } +} diff --git a/packages/apps/artusx-koa/src/public/index.js b/packages/apps/artusx-koa/src/public/index.js new file mode 100644 index 0000000..be38ae0 --- /dev/null +++ b/packages/apps/artusx-koa/src/public/index.js @@ -0,0 +1,32 @@ +document.addEventListener('DOMContentLoaded', () => { + const initEventSource = (url, onMessage) => { + if (!EventSource) { + console.error('EventSource is not supported'); + return; + } + + const eventSource = new EventSource(url); + + // eventSource.onopen = () => { + // console.log('EventSource connected:', url); + // }; + + eventSource.onmessage = (event) => { + onMessage(event.data); + }; + + eventSource.onerror = (error) => { + console.error('EventSource error:', error); + }; + + return eventSource; + }; + + const eventSource = initEventSource('/stream', (data) => { + console.log('Event:', data); + }); + + eventSource.onopen = () => { + console.log('EventSource connected'); + }; +}); diff --git a/packages/apps/artusx-koa/src/view/index.html b/packages/apps/artusx-koa/src/view/index.html index 35212f4..a47fbb9 100644 --- a/packages/apps/artusx-koa/src/view/index.html +++ b/packages/apps/artusx-koa/src/view/index.html @@ -5,7 +5,9 @@