kostenloser Webspace werbefrei: lima-city


c# Websockets -> An alle eine Nachricht senden

lima-cityForumProgrammiersprachenProgrammieren mit .NET & Mono

  1. Autor dieses Themas

    forceofkingdoms

    forceofkingdoms hat kostenlosen Webspace.

    Hallo zusammen

    Ich habe mit in c# einen Websocket-server gemacht, wo sich mehrere Benutzer über eine Website verbinden können.
    Wenn ich nun allen eine Nachricht schreiben möchte, z.B "User.1 ist dem Chat beigetreten", dann müsste ich doch alle Sockets in einer Liste speichern und ihnen dann diese Nachricht senden.

    Dies geht auch, aber sobald ich diejenigen, die ihre Verbindung trennen, aus der Liste entferne, bekomme ich Fehlermeldungen wie
    "Die Auflistung wurde geändert. Der Enumerationsvorgang kann möglicherweise nicht ausgeführt werden."

    "Eine Anforderung zum Senden oder Empfangen von Daten wurde verhindert, da der Socket in diese Richtung bereits durch einen vorangegangenen shutdown-Aufruf heruntergefahren worden war"

    oder auch das der Index außerhalb des Araberreiches ist.

    private static void RecieveDisconnect(IAsyncResult ar)
            {
                sockets.Remove((Socket)ar.AsyncState);
                sendMessageToSockets("Client disconnected!", sockets);
            }
    -------->
    sendMessageToSockets("Client connected!", sockets);
    
    -------->
            private static void preSendMessageToSocets(List<Socket> sockets, String msg)
            {
                sockets.ForEach(socket => sendMessageToSocket(socket, msg));
            }
    -------->
            public static void sendMessageToSocket(Socket s, String msg)
            {
                if ( s.Connected) {
                    s.BeginSend(getBytes(msg), 0, getBytes(msg).Length, SocketFlags.None, new                AsyncCallback(SendCallback), s);
                }
            }


    Dies geschieht nur wenn ich viele Verbindungen hintereinander schliesse!

    Gibt es da eine Lösung dies zu verhindern?

    Mfg
    foc

    Beitrag zuletzt geändert: 28.11.2015 20:29:44 von forceofkingdoms
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Moin,

    es kommt zu einer System.InvalidOperationException ("Die Auflistung wurde geändert. Der Enumerationsvorgang kann möglicherweise nicht ausgeführt werden."), wenn mal folgendes macht/versucht:

    List<string> list = new List<string>()
    {
        Guid.NewGuid().ToString(),
        Guid.NewGuid().ToString(),
    };
    
    foreach (var item in list)
    {
        list.Remove(item);
    }


    Dies ist nur ein Beispiel, aber zeigt es recht deutlich. Ich iteriere durch die Liste und versuche dabei ein Object davon zu entfernen. Damit verändert sich die Liste und die Iteration kann nicht an der richtigen Stelle fortgesetzt werden.

    Um dein Problem im Allgemeinen zu lösen, benötige ich mehr Code.

    MfG Trancer.

    Beitrag zuletzt geändert: 29.11.2015 14:12:31 von trancedrome
  4. Autor dieses Themas

    forceofkingdoms

    forceofkingdoms hat kostenlosen Webspace.

    trancedrome schrieb:
    es kommt zu einer System.InvalidOperationException ("Die Auflistung wurde geändert. Der Enumerationsvorgang kann möglicherweise nicht ausgeführt werden."), wenn mal folgendes macht/versucht:


    Ich dachte eben, da ich die Socketliste an die Funktion weiter gebe, dass es da keine Probleme gibt.
    sockets.Remove((Socket)ar.AsyncState);
    sendMessageToSockets("Client disconnected!", sockets);
    Also ich lösche zuerst das Socket aus der Liste und gebe es dann die Liste weiter.

    Ich hab den Code jetzt so angepasst das solche Fehlermeldungen nichtmehr oder nur vereinzelt kommen, hab den alten Code nicht mehr, kann daher auch nicht mehr so genau sagen wo der Fehler war.

    Hier mein jetziger (neuer) code:
    Codepaste URL
  5. Habe mir den Code ein wenig angeschaut und bisher ist alle i.o.

    Nachdem ausführen habe ich festgestellt, dass du bitte einen anderen Port nehmen solltest, irgendwas über 1024, weil bis dahin sind die ports "fest belegt".

    Außerdem habe ich festgestellt, dass bei der Funktion "ReceiveCallback" ein Text gesplittet wird und von diesem Array der Index 11 genutzt werden soll. Welchen Browser nimmst du, damit du bei dem Request den String in mehr als 11 Teile zerlegst oder wie sprichst du den Server an, damit du Index 11 nehmen kannst ? O.o

    FF sowie IE stellen nur 9 Teile zur Verfügung. Also, was macht der Client bzw. was macht der Server mit den Teilstring bzw. was wird erwartet? ;-)

    string keyRaw = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[11].Split(new string[] { " " }, StringSplitOptions.None)[1] + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

    Diese Zeile könnte noch Probleme machen.

    Beitrag zuletzt geändert: 30.11.2015 20:04:41 von trancedrome
  6. Autor dieses Themas

    forceofkingdoms

    forceofkingdoms hat kostenlosen Webspace.

    trancedrome schrieb:
    FF sowie IE stellen nur 9 Teile zur Verfügung. Also, was macht der Client bzw. was macht der Server mit den Teilstring bzw. was wird erwartet? ;-)

    string keyRaw = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[11].Split(new string[] { " " }, StringSplitOptions.None)[1] + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

    Diese Zeile könnte noch Probleme machen.


    Danke ;)

    Das hätte mir sicher noch Probleme gemacht ;)
    Hab den Port auch umgestellt... sollte hoffentlich keine Probleme mehr machen.. :thumb:
  7. Nochmal zum grund Problem:

    Du darfst Listen (IEnumerable etc ..) nicht verändern während du über sie interierst.

    Einfach ist es wenn du eine seperate Remove liste bei einem durclauf erstellst und danach alle aus der Initial liste löscht die in der removeListe sind ... etwa so:

    foreach (var item in storageList)
    {
        if(ShouldItemBeRemoved(item))
        {
             removeList.Add(item);
        }
    }
    
    Oder:
    
    removeList = storageList.Where(item => ShouldItemBeRemoved(item)).ToList();
    
    und dann eben raus hauen
    
    removeList.ForEach(storageList.Remove);


    Wobei du eben auch sehr eleganten code mit Linq bei sowas schreiben kannst (siehe nach dem "oder").

    Ps: der code ist nur ein so in etwa, ... also hab ihn direkt hier rien gehauen ohne ihn laufen zu lassne :)


    Beitrag zuletzt geändert: 19.1.2016 21:11:28 von mprev
  8. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!