Benutzer mit den meisten Antworten
Instant Messager-Vorgehen

Frage
-
Nachdem ich einen einfacheres Server Client Programm mit TCP geschrieben habe, fühle ich mich nun sicher genung um den Instant Messager zu machen.
Ich habe mir das vorgehen so gedacht:
Server:
1.Thread: Benutereingabe
2.Thread:Warten auf eingehende Nachrichten bzw. Logins, Register, und anfragen auf alle angemeldeten Nuter.
3 Thread: Weiterleiten der Nachricht. Soll ich hier einfach einen TCPListener in jedem Cleint verwenden? Würde eine Liste verwenden, mit der foreach Schleife durchgehen, und dann Verbindung aufbauen und versenden.
Client:
1.Listbox, aller regestrierten Benutzer, und aller die online sind. In dem SelectionChanged-Event würde ich dann nochmal die Liste vom Server abrufen, und ggF. einen Chat mit einer Listbox aller gesendeten bzw. empfangen Liste und eine Textbox öffnen. Beim senden einer Nachricht dann den Server anfragen, dann eine Nachrichten Klasse senden.
Nachricht Klasse:
-Sender
-Empfänger
-Inhalt
Stimmt mein Prinzip so, oder was sollte ich verändern?
LG
Antworten
-
Hi,
die Schleife baust Du mit do...loop auf. In der Schleife prüfst Du, ob es Einträge in einer Warteschlange gibt, die dann nacheinander abgearbeitet werden. Ein Eintrag in der Warteschlange beschreibt, was zu tun ist, z.B., von wem, an wen, welcher Nachrichtentext zu versenden ist. Wenn nichts mehr zu tun ist, dann wartest Du über ein WaitAny auf die nächste Aufgabe oder den Abbruch der Schleife. Sobald sich ein Client meldet, trägst Du in die Wartschlange die nächste Aufgabe ein und informierst mit Set, dass das Warten in der Schleife zu beenden ist und wieder Aufgaben zur Verarbeitung anliegen. Aufgaben können z.B. sein: Warten auf eine Anmeldung, Warten auf eine Nachricht, Versenden einer Nachricht.--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks
Kommas richtig setzen!
Schüler sagen, Lehrer haben es gut.
Schüler, sagen Lehrer, haben es gut- Als Antwort markiert R3turnz Samstag, 17. Oktober 2015 20:13
Alle Antworten
-
Hi,
mit der Berechtigung wollte ich nur wissen, ob jeder dem Chat beitreten darf oder nur ausgewählte Personen etc.. Ich habe mal vor vielen Jahren in einem Seminar einen Chatserver in VB.NET programmiert. Hoffe das bringt dich ein bisschen weiter.
ChatServer: Hierbei handelt es sich um eine Consolen-Anwendung!
Public Class Client Public m_tcpclient As TcpClient Public m_server As Server Public sr As StreamReader Public sw As StreamWriter Public name As String Sub New(ByVal tcpClient As System.Net.Sockets.TcpClient, _ ByVal server As Server) m_tcpclient = tcpClient m_server = server End Sub Sub run() sr = New StreamReader(m_tcpclient.GetStream) sw = New StreamWriter(m_tcpclient.GetStream) sw.AutoFlush = True name = sr.ReadLine m_server.add(Me) Try While Not sr.EndOfStream Dim zeile As String = sr.ReadLine Dim befehl As String = sr.ReadLine 'Das hier ist die Reihenfolge des Protokolls!!! m_server.verarbeite(name, befehl, zeile) End While Catch ex As Exception Console.WriteLine(ex.Message) End Try m_server.remove(Me) End Sub Sub writeline(ByVal zeile As String) sw.WriteLine(zeile) End Sub Sub werdeGekickt() m_server.remove(Me) End Sub End Class
Module Module1 Sub Main() Dim server As New Server server.run() End Sub End Module
Public Class Server Public liste As New List(Of Client) Sub run() Dim ip As System.Net.IPAddress = System.Net.IPAddress.Parse("127.0.0.1") Dim tcplistener As New System.Net.Sockets.TcpListener(ip, 1234) tcplistener.Start() Do Dim tcpclient As System.Net.Sockets.TcpClient = tcplistener.AcceptTcpClient Dim client As New Client(tcpclient, Me) Dim thread As New System.Threading.Thread(AddressOf client.run) thread.Start() Loop End Sub Sub add(ByVal client As Client) liste.Add(client) End Sub Public Sub remove(ByVal client As Client) liste.Remove(client) End Sub Sub verarbeite(ByVal name As String, ByVal befehl As String, ByVal zeile As String) Select Case befehl Case "say" For Each c As Client In liste c.writeline("say") c.writeline(name & " : " & zeile) Next Case "quit" For Each c As Client In liste c.writeline("Benutzer " & name & " hat den Chat verlassen!") If c.name = name Then c.writeline("die") c.writeline("") c.werdeGekickt() End If Next Case "kick" Dim opfer As Client = Nothing For Each c As Client In liste c.writeline("say") c.writeline(zeile & " wurde von " & name & " gekickt!!") If c.name = zeile Then opfer = c End If Next If opfer IsNot Nothing Then opfer.writeline("die") opfer.writeline("") opfer.werdeGekickt() remove(opfer) End If End Select End Sub End Class
Und hier ist der Client in WindowsForms:
Public Class FormClient Private tcpClient As System.Net.Sockets.TcpClient Private sw As System.IO.StreamWriter Private sr As System.IO.StreamReader Private Sub ButtonConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonConnect.Click If Me.TextBoxName.Text = "" Then MessageBox.Show("Bitte Name eingaben!", "Fehler", MessageBoxButtons.OK) Return End If tcpClient = New System.Net.Sockets.TcpClient("localhost", 1234) sw = New System.IO.StreamWriter(tcpClient.GetStream) sr = New System.IO.StreamReader(tcpClient.GetStream) sw.AutoFlush = True sw.WriteLine(Me.TextBoxName.Text) Me.TextBoxName.Enabled = False Me.ButtonConnect.Enabled = False Me.TextBoxAusgabe.Enabled = True Me.TextBoxEingabe.Enabled = True Me.ButtonSenden.Enabled = True 'Me.TimerChecker.Start() Me.BackgroundWorker1.RunWorkerAsync() End Sub Private Sub TimerChecker_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerChecker.Tick If Not tcpClient.Connected Then Me.Close() If tcpClient.GetStream.DataAvailable Then Dim befehl As String = sr.ReadLine Dim zeile As String = sr.ReadLine Select Case befehl Case "die" Me.Close() Return Case "say" Me.TextBoxAusgabe.Text &= zeile & vbCrLf End Select End If End Sub Private Sub ButtonSenden_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSenden.Click sw.WriteLine(Me.TextBoxEingabe.Text) sw.WriteLine(Me.TextBoxBefehl.Text) Me.TextBoxEingabe.Text = "" Me.TextBoxBefehl.Text = "" End Sub Private Delegate Sub addStringDelegant(ByVal zeile As String) Private Delegate Sub quitDelegant() Private Sub addString(ByVal zeile As String) Me.TextBoxAusgabe.Text &= zeile & vbCrLf End Sub Private Sub quit() MessageBox.Show("Und Tschüss", "haha") Me.Close() End Sub Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork Do Dim befehl As String = sr.ReadLine Dim zeile As String = sr.ReadLine Select Case befehl Case "die" Me.Invoke(New quitDelegant(AddressOf Me.quit)) Return Case "say" Me.Invoke(New addStringDelegant(AddressOf Me.addString), zeile) End Select System.Console.Beep(1000, 10) System.Threading.Thread.Sleep(1000) Loop End Sub Private Sub FormClient_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load End Sub End Class
Die Form solltest du mit wenigen Clicks zusammengestellt bekommen. Achte mal auf die Befehle die zur Verfügung stehen.
-
Hi,
wie David bereits bemerkt hat, sollten vor Beginn einige Details festgelegt werden, die als Grundlage für die Lösung dienen. Ich sehe da die folgenden Festlegungen:1. Die Server-Funktionalität sollte als selbständige Lösung ohne Benutzereingaben für den eigentlichen Prozess aufgebaut werden.
2. Zwei Threads in der Client-Lösung reichen: 1. für die Oberfläche, 2. für die Kommunikation.
3. Für die Kommunikation sollte ein logisches Interface spezifiziert werden, welches den Typ der konkreten Nachricht, den Nachrichteninhalt und ggf. weitere Zustandsinformation enthält, z.B. als serialisierbaren XML-Strom.
Der Kommunikations-Thread sollte sowohl für Verbindungsaufbau, Login, Statusaustausch und auch die Nachrichten selbst verantwortlich. Er sollte so programmiert werden, dass er über eine "Warteschlange" zyklisch die anstehenden kurz zu haltenden Aktivitäten abarbeitet.
Ein Beispiel dazu hatte ich auf meiner Homepage veröffentlicht unter multilateraler Chat.
Viel Spass.
--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks
Kommas richtig setzen!
Schüler sagen, Lehrer haben es gut.
Schüler, sagen Lehrer, haben es gut -
Danke,
für die Antworten:
@David: Ich kann leider nur C# bzw. WPF, daher bringt mir der Code erdenklich wenig.
1.Ich weiß nicht genau was du meinst.
2.OK
3.Ich hatte auch an eine Nachrichten Klasse gedacht. Des weiteren hätte ich einfach einen BinaryWriter/Reader verwendet.
4.Also eine Liste mit Aufgaben?`WIe genau muss ich mir das vorstellen?
LG
-
Hi,
ich vermute mal, dass Du mir geantwortet hast.Mit Server-Funktionalität meine ich beispielsweise eine Konsolenanwendung, die auf Clients hört und auf jede Anforderung eines Clients eine Antwort zurücksendet. Diese Anwendung läuft auf irgendeinem Rechner und zeigt auf der Konsole maximal ein Protokoll der Arbeit.
Zwischen Client und Server gibt es unterschiedliche Fragen und Antworten, z.B. Anmelden (wer bin ich); Fragen, wer noch angemeldet ist; Nachricht an einen Client schicken, Nachricht an alle Clients schicken usw. Diese sollte man in eine Datenstruktur packen, z.B. ein Nachrichten-Objekt, welches serialisiert übertragen wird.
Mit einer Liste von Aufgaben meine ich: "was ist als nächstes zu tun?", z.B. Senden einer Antwort aufgrund einer Anforderung. Wenn beispielsweise alle Clients eine Nachricht bekommen sollen, dann werden entsprechend der angemeldeten Client für jeden Client Aufgaben in die Liste gestellt, die dann zyklisch abgearbeitet werden. Am besten ist dafür ein FIFO-Schlange (Queue) geeignet.
--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks
Kommas richtig setzen!
Schüler sagen, Lehrer haben es gut.
Schüler, sagen Lehrer, haben es gut -
Hi,
die Schleife baust Du mit do...loop auf. In der Schleife prüfst Du, ob es Einträge in einer Warteschlange gibt, die dann nacheinander abgearbeitet werden. Ein Eintrag in der Warteschlange beschreibt, was zu tun ist, z.B., von wem, an wen, welcher Nachrichtentext zu versenden ist. Wenn nichts mehr zu tun ist, dann wartest Du über ein WaitAny auf die nächste Aufgabe oder den Abbruch der Schleife. Sobald sich ein Client meldet, trägst Du in die Wartschlange die nächste Aufgabe ein und informierst mit Set, dass das Warten in der Schleife zu beenden ist und wieder Aufgaben zur Verarbeitung anliegen. Aufgaben können z.B. sein: Warten auf eine Anmeldung, Warten auf eine Nachricht, Versenden einer Nachricht.--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks
Kommas richtig setzen!
Schüler sagen, Lehrer haben es gut.
Schüler, sagen Lehrer, haben es gut- Als Antwort markiert R3turnz Samstag, 17. Oktober 2015 20:13