[ROZWIĄZANE] Sockets - problem z lagami
SeeK
19.11.2013
Witam,
napisałem sobie ostatnio pewien skrypcik pobierający dane z pliku php, który to natomiast wykonuje główne czynności. Aczkolwiek zanim użyję funkcji sockets_send to sprawdzam, czy dany plik php wogóle istnieje. Tak na wszelki wypadek. Mój kod wygląda tak:
new error, socket socket = socket_open("xxx.pl", 80, SOCKET_TCP, error) if(socket < 1) { client_print(id,print_chat,"[%s] Nie mozna polaczyc sie z serwerem weryfikacyjnym. Sprobuj ponownie pozniej.",PREFIX) return } else { new sData[256] format(sData, charsmax(sData),"GET /serwery_teksty/weryfikuj2.php HTTP/1.0^r^n") format(sData, charsmax(sData), "%sHost: xxx.pl^r^n^r^n", sData) socket_send(socket, sData, strlen(sData)) new sBuffer[40] socket_recv(socket, sBuffer, charsmax(sBuffer)) if(containi(sBuffer,"404 Not Found") != -1) { client_print(id,print_chat,"[%s] Nie mozna znalezc pliku weryfikacyjnego. Zglos nam ten blad: %s",PREFIX,kontakt) return } } [...]
GwynBleidD
19.11.2013
Pytanie oczywiste: dlaczego mam laga, gdy używam socketów. Zastanów się dlaczego są lagi, gdy używa się MySQL bez ThreadQuery, tu odpowiedź jest taka sama
Jednak tu nie mamy czegoś takiego, jak ThreadQuery i trzeba radzić sobie inaczej...
Jest natomiast funkcja socket_change, która tylko sprawdza, czy coś nowego nie przyszło, więc robimy tak: ustawiamy sobie socket_open i socket_send w jednej funkcji, a zamiast socket_recv ustawiamy taska. W tasku wywołujemy socket_change, jeśli zwróci, że nic nie przyszło, odpalamy następnego taska, jeśli przyszło, socket_read i robimy co sobie tam chcemy z tym, co przyjdzie albo wysyłamy coś nowego, albo czekamy na następne dane... To już od Ciebie zależy.
Zamiast taków można wrzucić to w jakiegoś thinka, server_frame czy inne często wykonujące się funkcje, jednak server_frame będzie do tego zdecydowanie zbyt często się wykonywał. Task natomiast ciut zbyt rzadko
SeeK
20.11.2013
Wracając do tematu. GwynBleid dzięki wielkie za podpowiedź, przetestuje, czy to wyeliminuje błąd
sebul
20.11.2013
(...)
set_task(0.6, "handleCheckData", TASK_ZG, data, 1, "b");
set_task(10.0, "handleEnd", TASK_ZG2, data, 1);
(...)
public handleEnd(data[1]) {
remove_task(TASK_ZG);
socket_close(g_socket);
g_socket = 0;
// jakieś info o niepowodzeniu
}
public handleCheckData(data[1]) {
if(!socket_change(g_socket)) {
return;
}
remove_task(TASK_ZG);
remove_task(TASK_ZG2);
new szData[256];
socket_recv(g_socket, szData, 255);
socket_close(g_socket);
g_socket = 0;
// operacje na tym co zostało zwrócone
}
A co do tego else co masz w kodzie, to jest one nie potrzebne, skoro w warunku masz return.
DarkGL
20.11.2013
Czyli dlaczego mam lagi.
Ponieważ w ten sposób urzyte sockety są synchroniczne czyli serwere czeka aż przyjdą dane nie wykonując żadnego innego kodu więc tak naprawdę nie są to lagi tylko proces "wisi" w jednym miejscu
GwynBleidD
20.11.2013
co do błędu z:
kodemNigdy nie miałem z tym problemów... Może pozwolisz, abym używając TeamViewera zobaczył na czym dokładnie polega ten błąd, może uda się go wtedy rozwiązać.
SeeK
21.11.2013
GwynBleidD nie ma sprawy, napisz na PW, to możemy ustalić "meeting" ;]
Czyli dlaczego mam lagi.
Ponieważ w ten sposób urzyte sockety są synchroniczne czyli serwere czeka aż przyjdą dane nie wykonując żadnego innego kodu więc tak naprawdę nie są to lagi tylko proces "wisi" w jednym miejscu
Zadałem złe pytanie. Wiem dlaczego mam lagi. Pytanie miało brzmieć, jak się ich pozbyć, jak stworzyć nowy wątek w którym serwer będzie oczekiwał na odpowiedź Btw. użyte przez 'ż' się pisze ;]
Co do else, to wiem, że jest niepotrzebny, ale nie robi on tam krzywdy, a dla mnie kod jest wtedy bardziej czytelny
---------------
Mam jeszcze jedno pytanie, jak przekazywać uchwyt do połączenia pomiędzy funkcjami? Zadeklarować go globalnie czy poprzez tablice w tasku?
Użytkownik SeeK edytował ten post 21.11.2013 21:53
GwynBleidD
23.11.2013
Tablica w tasku, oczywiście! Po co zaśmiecać kod zmiennymi globalnymi? Jeśli masz możliwość przekazania przez taką tablicę czegoś, zawsze to wykorzystuj... gdy powstanie Ci kilka połączeń na raz będziesz budował tablicę globalną na to wszystko?
sebul
24.11.2013
Ten temat został zamknięty przez moderatora.
Powód: Pomoc udzielona
Jeśli się z tym nie zgadzasz, raportuj ten post, a moderator lub administrator rozpatrzy go ponownie.
Z pozdrowieniami,
Zespół AMXX.PL