libgadu 1.12.2

- Strona główna
- Dodatkowe strony
- Moduły
- Struktury Danych
- Pliki

Struktury danych | Wyliczenia | Funkcje
Połączenie z serwerem
Połączenie z serwerem

## Struktury danych
struct | gg_session
| Sesja Gadu-Gadu. Więcej...
struct | gg_login_params
| Parametry połączenia z serwerem Gadu-Gadu. Więcej...

## Wyliczenia
enum | gg_ssl_t { GG_SSL_DISABLED = 0, GG_SSL_ENABLED, GG_SSL_REQUIRED }
| Flaga połączenia szyfrowanego. Więcej...
enum | { GG_FEATURE_MSG77, GG_FEATURE_STATUS77, GG_FEATURE_DND_FFC, GG_FEATURE_IMAGE_DESCR }
| Flagi opcji protokołu. Więcej...

## Funkcje
struct gg_session * | gg_login (const struct gg_login_params *p)
| Łączy się z serwerem Gadu-Gadu. Więcej...
int | gg_ping (struct gg_session *sess)
| Wysyła do serwera pakiet utrzymania połączenia. Więcej...
void | gg_logoff (struct gg_session *sess)
| Kończy połączenie z serwerem. Więcej...
void | gg_free_session (struct gg_session *sess)
| Zwalnia zasoby używane przez połączenie z serwerem. Więcej...
int | gg_multilogon_disconnect (struct gg_session *gs, gg_multilogon_id_t conn_id)
| Rozłącza inną sesję multilogowania. Więcej...

## Opis szczegółowy

Każde połączenie z serwerem jest rozpoczynane funkcją `gg_login()` zwracającą strukturę `gg_session`, opisującą dane połączenie. Funkcja `gg_login()` za parametr przyjmuje wskaźnik strukturę zawierającą listę parametrów połączenia. Przykładowy kod rozpoczynający łączenie wygląda następująco:

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";
parametry.async = 1;
parametry.status = GG_STATUS_INVISIBLE;
sesja = gg_login(&parametry);
if (!sesja) {
błąd("Nie można się połączyć");
exit(1);
}
// ...

Lista wszystkich parametrów połączenia znajduje się w opisie struktury `gg_login_params`. W zależności od tego, czy łączymy się synchronicznie czy asynchronicznie (jak w przykładzie), funkcja `gg_login()` zwróci wskaźnik dopiero po udanym połączeniu lub zaraz po rozpoczęciu procedury łączenia. Dokładny opis dalszej obsługi połączenia znajduje się w sekcji poświęconej obsłudze zdarzeń.

Nowe statusy (nie przeszkadzać, poGGadaj ze mną), opisy graficzne i wiadomości kodowane UTF-8 będą dostępne dopiero po ustawieniu odpowiednich parametrów połączenia. Jest to niezbędne, ponieważ starsze klienty mogłyby nie działać prawidłowo, gdyby przy domyślnych parametrach połączenia zmieniło się zachowanie biblioteki.

parametry.encoding = GG_ENCODING_UTF8;
parametry.protocol_features = GG_FEATURE_DND_FFC | GG_FEATURE_IMAGE_DESCR;

Aby łączyć się z użyciem serwera pośredniczącego (ang. proxy), należy przed połączeniem ustawić zmienne globalne `gg_proxy_enabled` , `gg_proxy_host` , `gg_proxy_port` i inne.

Do korzystania z połączeń bezpośrednich wersji 6.x, konieczne jest przed połączeniem ustawienie zmiennych globalnych `gg_dcc_ip` i `gg_dcc_port`.

Począwszy od Gadu-Gadu 10 możliwe są połączenia szyfrowane. Aby je włączyć, należy ustawić pole `tls` struktury `gg_login_params:`

parametry.tls = GG_SSL_ENABLED;

W przypadku braku wkompilowanej obsługi SSL parametr ten zostanie zignorowany. By upewnić się, że połączenie nigdy nie będzie przeprowadzone bez szyfrowania, należy przypisać wartość `GG_SSL_REQUIRED` (patrz `gg_ssl_t`).

# Procedura łączenia z serwerem

Procedura łączenia się z serwerem składa się z kilku etapów:

1. Rozwiązywanie nazwy serwera rozdzielającego (ang. hub), domyślnie `appmsg.gadu-gadu.pl`
2. Nawiązanie połączenia z serwerem rozdzielającym na porcie 80.
3. Wysłanie zapytania o adres właściwego serwera. Parametrami zapytania są m.in. numer konta i wersja klienta.
4. Odebranie odpowiedzi zawierającej adres IP właściwego serwera, jego port i ewentualnie wiadomość systemową.
5. Nawiązanie połączenia z właściwym serwerem.
6. Odebranie pakietu z ziarnem hasła do przeprowadzenia autoryzacji typu challenge-response.
7. Wysłanie pakietu z parametrami logowania (w tym skrótem hasła).
8. Odebranie pakietu z informacją o pomyślnym lub nieudanym logowaniu.

Wszystkimi etapami zajmuje się funkcja `gg_login()` w przypadku połączenia synchronicznego lub `gg_login()` i `gg_watch_fd()` dla połączeń asynchronicznych. Możliwe jest pominięcie pierwszych czterech kroków, związanych z połączeniem z serwerem rozdzielającym, przez ręczne podanie adresu i portu właściwego serwera w polach `server_addr` i `server_port` struktury `gg_login_params`. Jest to przydatne w sytuacjach, gdy serwer rozdzielający jest przeciążony lub niedostępny, albo gdy zwraca nieprawidłowy adres właściwego serwera.

Rozwiązywanie nazwy w systemach zgodnych z normą POSIX jest operacją synchroniczną. Z tego powodu w trybie asynchronicznym konieczne jest utworzenie dodatkowego procesu lub wątku (w zależności od opcji kompilacji), który w tle dokona rozwiązania nazwy i zwróci wynik do procesu lub wątku nadrzędnego.

Nota
  Jeśli biblioteka używa procesu do rozwiązywania nazw, w aplikacji należy użyć funkcji systemowej `wait()` lub podobnej do prawidłowego zakończenia życia procesu potomnego. W przeciwnym wypadku, w zależności od zachowania systemu operacyjnego, mogą powstawać procesy zombie.

# Utrzymanie połączenia

Serwer oczekuje regularnego wysyłania pakietów utrzymania połączenia. W tym celu należy co minutę wywoływać funkcję `gg_ping()`.

# Zakończenie połączenia

Aby się wylogować, należy użyć funkcji `gg_logoff()`, a następnie zwolnić zasoby związane z sesją za pomocą funkcji `gg_free_session()`. Aby ustawić status z opisem, należy wcześniej wywołać funkcję `gg_change_status_descr()`.

# Multilogowanie

Około wersji Gadu-Gadu 10 pojawiła się możliwość łączenia kilku sesji jednocześnie. Aby włączyć tę funkcję należy do `gg_login_params.protocol_features` dodać `GG_FEATURE_MULTILOGON`. Domyślnie ta opcja jest wyłączona, więc zwykle będzie to wyglądać następująco:

parametry.protocol_features = GG_FEATURE_ALL | GG_FEATURE_MULTILOGON;

Po połączeniu z włączoną możliwością multilogowania, inne sesje nie zostaną rozłączone. W momencie połączenia dodatkowej sesji, aplikacja otrzyma zdarzenie `GG_EVENT_MULTILOGON_INFO` . Wiadomości przychodzące sąprzekazywane do wszystkich sesji, a wychodzące do rozmówców z jednej sesji do pozostałych za pomocą zdarzenia `GG_EVENT_MULTILOGON_MSG` . Aby zdalnie rozłączyć innąsesję, należy użyć funkcji `gg_multilogon_disconnect()`.

## Dokumentacja typów wyliczanych

enum gg_ssl_t

Flaga połączenia szyfrowanego.

Wartości wyliczeń
GG_SSL_DISABLED | Połączenie SSL wyłączone.
GG_SSL_ENABLED | Połączenie SSL włączone gdy dostępne. Błędny certyfikat serwera nie powoduje odrzucenia połączenia.
GG_SSL_REQUIRED | Połączenie SSL wymagane. Błędny certyfikat serwera powoduje odrzucenie połączenia.

anonymous enum

Flagi opcji protokołu.

Wartości wyliczeń
GG_FEATURE_MSG77 | Klient życzy sobie otrzymywać wiadomości zgodnie z protokołem 7.7.
GG_FEATURE_STATUS77 | Klient życzy sobie otrzymywać zmiany stanu zgodnie z protokołem 7.7.
GG_FEATURE_DND_FFC | Klient obsługuje statusy "nie przeszkadzać" i "poGGadaj ze mną".
GG_FEATURE_IMAGE_DESCR | Klient obsługuje opisy graficzne oraz flagę `GG_STATUS80_DESCR_MASK`.

## Dokumentacja funkcji

struct gg_session* gg_login | ( | const struct gg_login_params * | p | ) |

Łączy się z serwerem Gadu-Gadu.

Przy połączeniu synchronicznym funkcja zakończy działanie po nawiązaniu połączenia lub gdy wystąpi błąd. Po udanym połączeniu należy wywoływać funkcję `gg_watch_fd()`, która odbiera informacje od serwera i zwraca informacje o zdarzeniach.

Przy połączeniu asynchronicznym funkcja rozpocznie procedurę połączenia i zwróci zaalokowaną strukturę. Pole `fd` struktury `gg_session` zawiera deskryptor, który należy obserwować funkcją `select`, `poll` lub za pomocą mechanizmów użytej pętli zdarzeń (Glib, Qt itp.). Pole `check` jest maską bitową mówiącą, czy biblioteka chce być informowana o możliwości odczytu danych (`GG_CHECK_READ`) czy zapisu danych (`GG_CHECK_WRITE`). Po zaobserwowaniu zmian na deskryptorze należy wywołać funkcję `gg_watch_fd()`. Podczas korzystania z połączeń asynchronicznych, w trakcie połączenia może zostać stworzony dodatkowy proces rozwiązujący nazwę serwera – z tego powodu program musi poprawnie obsłużyć sygnał SIGCHLD.

Nota
  Po nawiązaniu połączenia z serwerem należy wysłać listę kontaktów za pomocą funkcji `gg_notify()` lub `gg_notify_ex()`.
  Funkcja zwróci błąd ENOSYS jeśli połączenie SSL było wymagane, ale obsługa SSL nie jest wkompilowana.

Parametry

  p | Struktura opisująca parametry połączenia. Wymagane pola: uin, password, async.

Zwraca
  Wskaźnik do zaalokowanej struktury sesji `gg_session` lub NULL w przypadku błędu.

int gg_ping | ( | struct gg_session * | sess | ) |

Wysyła do serwera pakiet utrzymania połączenia.

Klient powinien regularnie co minutę wysyłać pakiet utrzymania połączenia, inaczej serwer uzna, że klient stracił łączność z siecią i zerwie połączenie.

Parametry

  sess | Struktura sesji

Zwraca
  0 jeśli się powiodło, -1 w przypadku błędu

void gg_logoff | ( | struct gg_session * | sess | ) |

Kończy połączenie z serwerem.

Funkcja nie zwalnia zasobów, więc po jej wywołaniu należy użyć `gg_free_session()`. Jeśli chce się ustawić opis niedostępności, należy wcześniej wywołać funkcję `gg_change_status_descr()` lub `gg_change_status_descr_time()`.

Nota
  Jeśli w buforze nadawczym połączenia z serwerem znajdują się jeszcze dane (np. z powodu strat pakietów na łączu), prawdopodobnie zostaną one utracone przy zrywaniu połączenia. Aby mieć pewność, że opis statusu zostanie zachowany, należy ustawić stan `GG_STATUS_NOT_AVAIL_DESCR` za pomocą funkcji `gg_change_status_descr()` i poczekać na zdarzenie `GG_EVENT_DISCONNECT_ACK`.

Parametry

  sess | Struktura sesji

void gg_free_session | ( | struct gg_session * | sess | ) |

Zwalnia zasoby używane przez połączenie z serwerem.

Funkcję należy wywołać po zamknięciu połączenia z serwerem, by nie doprowadzić do wycieku zasobów systemowych.

Parametry

  sess | Struktura sesji

int gg_multilogon_disconnect | ( | struct gg_session * | gs,
|  | gg_multilogon_id_t | conn_id
| ) |  |

Rozłącza inną sesję multilogowania.

Parametry

  gs | Struktura sesji
  conn_id | Sesja do rozłączenia

Zwraca
  0 jeśli się powiodło, -1 w przypadku błędu