libgadu  1.12.2
All Struktury Danych Pliki Funkcje Zmienne Definicje typów Wyliczenia Wartości wyliczeń Definicje Grupay Strony
Struktury danych | Wyliczenia | Funkcje
Obsługa zdarzeń


Więcej...

Struktury danych

union  gg_event_union
 Unia wszystkich zdarzeń zwracanych przez funkcje gg_watch_fd(), gg_dcc_watch_fd() i gg_dcc7_watch_fd(). Więcej...
 
struct  gg_event
 Opis zdarzenia. Więcej...
 

Wyliczenia

enum  gg_check_t {
  GG_CHECK_NONE = 0,
  GG_CHECK_WRITE = 1,
  GG_CHECK_READ = 2
}
 Informacja o tym, czy biblioteka chce zapisywać i/lub czytać z deskryptora. Więcej...
 
enum  gg_event_t {
  GG_EVENT_NONE = 0,
  GG_EVENT_MSG,
  GG_EVENT_NOTIFY,
  GG_EVENT_NOTIFY_DESCR,
  GG_EVENT_STATUS,
  GG_EVENT_ACK,
  GG_EVENT_PONG,
  GG_EVENT_CONN_FAILED,
  GG_EVENT_CONN_SUCCESS,
  GG_EVENT_DISCONNECT,
  GG_EVENT_DCC_NEW,
  GG_EVENT_DCC_ERROR,
  GG_EVENT_DCC_DONE,
  GG_EVENT_DCC_CLIENT_ACCEPT,
  GG_EVENT_DCC_CALLBACK,
  GG_EVENT_DCC_NEED_FILE_INFO,
  GG_EVENT_DCC_NEED_FILE_ACK,
  GG_EVENT_DCC_NEED_VOICE_ACK,
  GG_EVENT_DCC_VOICE_DATA,
  GG_EVENT_PUBDIR50_SEARCH_REPLY,
  GG_EVENT_PUBDIR50_READ,
  GG_EVENT_PUBDIR50_WRITE,
  GG_EVENT_STATUS60,
  GG_EVENT_NOTIFY60,
  GG_EVENT_USERLIST,
  GG_EVENT_IMAGE_REQUEST,
  GG_EVENT_IMAGE_REPLY,
  GG_EVENT_DCC_ACK,
  GG_EVENT_DCC7_NEW,
  GG_EVENT_DCC7_ACCEPT,
  GG_EVENT_DCC7_REJECT,
  GG_EVENT_DCC7_CONNECTED,
  GG_EVENT_DCC7_ERROR,
  GG_EVENT_DCC7_DONE,
  GG_EVENT_DCC7_PENDING,
  GG_EVENT_XML_EVENT,
  GG_EVENT_DISCONNECT_ACK,
  GG_EVENT_TYPING_NOTIFICATION,
  GG_EVENT_USER_DATA,
  GG_EVENT_MULTILOGON_MSG,
  GG_EVENT_MULTILOGON_INFO,
  GG_EVENT_USERLIST100_VERSION,
  GG_EVENT_USERLIST100_REPLY,
  GG_EVENT_IMTOKEN,
  GG_EVENT_PONG110,
  GG_EVENT_JSON_EVENT,
  GG_EVENT_ACK110,
  GG_EVENT_CHAT_INFO,
  GG_EVENT_CHAT_INFO_GOT_ALL,
  GG_EVENT_CHAT_INFO_UPDATE,
  GG_EVENT_CHAT_CREATED,
  GG_EVENT_CHAT_INVITE_ACK
}
 Rodzaj zdarzenia. Więcej...
 

Funkcje

void gg_event_free (struct gg_event *e)
 Zwalnia pamięć zajmowaną przez informację o zdarzeniu. Więcej...
 
struct gg_eventgg_watch_fd (struct gg_session *sess)
 Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze sesji. Więcej...
 

Opis szczegółowy


Funkcje biblioteki zostały przygotowane w taki sposób, by móc z nich korzystać zarówno w trybie synchronicznym (działanie programu jest blokowane do zakończeniu operacji), jak i asynchroniczym (operacja jest rozpoczynana, a do czasu jej zakończenia program może robić inne rzeczy). Wyjątkiem są połączenia bezpośrednie, które pozwalają jedynie na połączenia asynchroniczne.

W trybie synchronicznym, po udanym zakończeniu funkcji gg_login(), należy w pętli wywoływać funkcję gg_watch_fd(), która po odebraniu informacji od serwera zwróci informację o zdarzeniu w strukturze gg_event lub NULL w przypadku błędu. Lista zdarzeń znajduje się poniżej.

Tryb asynchroniczny wymaga od programu obserwowania zmian na określonych deskryptorach za pomocą funkcji systemowych select() czy poll(), lub za pomocą mechanizmów pętli zdarzeń wbudowanych w wykorzystaną bibliotekę interfejsu użytkownika. Interesujące z punktu widzeniu połączenia asynchronicznego pola to fd określające obserwowany deskryptor, pole check będące maską bitową typu gg_check_t , mówiącą czy obserwowana ma być możliwość odczytu i/lub zapisu oraz timeout określające maksymalny czas wykonywania operacji. Gdy zaobserwuje się zmianę na deskryptorze należy wywołać funkcję gg_watch_fd() i postępować podobnie jak w trybie synchronicznym.

Nota
Po przekroczeniu czasu określonego w polu timeout, należy sprawdzić wartość flagi soft_timeout . Jeśli jest równa 0 (tj. FALSE), można przerwać połączenie i zwolnić zasoby, a jeśli jest różna (tj. TRUE), należy wywołać gg_watch_fd() ustawiając wcześniej timeout na 0, by dać szansę bibliotece zareagować na przekroczenie czasu operacji. Za pomocą mechanizmu soft_timeout są realizowane próby połączenia z innymi portami, np. gdy domyślny port 8074 jest zablokowany oraz zwrotne połączenia bezpośrednie (7.x), gdy jedna ze stron połączenia znajduje się za routerem NAT lub firewallem.
Po zerwaniu połączenia lub nieudanym logowaniu pole state przyjmuje wartość GG_STATE_IDLE. Przed dodaniem deskryptora fd do listy obserwowanych, warto w ten sposób sprawdzić, czy dane połączenie nie jest już nieaktywne.
Próba wysłania danych do zamkniętego połączenia (np. zerwanego przez serwer) w systemach uniksowych powoduje wysłanie sygnału SIGPIPE, który domyślnie powoduje unicestwienie procesu. Dlatego, aby pozwolić bibliotece zareagować na zerwanie połączenia w sensowny sposób, należy ignorować sygnał w aplikacji.

Przykład połączenia asynchronicznego

struct gg_session *sesja;
struct gg_login_params parametry;
struct gg_event *zdarzenie;
memset(&parametry, 0, sizeof(parametry));
parametry.uin = 12345;
parametry.password = "hasło";
sesja = gg_login(&parametry);
if (!sesja) {
błąd("Nie można się połączyć");
exit(1);
}
informacja("Połączono");
gg_send_message(sesja, 23456, "Cześć!");
while ((zdarzenie = gg_watch_fd(sesja))) {
switch (zdarzenie->type) {
// ...
}
gg_event_free(zdarzenie);
}
gg_logoff(sesja);
Nota
Przykład jest niekompletny, ponieważ powinien wysłać listę kontaktów i co minutę wywoływać funkcję gg_ping().

Przykład połączenia asynchronicznego

struct gg_session *sesja;
struct gg_login_params parametry;
struct timeval tv;
fd_set rd, wd;
int wynik;
memset(&parametry, 0, sizeof(parametry));
parametry.uin = 12345;
parametry.password = "hasło";
parametry.async = 1;
sesja = gg_login(&parametry);
if (!sesja) {
błąd("Nie można się połączyć");
exit(1);
}
for (;;) {
FD_ZERO(&rd);
FD_ZERO(&wd);
if ((sesja->check & GG_CHECK_READ))
FD_SET(sesja->fd, &rd);
if ((sesja->check & GG_CHECK_WRITE))
FD_SET(sesja->fd, &wd);
if (sesja->timeout) {
tv.tv_sec = sesja->timeout;
tv.tv_usec = 0;
}
wynik = select(sesja->fd + 1, &rd, &wd, NULL, (sesja->timeout) ? &tv : NULL);
if (!wynik) {
błąd("Przekroczono czas operacji");
exit(1);
}
if (wynik == -1) {
if (errno != EINTR) {
błąd("Błąd funkcji select()");
exit(1);
}
}
if (FD_ISSET(sesja->fd, &rd) || FD_ISSET(sesja->fd, &wd)) {
struct gg_event *zdarzenie;
zdarzenie = gg_watch_fd(sesja);
if (!zdarzenie) {
błąd("Połączenie przerwane");
exit(1);
}
switch (zdarzenie->type) {
informacja("Połączono");
break;
błąd("Nie można się połączyć");
gg_event_free(zdarzenie);
exit(1);
// ...
}
gg_event_free(zdarzenie);
}
}
Nota
Przykład jest niekompletny, ponieważ powinien wysłać listę kontaktów i co minutę wywoływać funkcję gg_ping().

Zdarzenia

Typ zdarzenia Pole gg_event Typ pola Opis
GG_EVENT_NONE - -

Zdarzenia związane z połączeniem
GG_EVENT_CONN_SUCCESS - -

GG_EVENT_CONN_FAILED event.failure gg_failure_t

GG_EVENT_PONG - -

GG_EVENT_DISCONNECT - -

GG_EVENT_DISCONNECT_ACK - -

Multilogowanie
GG_EVENT_MULTILOGON_INFO event.multilogon_info gg_event_multilogon_info

GG_EVENT_MULTILOGON_MSG event.multilogon_msg gg_event_msg

Wiadomości
GG_EVENT_XML_EVENT event.xml_event gg_event_xml_event

GG_EVENT_MSG event.msg gg_event_msg

GG_EVENT_ACK event.ack gg_event_ack

GG_EVENT_TYPING_NOTIFICATION event.typing_notification gg_event_typing_notification

GG_EVENT_IMAGE_REQUEST event.image_request gg_event_image_request

GG_EVENT_IMAGE_REPLY event.image_reply gg_event_image_reply

Lista kontaktów
GG_EVENT_NOTIFY event.notify[] gg_notify_reply

GG_EVENT_NOTIFY_DESCR event.notify_descr gg_event_notify_descr

GG_EVENT_STATUS event.status gg_event_status

GG_EVENT_NOTIFY60 event.notify60[] gg_event_notify60

GG_EVENT_STATUS60 event.status60 gg_event_status60

GG_EVENT_USERLIST event.userlist gg_event_userlist

GG_EVENT_USERLIST100_VERSION event.userlist100_version gg_event_userlist100_version

GG_EVENT_USERLIST100_REPLY event.userlist100_reply gg_event_userlist100_reply

Katalog publiczny
GG_EVENT_PUBDIR50_SEARCH_REPLY event.pubdir50 gg_pubdir50_t

GG_EVENT_PUBDIR50_READ event.pubdir50 gg_pubdir50_t

GG_EVENT_PUBDIR50_WRITE event.pubdir50 gg_pubdir50_t

Połączenia bezpośrednie
GG_EVENT_DCC7_NEW event.dcc7_new gg_dcc7

GG_EVENT_DCC7_ACCEPT event.dcc7_accept gg_event_dcc7_accept

GG_EVENT_DCC7_REJECT event.dcc7_reject gg_event_dcc7_reject

GG_EVENT_DCC7_PENDING event.dcc7_pending gg_event_dcc7_pending

GG_EVENT_DCC7_CONNECTED event.dcc7_connected gg_event_dcc7_connected

GG_EVENT_DCC7_DONE event.dcc7_connected gg_event_dcc7_connected

GG_EVENT_DCC7_ERROR event.dcc7_error gg_error_t

Dokumentacja typów wyliczanych

enum gg_check_t

Informacja o tym, czy biblioteka chce zapisywać i/lub czytać z deskryptora.

Maska bitowa.

Wartości wyliczeń
GG_CHECK_NONE 

Nie sprawdzaj niczego.

GG_CHECK_WRITE 

Sprawdź możliwość zapisu.

GG_CHECK_READ 

Sprawdź możliwość odczytu.

enum gg_event_t

Rodzaj zdarzenia.

Wartości wyliczeń
GG_EVENT_NONE 

Nie wydarzyło się nic wartego uwagi.

GG_EVENT_MSG 

Otrzymano wiadomość.

Przekazuje również wiadomości systemowe od numeru 0.

GG_EVENT_NOTIFY 

Informacja o statusach osób z listy kontaktów (przed 6.0).

Zdarzenie należy obsługiwać, jeśli planuje się używać protokołu w wersji starszej niż domyślna. Ostatni element tablicy zawiera uin równy 0, a pozostałe pola są niezainicjowane.

GG_EVENT_NOTIFY_DESCR 

Informacja o statusie opisowym osoby z listy kontaktów (przed 6.0).

Zdarzenie należy obsługiwać, jeśli planuje się używać protokołu w wersji starszej niż domyślna.

GG_EVENT_STATUS 

Zmiana statusu osoby z listy kontaktów (przed 6.0).

Zdarzenie należy obsługiwać, jeśli planuje się używać protokołu w wersji starszej niż domyślna.

GG_EVENT_ACK 

Potwierdzenie doręczenia wiadomości.

GG_EVENT_PONG 

Utrzymanie połączenia.

Obecnie serwer nie wysyła już do klienta ramek utrzymania połączenia, polega wyłącznie na wysyłaniu ramek przez klienta.

GG_EVENT_CONN_FAILED 

Nie udało się połączyć

GG_EVENT_CONN_SUCCESS 

Połączono z serwerem.

Pierwszą rzeczą, jaką należy zrobić jest wysłanie listy kontaktów.

GG_EVENT_DISCONNECT 

Serwer zrywa połączenie.

Zdarza się, gdy równolegle do serwera podłączy się druga sesja i trzeba zerwać połączenie z pierwszą.

GG_EVENT_DCC_NEW 

Nowe połączenie bezpośrednie (6.x)

GG_EVENT_DCC_ERROR 

Błąd połączenia bezpośredniego (6.x)

GG_EVENT_DCC_DONE 

Zakończono połączenie bezpośrednie (6.x)

GG_EVENT_DCC_CLIENT_ACCEPT 

Moment akceptacji klienta w połączeniu bezpośrednim (6.x)

GG_EVENT_DCC_CALLBACK 

Zwrotne połączenie bezpośrednie (6.x)

GG_EVENT_DCC_NEED_FILE_INFO 

Należy wypełnić file_info dla połączenia bezpośredniego (6.x)

GG_EVENT_DCC_NEED_FILE_ACK 

Czeka na potwierdzenie pliku w połączeniu bezpośrednim (6.x)

GG_EVENT_DCC_NEED_VOICE_ACK 

Czeka na potwierdzenie rozmowy w połączeniu bezpośrednim (6.x)

GG_EVENT_DCC_VOICE_DATA 

Dane bezpośredniego połączenia głosowego (6.x)

GG_EVENT_PUBDIR50_SEARCH_REPLY 

Odpowiedź katalogu publicznego.

GG_EVENT_PUBDIR50_READ 

Odczytano własne dane z katalogu publicznego.

GG_EVENT_PUBDIR50_WRITE 

Zmieniono własne dane w katalogu publicznym.

GG_EVENT_STATUS60 

Zmiana statusu osoby z listy kontaktów.

GG_EVENT_NOTIFY60 

Informacja o statusach osób z listy kontaktów.

Ostatni element tablicy zawiera uin równy 0, a pozostałe pola są niezainicjowane.

GG_EVENT_USERLIST 

Wynik importu lub eksportu listy kontaktów.

GG_EVENT_IMAGE_REQUEST 

Żądanie przesłania obrazka z wiadomości.

GG_EVENT_IMAGE_REPLY 

Przysłano obrazek z wiadomości.

GG_EVENT_DCC_ACK 

Potwierdzenie transmisji w połączeniu bezpośrednim (6.x)

GG_EVENT_DCC7_NEW 

Nowe połączenie bezpośrednie (7.x)

GG_EVENT_DCC7_ACCEPT 

Zaakceptowano połączenie bezpośrednie (7.x), nowy deskryptor.

GG_EVENT_DCC7_REJECT 

Odrzucono połączenie bezpośrednie (7.x)

GG_EVENT_DCC7_CONNECTED 

Zestawiono połączenie bezpośrednie (7.x), nowy deskryptor.

GG_EVENT_DCC7_ERROR 

Błąd połączenia bezpośredniego (7.x)

GG_EVENT_DCC7_DONE 

Zakończono połączenie bezpośrednie (7.x)

GG_EVENT_DCC7_PENDING 

Trwa próba połączenia bezpośredniego (7.x), nowy deskryptor.

GG_EVENT_XML_EVENT 

Otrzymano komunikat systemowy (7.7)

GG_EVENT_DISCONNECT_ACK 

Potwierdzenie zakończenia sesji.

Informuje o tym, że zmiana stanu na niedostępny z opisem dotarła do serwera i można zakończyć połączenie TCP.

GG_EVENT_TYPING_NOTIFICATION 

Powiadomienie o pisaniu.

GG_EVENT_USER_DATA 

Informacja o kontaktach.

GG_EVENT_MULTILOGON_MSG 

Wiadomość wysłana z innej sesji multilogowania.

GG_EVENT_MULTILOGON_INFO 

Informacja o innych sesjach multilogowania.

GG_EVENT_USERLIST100_VERSION 

Otrzymano numer wersji listy kontaktów na serwerze (10.0)

GG_EVENT_USERLIST100_REPLY 

Wynik importu lub eksportu listy kontaktów (10.0)

GG_EVENT_IMTOKEN 

Otrzymano ciąg IMTOKEN (11.0)

GG_EVENT_PONG110 

Utrzymanie połączenia (11.0).

Może służyć do synchronizacji czasu z serwerem.

GG_EVENT_JSON_EVENT 

Otrzymano komunikat systemowy (11.0)

GG_EVENT_ACK110 

Potwierdzenie wysłania wiadomości (11.0)

GG_EVENT_CHAT_INFO 

Otrzymano informację o konferencji (11.0).

GG_EVENT_CHAT_INFO_GOT_ALL 

Informacje o wszystkich konferencjach zostały już wysłane (11.0).

Otrzymywany po ostatnim pakiecie GG_EVENT_CHAT_INFO

GG_EVENT_CHAT_INFO_UPDATE 

Aktualizacja informacji o konferencji (11.0).

Dodanie, usunięcie jednego z uczestników.

GG_EVENT_CHAT_CREATED 

Potwierdzenie utworzenia konferencji (11.0)

GG_EVENT_CHAT_INVITE_ACK 

Potwierdzenie wysłania zaproszenia do konferencji (11.0)

Dokumentacja funkcji

void gg_event_free ( struct gg_event e)

Zwalnia pamięć zajmowaną przez informację o zdarzeniu.

Funkcję należy wywoływać za każdym razem gdy funkcja biblioteki zwróci strukturę gg_event.

Parametry
eStruktura zdarzenia
struct gg_event* gg_watch_fd ( struct gg_session sess)

Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze sesji.

Funkcja zwraca strukturę zdarzenia gg_event. Jeśli rodzaj zdarzenia to GG_EVENT_NONE, nie wydarzyło się jeszcze nic wartego odnotowania. Strukturę zdarzenia należy zwolnić funkcja gg_event_free().

Parametry
sessStruktura sesji
Zwraca
Struktura zdarzenia lub NULL jeśli wystąpił błąd