Skip to content

Commit

Permalink
feat(artusx-koa): support server send events
Browse files Browse the repository at this point in the history
  • Loading branch information
thonatos committed Oct 22, 2024
1 parent d6389f1 commit f37cf3e
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 0 deletions.
35 changes: 35 additions & 0 deletions packages/apps/artusx-koa/src/controller/home.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { PassThrough } from 'stream';

import {
ArtusXErrorEnum,
ArtusXInjectEnum,
Expand All @@ -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;

Expand Down Expand Up @@ -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) {
Expand Down
18 changes: 18 additions & 0 deletions packages/apps/artusx-koa/src/module-events/eventEmitter.service.ts
Original file line number Diff line number Diff line change
@@ -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;
};
22 changes: 22 additions & 0 deletions packages/apps/artusx-koa/src/module-events/stream.schedule.ts
Original file line number Diff line number Diff line change
@@ -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'));
}
}
32 changes: 32 additions & 0 deletions packages/apps/artusx-koa/src/public/index.js
Original file line number Diff line number Diff line change
@@ -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');
};
});
2 changes: 2 additions & 0 deletions packages/apps/artusx-koa/src/view/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{title}}</title>
<link rel="stylesheet" href="/public/style.css" />
<script src="/public/index.js"></script>
</head>

<body>
{% include "nav.html" ignore missing %}
<div class="container">
Expand Down

0 comments on commit f37cf3e

Please sign in to comment.