Dieser Artikel erklärt, wie Sie die serverseitige Unterstützung für die Echtzeit-Update-Funktion im DHTMLX Scheduler einrichten.
Dieser Artikel behandelt die Implementierung des Live Updates-Modus für DHTMLX Scheduler v7.2. Informationen zu früheren Versionen finden Sie hier.
DHTMLX Scheduler enthält den RemoteEvents
-Helper, um Änderungen zwischen mehreren Benutzern sofort zu synchronisieren.
RemoteEvents
-Client öffnet eine WebSocket-Verbindung, sobald der Scheduler initialisiert wird.DataProcessor
mittels REST-API an den Server gesendet.RemoteEvents
-Client empfängt diese Aktualisierungen und übernimmt sie im Scheduler, sodass alle Nutzer dieselben Daten sehen.Dieses Setup unterstützt mehrere DHTMLX-Widgets (wie Kanban, Gantt, Scheduler) innerhalb einer Anwendung, indem ein gemeinsames Format verwendet wird, das die Synchronisierung vereinfacht, ohne dass für jedes Widget ein eigenes Backend erforderlich ist.
Richten Sie RemoteEvents
und DataProcessor
gemeinsam in dem Teil Ihres Codes ein, in dem die Scheduler-Daten geladen werden.
const AUTH_TOKEN = "token";
scheduler.init('scheduler_here', new Date(2025, 3, 20), "week");
scheduler.load("/events");
const dp = scheduler.createDataProcessor({
url: "/events",
mode: "REST-JSON",
headers: {
"Remote-Token": AUTH_TOKEN
}
});
const { RemoteEvents, remoteUpdates } = scheduler.ext.liveUpdates;
const remoteEvents = new RemoteEvents("/api/v1", AUTH_TOKEN);
remoteEvents.on(remoteUpdates);
RemoteEvents
benötigt ein Autorisierungs-Token, das im "Remote-Token"-Header zur serverseitigen Überprüfung gesendet wird.WebSocket
-Endpunkt (zum Beispiel /api/v1).remoteUpdates
-Helper verarbeitet eingehende WebSocket
-Nachrichten und hält die Scheduler-Daten synchron.Dieser Abschnitt beschreibt, wie Sie ein Backend erstellen, das Live-Updates unterstützt.
So probieren Sie es aus:
npm install
und npm run start
aus.Wenn RemoteEvents
startet, sendet es eine GET-Anfrage an den Server, um die Verbindung einzurichten.
Beispiel:
GET /api/v1
Remote-Token: AUTH_TOKEN
Antwort:
{"api":{},"data":{},"websocket":true}
Nach dem Handshake öffnet RemoteEvents
die WebSocket-Verbindung über den Endpunkt.
Beispiel:
ws://${URL}?token=${token}&ws=1
Der Server überprüft das Token und antwortet mit einer Nachricht wie:
{"action":"start","body":"connectionId"}
Beispiel-Codeausschnitt:
app.get('/api/v1', (req, res) => {
const token = req.headers['remote-token'];
if (!token || !verifyAuthHeader(token)) {
return res.status(403).json({ error: 'Forbidden' });
}
res.json({ api: {}, data: {}, websocket: true });
});
wss.on('connection', (ws, req) => {
const token = new URLSearchParams(req.url.split('?')[1]).get('token');
if (!token || !verifyAuthToken(token)) {
ws.close(1008, 'Unauthorized');
return;
}
const connectionId = generateConnectionId();
ws.send(JSON.stringify({ action: 'start', body: connectionId }));
});
Nach dem Verbindungsaufbau abonniert RemoteEvents
Updates für bestimmte Entitäten — beim Scheduler ist dies events
:
{"action":"subscribe","name":"events"}
Um keine Updates mehr zu erhalten:
{"action":"unsubscribe","name":"events"}
Dieses Setup eignet sich gut für Apps, die mehrere DHTMLX-Widgets gleichzeitig verwenden. So kann jedes Widget nur die Updates abonnieren, die es benötigt.
Beispiel für die serverseitige Verarbeitung:
ws.on('message', function(message) {
try {
const msg = JSON.parse(message);
const client = clients.get(connectionId);
if (!client) return;
if (msg.action === 'subscribe') {
client.subscriptions.add(msg.name);
} else if (msg.action === 'unsubscribe') {
client.subscriptions.delete(msg.name);
}
} catch (err) {
console.error('Error parsing WebSocket message:', err);
}
});
Der Server verschickt WebSocket-Nachrichten, um die Clients über das Erstellen, Aktualisieren oder Löschen von Terminen zu informieren. Dabei wird folgendes Format verwendet.
Wenn diese Nachrichten eintreffen, aktualisiert der Scheduler die Daten automatisch mit dem remoteUpdates
-Helper.
Termin erstellt
{"action":"event","body":{"name":"events",
"value":{"type":"add-event","event":EVENT_OBJECT}}}
Beispiel:
app.post('/events', (req, res) => {
const newEvent = req.body.event;
const insertedEvent = crud.events.insert(newEvent);
// Benachrichtige alle verbundenen Clients über das neue Event
const message = {
name: 'events',
value: {
type: 'add-event', event: insertedEvent
}
};
broadcast('event', message);
res.status(200).json({ id: insertedEvent.id });
});
function broadcast(action, body) {
const entity = body.name;
for (const [connectionId, client] of clients.entries()) {
const { ws, subscriptions } = client;
if (subscriptions.has(entity) && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ action, body }));
}
}
}
Termin aktualisiert
{"action":"event","body":{"name":"events",
"value":{"type":"update-event","event":EVENT_OBJECT}}}
Beispiel:
app.put('/events/:id', (req, res) => {
const id = req.params.id;
const updatedEvent = req.body.event;
crud.events.update(id, updatedEvent);
// Benachrichtige die Clients über die Aktualisierung
const message = {
name: 'events',
value: {
type: 'update-event', event: updatedEvent
}
};
broadcast('event', message);
res.status(200).send();
});
Termin gelöscht
{"action":"event","body":{"name":"events",
"value":{"type":"delete-event","event":{"id":ID}}}}
Beispiel:
app.delete('/events/:id', (req, res) => {
const id = req.params.id;
crud.events.delete(id);
// Informiere die Clients über das Löschen
const message = {
name: 'events',
value: {
type: 'delete-event',
event: { id }
}
};
broadcast('event', message);
res.status(200).send();
});
Der RemoteEvents
-Helper übernimmt das initiale Handshake und die WebSocket-Verbindung, während der remoteUpdates
-Helper eingehende Nachrichten verarbeitet und den Scheduler entsprechend aktualisiert.
const { RemoteEvents, remoteUpdates } = scheduler.ext.liveUpdates;
const remoteEvents = new RemoteEvents("/api/v1", AUTH_TOKEN);
remoteEvents.on(remoteUpdates);
In der Regel funktionieren diese Helper direkt. Es ist jedoch möglich, das Protokoll zu erweitern, indem Sie eigene Handler oder Helper für spezielle Remote-Update-Szenarien hinzufügen.
Die Methode RemoteEvents.on
akzeptiert ein Objekt, das Handler für eine oder mehrere Entitäten definieren kann:
const remoteEvents = new RemoteEvents("/api/v1", AUTH_TOKEN);
remoteEvents.on({
events: function(message) {
const { type, event } = message;
switch (type) {
case "add-event":
// Event hinzufügen verarbeiten
break;
case "update-event":
// Event aktualisieren verarbeiten
break;
case "delete-event":
// Event löschen verarbeiten
break;
}
}
});
Um eigene Aktionen zu verarbeiten, können Sie einen weiteren Handler zu remoteEvents
hinzufügen:
const { RemoteEvents, remoteUpdates } = scheduler.ext.liveUpdates;
const remoteEvents = new RemoteEvents("/api/v1", AUTH_TOKEN);
remoteEvents.on(remoteUpdates);
remoteEvents.on({
events: function(message) {
const { type, event } = message;
switch (type) {
case "custom-action":
// Eigene Aktion verarbeiten
break;
}
}
});
Dieser Handler wird durch Nachrichten wie diese ausgelöst:
{"action":"event","body":{"name":"events",
"value":{"type":"custom-action","event":value}}}
Um Updates für eigene Entitäten zu erhalten, fügen Sie einen entsprechenden Handler hinzu:
const { RemoteEvents, remoteUpdates } = scheduler.ext.liveUpdates;
const remoteEvents = new RemoteEvents("/api/v1", AUTH_TOKEN);
remoteEvents.on(remoteUpdates);
// Abonniere eigene Entitäten
remoteEvents.on({
calendars: function(message) {
const { type, value } = message;
switch (type) {
case "custom-action":
// Eigene Aktion verarbeiten
break;
}
}
});
Mit diesem Setup sendet remoteEvents
eine Abonnement-Nachricht wie:
{"action":"subscribe","name":"calendars"}
Und der Handler reagiert auf Nachrichten wie:
{"action":"event","body":{"name":"calendars",
"value":{"type":"custom-action","value":value}}}
Diese Anleitung beschreibt die Grundlagen für die Einrichtung und Anpassung von Live-Updates im DHTMLX Scheduler. Für ein vollständiges, funktionierendes Beispiel besuchen Sie das GitHub-Repository.
Nach oben