ein freies Lehrmittel auf der Basis von eduskript

Real-Time Events

Server-Sent Events (SSE) for push notifications without polling.

Architecture

Teacher saves → Server → EventBus → SSE → Students

Event Types

type AppEvent =
  | { type: 'class-invitation'; classId: string; className: string }
  | { type: 'teacher-annotation'; classId: string; pageId: string; annotation: Annotation }
  | { type: 'quiz-submission'; quizId: string; studentPseudonym: string }
  | { type: 'collaboration-request'; fromUserId: string; fromName: string }

Channel Naming

PatternUse
user:${userId}User-specific notifications
class:${classId}Class-wide broadcasts
class:${classId}:studentsStudents only
quiz:${quizId}Quiz state changes

Publishing Events

import { eventBus } from '@/lib/events'

await eventBus.publish(`class:${classId}`, {
  type: 'teacher-annotation',
  classId,
  pageId,
  annotation: data
})

Client Hook

import { useRealtimeEvents } from '@/hooks/use-realtime-events'

useRealtimeEvents(
  ['class-invitation'],
  (event) => handleInvitation(event),
  enabled
)

EventBus Implementations

ImplementationUse Case
memory-bus.tsSingle server (default)
postgres-bus.tsMulti-instance (PostgreSQL LISTEN/NOTIFY)

Switch via EVENT_BUS=postgres environment variable.

Teacher Broadcast Mode

Teachers can broadcast annotations to students in real-time:

  1. Teacher enables Broadcast Mode for a class
  2. Annotation saves trigger broadcast (piggybacks on 2s debounce)
  3. Students receive same data format as DB storage
  4. Late-joining students load from DB

Performance

MetricValue
Latency<100ms
Per connection~1KB memory
Browser limit6 SSE connections/domain

Key Files

FilePurpose
src/lib/events/types.tsEvent definitions
src/lib/events/memory-bus.tsIn-memory implementation
src/lib/events/index.tsFactory export
src/app/api/events/stream/route.tsSSE endpoint
src/hooks/use-realtime-events.tsClient hook