Skocz do zawartości

GMS Multi łączenie/rozłączanie


Rekomendowane odpowiedzi

Bawię się dalej tym przykładem i napotkałem pewien problem.

Gdy połączę klienta, a następnie go rozłączę, następnie znowu spróbuję podłączyć klienta, zawiesza mi się serwer.

Dziwne okazuje się, że z szybkiego debugowania wynika, iż coś źle usuwa gracza:

743adb7eacb9.png

Usuwa gracza o ID 0, gdy gracz ma ID 1!!!

Warto jeszcze dodać, że jeżeli żadnego z klientów nie rozłączę, to spokojnie mogę kilka podłączyć. Czyli sęk tkwi w rozłączaniu, a raczej w tych listach graczy, czy coś, ponieważ ja jeszcze nie rozkmniłem do końca jak to wszystko działa :D

Mój kod(praktycznie 1 do 1 z przykładu, lekko zmodyfikowany) newtowringu obiekru oSerwer, w apce serera:

GML
var eventid = ds_map_find_value(async_load, "id");

 

if( server == eventid )

{

var t = ds_map_find_value(async_load, "type"); //Typ polaczenia (połączył się/rozłączył się)

var sock = ds_map_find_value(async_load, "socket"); //Pobieramy jego sock

if( t==network_type_connect) //Jezeli ktos dolaczyl

{

ds_list_add( socketlist, sock ); //Dodajemy do listy

idd ++; //Dodajemy 1 do idd

ds_map_add( Clients, sock, idd ); //Dodajemy do mapy //idd - przypisujemy mu id

Console_Add_Msg("Nowy gracz("+string(sock)+")dolaczyl!", 4, -1);

 

Send_ID(1, idd);

 

}

else //Jeżeli się rozłączył

{

var inst = ds_map_find_value(Clients, sock ); //Znajdujemy tego gracza

var index = ds_list_find_index( socketlist, sock ); //Znajdujemy go w liscie

ds_map_delete(Clients, sock ); //Usuwamy go z mapy

ds_list_delete(socketlist,index); //I usuwamy

Console_Add_Msg("Usunięto gracza: "+string(index) , 4, -1);

}

}

else if( eventid!=0) //Jezeli nie rowna sie 0

{

var buff = ds_map_find_value(async_load, "buffer"); //Tworzymy buffer

var _idd = buffer_read(buff, buffer_u8 ); //No i odbieramy dane

var wiadomosc = buffer_read(buff, buffer_string ); //No i odbieramy dane

Console_Add_Msg(wiadomosc, 1, _idd, 3); //Wyświetlanie wiadomosc

//var sock = ds_map_find_value(async_load, "id"); //Przydatne do tego niżej

//var inst = ds_map_find_value(Clients, sock ); //Przydatne jeżeli chcemy określić od kogo to zostało wysłane

var t_buffer = buffer_create(256, buffer_grow, 1), _msg="";

 

 

}

Zauważyłem też, że jeżeli zmienię:

GML
var inst = ds_map_find_value(Clients, sock ); //Znajdujemy tego gracza

var index = ds_list_find_index( socketlist, sock ); //Znajdujemy go w liscie

ds_map_delete(Clients, sock ); //Usuwamy go z mapy

ds_list_delete(socketlist,index); //I usuwamy</span>

na:

GML
var inst = ds_map_find_value(Clients, sock ); //Znajdujemy tego gracza

var index = ds_list_find_index( socketlist, sock ); //Znajdujemy go w liscie

ds_map_delete(Clients, sock ); //Usuwamy go z mapy

ds_list_delete(socketlist,index-1); //I usuwamy</span>

to niby na krotką metę działa, ale jak łącze kilka klientów, a następnie je rołączam w innej kolejności niż je łączyłem to serwer siada.

Kiedy siada nie ma żadnych errorów od GMS, tylko, że aplikacja systemu windows przestała odpowiadać :/

 

Macie jakieś koncepcje?

Odnośnik do komentarza
Udostępnij na innych stronach

Jestem solidnie wcięty bo wracam z rozmowy kwalifikacyjnej, ale chyba widzę problem. Rozważmy te linijki:

GML
ds_list_add( socketlist, 1 ); //Przyjmujemy że sock=1, więc będę pisał 1

idd ++; //Rozumiem że było 0 więc teraz jest 1

ds_map_add( Clients, 1, 1 ); //wiemy ile ma idd więc będę wpisywał

//Wszystko dodało spoko

inst = ds_map_find_value(Clients, 1 ); //Dla podanego klucza (1) szuka wartości. Zwraca ją: inst=1

index = ds_list_find_index( socketlist, 1 ); //w liście szuka indexu przypisanego do danej wartości (1), ale wartość 1 jest dodana na pierwszym miejscu czyli ma index=0!

ds_map_delete(Clients, 1 ); //Usuwamy z mapy

ds_list_delete(socketlist,0); //I usuwamy źle!</span>

 

 

Problem masz z listami... chyba

Odnośnik do komentarza
Udostępnij na innych stronach

Sockety nie do konca dzialaja tak jak uwazasz.

 

Pierwszy podlaczony klient uzywa socket 0, drugi socket 1, trzeci socket 2.

Kiedy klient #2 sie rozlacza, socket 1 zostaje zwolniony.

 

Kiedy ktos nowy sie polaczy(klient #4), nie dostanie socketu 3 tylko wolny socket 1.

 

Aby poprawnie listowac ID uzytkownikow zapisuj do listy socket pobrany w evencie networking.

Wyglada to mniej-wiecej tak:

GML (quotNetworkingquot)
switch(ds_map_find_value(async_load,"type")) //Sprawdzenie rodzaju pakietu jaki przyszedl

/*

Istniejace rodzaje sa w dokumentacji i nazywaja sie:

network_type_disconnect ,

network_type_connect ,

network_type_data

*/

{

case network_type_connect: // To sie bedzie dziac gdy nowy uzytkownik sie laczy

ds_list_add(UserList,ds_map_find_value(async_load,"socket")); // Dodanie do listy uzytkownikow socketu uzywanego przez tego uzytkownika.

//Bierze sie to stad ze w ds_map'ie ze zmiennej async_load jest klucz "socket" ktory trzyma ID socketu uzywanego przez swiezo podlaczonego uzytkownika

// < Reszta rzeczy ktore sie dzieja >

break;

}

 

 

Edit: Socket jest rowniez podawany przy network_type_disconnect i mozesz go uzyc do usuniecia odpowiednich danych z listy uzytkownikow.

Odnośnik do komentarza
Udostępnij na innych stronach

Mówiąc najprostrzym językiem socket to połączenie między serwerem a klientem.

 

Kiedy chcesz wyslac dane do konkretnego uzytkownika, wysylasz dane przez jego socket.

 

Id które dostajesz w ds_map_find_value(async_load,"socket") to numer połączenia między serwerem a klientem.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...