Entwicklung eines Chats - Teil I

Aufgrund meines aktuellen Projekts setzte ich mich mit verschiedenen Kommunikationsmechanismen auseinander. Unter anderen geht es dabei um Chatfunktionen (Austausch von Nachrichten), Telefonie oder Videokonferenzen.
Dieser erste Teil hat ein relativ langes Vorwort und beinhaltet erst nur die konzeptionelle Idee für die Umsetzung und ein Beispielprojekt.
Insgesamt plane ich hierfür drei Artikel:
- Teil I – Grundlagen und Konzept (dieser Artikel)
- Teil II – Entwicklung eines Servers
- Teil III – Entwicklung eines Clients
Der erste Teil stellt eine allgemeine Einführung in Chat bzw. Netzwerkkommunikation dar. Ich werde einige Konzepte erklären und Entscheidungsmöglichkeiten hervorheben. Zudem definieren wir hier den Funktionsumfang für das Demoprojekt. Teil II und III beinhalten die konkrete Entwicklung. Hier wird vor allem auf die Umsetzung der geforderten Funktionen eingegangen.
Im ersten Teil beginne ich mit einem sehr allgemeinen Kundenwunsch, welcher nach und nach durch Fragen und Abgrenzungen näher definiert wird. Durch diese Definition ist es uns möglich, ein Produkt (das Programm) zu entwickeln.
Vorwort
Weshalb ich mich entschlossen habe, über eine eigene Entwicklung und das Vorgehen dazu zu schreiben hat mehrere Gründe:
- Ich bin auf vielen Seiten gewesen, um entsprechende Tutorials oder Get-Started-Dokumente zu lesen. Bei diesen ging es darum, wie ein Live-Chat als Browser- oder Desktopanwendung realisiert werden kann
- Viele dieser Tutorials beinhalten einfach den Quellcode mit (sehr) kurzer Erklärung
- Mir fehlen Entscheidungsgründe, warum etwas verwendet oder nicht verwendet wird. Manche Artikel gehen nur sehr minimal darauf ein
Wenn ich konkret nach der Umsetzung suche, wie ich mein Problem lösen kann, gibt es ein sehr breites Angebot. Es gibt viele Tutorials, die eine Schritt für Schritt Entwicklung durchführen. Andere haben hingegen nur ein paar Zeilen Quellcode. Bei einigen Artikeln finde ich es schade, dass es nur heißt „wir machen das und das und so sieht der Code aus“.
Ich finde wichtig, die Warum-Fragen zu beantworten. Warum nehme ich TCP statt UDP? Warum nehme ich Threads für den Server? Warum entscheide ich mich für oder gegen eine Art der Umsetzung?
Die Beantwortung dieser Fragen bringen dem Programmierer das Konzept bei. Und dann ist egal, wie die Lösung aussieht. Diese kann anschließend in Java, C#, PHP, Python oder einer anderen Programmiersprache entwickelt werden. Wenn das Konzept verstanden wurde und der Programmierer dieses Konzept umsetzen bzw. herleiten kann, dann ist ein Programmierer ein Programmierer[1].
Ich möchte zuerst einige Begriffe definieren und erklären. Nachdem die gewünschten Funktionen definiert und abgegrenzt wurden, stellen Teil II und III eine mögliche Umsetzung vor.
Mein definiertes Ziel für diese Artikel besteht in der Vorstellung und Präsentation einer möglichen Vorgehensweise, um das Ziel “Chat-Client” zu erreichen[2]. Ich möchte den Weg skizzieren, welcher beim Kunden anfängt mit “Ich möchte Chatten” und mit einem fertigen Produkt endet.
Diese Artikelserie soll daher eher das Konzept vorstellen. Was wollte der Kunde haben, welche technischen Möglichkeiten gibt es und warum entscheiden wir uns für den einen oder den anderen Weg. Es mag viele verschiedene Lösungen geben und jede hat ihre Daseinsberechtigung. Seht das Projekt bitter daher als Leitfaden 🙂
Das Chat-Konzept
In diesem Szenario haben wir einen Kunden mit einem Wunsch. Dieser Kunde möchte einen Chat haben. So oder so ähnlich allgemein sind wahrscheinlich viele Kundenanfragen. Durch Fragen wie „Wie viele Benutzer sollen Chatten?“, „Gibt es ein Login oder kann jeder dem Chat beitreten?“, „Können die Anwender Daten austauschen?“ können wir einen bestimmten Funktionsumfang abgrenzen und aus dem abstrakten Wunsch eine Liste mit geforderten Funktionen ableiten.
Gewünschte Funktionen
Durch das Gespräch wurden folgende Punkte definiert:
-
Der Anwender kann mit anderen angemeldeten Personen in Echtzeit chatten
-
Jeder, der das Programm hat, kann dem Chat beitreten
-
Beim Anmelden muss die Person einen beliebigen Benutzernamen angeben
-
Es gibt keine Benutzerkontos oder eine Kontoverwaltung
-
Der Benutzername innerhalb einer Sitzung darf nur einmalig vergeben werden
-
Es gibt nur einen Raum, in dem öffentlich gechattet wird. Jeder, der zum Zeitpunkt der Nachricht angemeldet ist, kann die Nachricht lesen
-
Es gibt die Möglichkeit zu flüstern (private Nachricht)
-
Der Anwender soll folgende Möglichkeiten haben
-
Liste aller aktuell eingeloggten Personen
-
Lesen und schreiben des öffentlichen Chats
-
Lesen und schreiben von privaten Nachrichten
-
An- und Abmelden
-
Setzten des Benutzernamens
-
Aufrufen einer Hilfe oder Dokumentation zur Benutzung
Anmerkung: Diese Anforderungen sind teilweise immernoch sehr allgemein. Zur Erstellung von Pflichten- und Lastenheften gibt es gute Literatur. Die o.g. Punkte sollen einen groben Funktionsrahmen abstecken
Organisatorisches Umfeld
Unter dem organisatorischen Umfeld wird das Umfeld verstanden, in welchem die Anwendung eingesetzt wird. Darunter fallen die Anwender (mit ihrem Kenntnisstand), die technische Ausrüstung (z.B. Leistungsfähigkeit des Computers) oder andere organisatorische Vorgaben (z.B. nur kostenlose Open-Source Software verwenden).
Das Umfeld hat indirekten Einfluss auf das Konzept der Anwendung. Wenn es eine heterogene Landschaft ist, in welcher Windows, Linux und iOS gleichermaßen eingesetzt wird, müsste unsere Anwendung für alle 3 Betriebssysteme konzipiert werden.
Technisches Umfeld
Das technische Umfeld in Zusammenhang mit den Anforderungen definiert die Möglichkeiten, die Anforderungen umzusetzen. Nachfolgend werden verschiedene Vorgehensweisen vorgestellt und diskutiert.
Chat in Echtzeit mit angemeldeten Benutzern
Chat in Echtzeit mit anderen Benutzern ist die Kernanforderung von jedem Chat. Doch wie lässt sich diese realisieren? Es könnte zum einen ein bestimmtes Objekt innerhalb einer Schleife auf eine Änderung geprüft werden (polling) oder der Client empfängt ein Signal. Auf dieses Signal kann die Anwendung reagieren und die neue Nachricht anzeigen.
Von der Auslastung her macht es mehr Sinn mit Signalen zu arbeiten. Beim Polling wird innerhalb einer Schleife dauerhaft ein Objekt überwacht. Dies kostet jedoch viel Rechenzeit. Das ist vergleichbar mit der Haustüre. Beim Polling würde der Bewohner jede Minute an die Tür gehen und prüfen, ob jemand da ist. Wartet der Bewohner jedoch auf ein Signal (die Klingel) kann parallel etwas anderes gemacht werden. Erst auf das Klingelzeichen wird reagiert.
Die Echtzeit lässt sich am besten mit Sockets realisieren. Für den Browser gibts es seit einiger Zeit WebSockets . Sockets bauen eine direkte Verbindung mit einem anderen Computer auf und übertragen darüber Daten. Sockets werden vom Betriebssystem bereitgestellt. Bei WebSockets besteht die Besonderheit, dass Sockets im Browser verwendet werden können, um Browseranwendungen mit Echtzeit-Elementen zu ermöglichen. Jedoch muss dies von dem Browser und Server unterstützt werden.
Auf Sockets werde ich in Teil II näher eingehen, da dieser die Realisierung behandelt.
Funktionen der Benutzer
Der Anwender muss einen Namen angeben und erhält die Möglichkeit, bestimmte Befehle auszuführen. Die benötigten Daten muss der Client bereitstellen. Entweder speichert er diese selbst oder fordert diese von einer Quelle (Server) an.
Topologie
Es gibt verschiedene Arten, um die Topologie des Chats zu organisieren. Diese sind P2P und das Client-Server-Modell. Diese Modelle sind als Schema in folgender Grafik zu sehen:

Client-Server und P2P als grafische Netzwerktopologie dargestellt
Client-Server-Modell
Bei diesem Modell gibt es einen Server, den alle Clients kennen. Dieser verwaltet zentral die Benutzer und die Kommunikation. Wenn es einen zentralen Server gibt, mit welchem die Clients kommunizieren, wird dies Client-Server-Modell genannt. Wenn der Anwender eine Nachricht an alle sendet, sendet der Client die Nachricht nur an den Server. Dieser verteilt die Nachricht an alle Clients weiter.
Der Vorteil bei dieser Lösung besteht darin, dass nur eine zentrale Stelle die angemeldeten Benutzer und den Nachrichtenaustausch organisieren muss. Ein Client muss nur eine einzige Verbindung öffnen, um Nachrichten zu senden und empfangen. Der Nachteil ist jedoch, dass der gesamte Chat nicht mehr funktioniert, falls der Server ausfällt.
P2P-Modell
Bei dem P2P-Modell verbindet sich jeder Client mit jedem Client. Es gibt keinen zentralen Server und die Nachrichten müssen von dem Client selbst an alle Nutzer gesendet werden. Bei dieser Topologie wird ein dezentrales Chat-Netzwerk aufgebaut und die Clients sind von einem zentralen Server unabhängig. Die Clients fungieren selbst als lokaler Server, welcher die Nachrichten empfängt oder sendet.
Falls eine Stelle ausfällt, kann der Rest immernoch Chatten. Jedoch muss einer von den Clients bekannt sein, um eine Verbindung herzustellen. Auch das Broadcasten (senden einer Nachricht an alle Benutzer) wird aufwändig, da ein Client die Adressen von allen anderen kennen muss.
Ausblick und Abgrenzung
Aufgrund der Anforderungen und der Komplexität, wird diese Anwendung als Client-Server-Modell erstellt. Da es die Anforderung gibt, dass jeder mit jedem chatten kann, müsste bei einem P2P-Chat-Netzwerk eine Synchronisation der verschiedenen Clientadressen stattfinden. Die Clients müssten Änderungen im Netzwerk (an-/abmeldung) an die verbundenen Clients weiterreichen. Eine Client-Server-Architektur bietet zudem den Vorteil, dass eine Benutzerverwaltung (falls später gewünscht) einfacher zu implementieren ist.
Des Weiteren werde ich die Anwendung als Konsolenprojekt umsetzen. Dadurch möchte ich den Codeumfang reduzieren. Ein- und Ausgaben in Textboxen und Fenstern benötigen zusätzlichen Aufwand und Code. Falls jemand dieses Projekt selbst programmieren möchte, erhält derjenige mit dem Projekt eine Kommunikationsbasis und kann eine eigene GUI entwickeln. Auch hier nochmal der Hinweis: Mir geht es vor allem darum, die Vorgehensweise zu beleuchten!
Dieses Projekt umfasst die Kernfunktionen eines Chats und es werden nicht alle möglichen Fehler abgefangen oder behandelt. Ich werde jedoch auf möglich Fehler hinweisen und diese markieren.
- [1]: Ich verstehe darunter eine Person, die das Konzept entwerfen und umsetzen kann (unabhängig vom Code und der Programmiersprache). Auch aus allgemeinen Anfragen wie „Programmier mir einen Chat“ kann ein Programmierer die Anforderungen herleiten/abfragen und die Anwendung realisieren. Für manche Personen ist ein Programmierer nur jemand, der Code schreibt.
- [2]: Es gibt verschiedene Wege, um das Ziel zu erreichen. Ich denke nicht, dass mein Weg der einzig Richtige ist. Ich möchte diesen jedoch vorstellen und vielleicht liefert dies eine gute Diskussionsgrundlage, um das eigene Vorgehen zu verbessern oder zu reflektieren.