prosty komunikator c.d.

0

cześć jakiś czas temu pisałem kilka postów, które pomogły mi podczas początkowych problemów z prostym komunikatorem

tym razem jestem już prawie na końcu i zmagam się z jednym problemem cały dzień":

strona serwera otrzymuje informację o tym, aby wysłać innemu podłączonemu użytkownikowi jakąś wiadomość

if (otrzymano.Equals("^Wiadomosc^"))
            {
                string nadawca = null;
                string adresat = null;
                string wiadomosc = null;

                do
                {
                    otrzymano = binaryReader.ReadString();

                    if (otrzymano.Equals("^KoniecWiadomosc^"))
                    {
                        break;
                    }

                    nadawca = otrzymano;
                    otrzymano = binaryReader.ReadString();
                    adresat = otrzymano;
                    otrzymano = binaryReader.ReadString();
                    wiadomosc = otrzymano;                    
                }
                while (!otrzymano.Equals("^KoniecWiadomosc^"));

                serwer.WyslijWiadomoUzytkownikowi(nadawca, adresat, wiadomosc);
            }

po zdebugowaniu klient otrzymuje właściwe informacje i ma za zadanie stworzyć nowy obiekt klasy oknoDialogu (kolejny winform) oraz wyświetlić go wraz z otrzymaną wiadomością. obiekt ten tworzy się (pojawia), na górze w tytule okna pojawia sie nazwa użytkownika, który przesyła nam wiadomość, ale nie pokazuje zawartości wiadomości i wiesza się. po kilku sekundach w nawiasie pojawia sie "brak odpowiedzi" tylko w tym oknie. Okno główne komunikatora działa w tym czasie nadal

a tutaj co ma zrobić klient po otrzymaniu informacji ze strony serwera:

to jest osobna klasa polaczenie, w ktorej w odrębnym wątku uruchamiana jest metoda Komunikacja, która non stop słucha co przychodzi od strony serwera i "przetwarza" odpowiednio "rozpoznane" komendy

if (otrzymano.Equals("^Wiadomosc^"))
            {
                string nadawca = null;
                string wiadomosc = null;

                do
                {
                    otrzymano = binaryReader.ReadString();

                    if (otrzymano.Equals("^KoniecWiadomosc^"))
                    {
                        break;
                    }

                    nadawca = otrzymano;
                    otrzymano = binaryReader.ReadString();
                    wiadomosc = otrzymano;

                    if (klient.konwersacje.ContainsKey(nadawca))
                    {
                        klient.konwersacje[nadawca].DodajWiadomosc(wiadomosc);
                        klient.konwersacje[nadawca].Focus();
                    }
                    else
                    {
                        klient.stworzKonwersacje(nadawca, wiadomosc);
                    }
                }
                while (!otrzymano.Equals("^KoniecWiadomosc^"));                
            }

i metoda w głównej klasie klient.stworzKonwersacje:

public static void stworzKonwersacje(string nadawca, string wiadomosc)
        {
            oknoDialogu nowyDialog = new oknoDialogu();

            if (nowyDialog.InvokeRequired)
            {
                nowyDialog.BeginInvoke(new MethodInvoker(delegate() { stworzKonwersacje(nadawca, wiadomosc); }));
            }
            else
            {
                nowyDialog.Text = nadawca;
                konwersacje.Add(nowyDialog.Text, nowyDialog);
                nowyDialog.DodajWiadomosc(wiadomosc);
                nowyDialog.Visible = true;   
            }                                    
        }

konwersacje są trzymane w Dictionary o nazwie konwersacje, tylko po to by móc sprawdzać czy już taka konwersacja istnieje i jeśli tak do dopisywać nową wiadomość do istniejącego obiektu

debugowałem program wielokrotnie krok po kroku

pewnie wielu rzeczy nie napisałem i gdzieś zjadłem pisząc ten post, więc jeśli jakichś informacji brakuje to napiszę

załączam dwa zrzuty ekranu

z góry serdecznie dziękuję za jakąkolwiek pomoc

Maciek

0

szukam i na chwilę obecną znalazłem tylko to, że prawdopodobnie wytwarzam kontrolkę RichTextBox z innego wątku i dlatego całość może się sypać

gdy używam invoke wywala ten error

"Invoke or BeginInvoke cannot be called on a control until the window handle has been created."

pomóżcie proszę :)

0
public static void stworzKonwersacje(string nadawca, string wiadomosc)
        {
            oknoDialogu nowyDialog = new oknoDialogu();
 
            if (nowyDialog.InvokeRequired)
            {
                nowyDialog.BeginInvoke(new MethodInvoker(delegate() { stworzKonwersacje(nadawca, wiadomosc); }));
            }
            ....
       }

Tu jest problem byc moze, przy rekurencyjnym wywolaniu stworzKonwersacje. W delegacie w begininvoke powinny byc wszstkie instrukcje, ktore powinny zaktualizowac GUI. Nie spotkalem sie z taka praktyka jaka tutaj stosujesz. i dlaczego nowyDialog jest w zasiegu statycznej funkcji (a nie klasy)?

0

niestety nadal to samo, przy debugowaniu zauważyłem, że program pomija ten blok

if (nowyDialog.InvokeRequired)
{
      nowyDialog.BeginInvoke(new MethodInvoker(delegate() { stworzKonwersacje(nadawca, wiadomosc); }));
}

a jak przykładowo miałoby wyglądać tworzenie obiektu oknoDialogu z klasy ?

0
                string nadawca = null;
                string adresat = null;
                string wiadomosc = null;
 

To aż się prosi żeby zrobić nową klasę Wiadomość która zawiera powyższe pola i która ma np. konstruktor przyjmujący BinaryReadera, wtedy zamiast...

WyslijWiadomoUzytkownikowi(string, string, string)

... miałbyś jeden argument...

WyslijWiadomoUzytkownikowi(Wiadomość)

... tak naprawdę ciężko mi nawet przeczytać z czym masz problem, bo kod jest potężnie zagmatwany w pierwszym fragmencie masz pętle... Tylko po co Ci ta pętla? Odbierasz 5 wiadomości i 4 z nich wyrzucasz?

0

serdecznie dziękuję wszystkim za pomoc

zrobiłem jak polecaliście oraz znalazłem dodatkowo coś co mi o wiele uprościło sprawę

http://www.codeproject.com/Articles/429144/Simple-Instant-Messenger-with-SSL-Encryption-in-Cs

gdyby ktoś się zmagał z podobnym problemem

jeszcze raz dzięki wielkie

1 użytkowników online, w tym zalogowanych: 0, gości: 1