Both sides previous revision
Poprzednia wersja
Nowa wersja
|
Poprzednia wersja
|
pl:prolog:prolog_lab:prolog_lab_http [2009/05/06 09:17] gjn |
pl:prolog:prolog_lab:prolog_lab_http [2019/06/27 15:50] (aktualna) |
====== LAB: Integracja z HTTP/WWW ====== | ====== LAB: Integracja z HTTP/WWW ====== |
| |
Celem laboratorium jest ukazanie podstawowych metod integracji języka Prolog z protokołem HTTP i SSL oraz zademonstrowanie wielowątkowości w SWI-Prolog. | Celem laboratorium jest ukazanie podstawowych metod integracji języka Prolog z protokołem HTTP, używania gniazd TCP oraz zademonstrowanie wielowątkowości w SWI-Prolog. |
| |
===== -. Wątki ===== | ===== -. Wątki ===== |
* //tcp_connect(+Socket,+Host:+Port)// dokonuje połączenia z hostem na wskazanym porcie przy użyciu uprzednio zainicjowanego gniazda, | * //tcp_connect(+Socket,+Host:+Port)// dokonuje połączenia z hostem na wskazanym porcie przy użyciu uprzednio zainicjowanego gniazda, |
* //tcp_open_socket(+SocketId,-InStream,-OutStream)// otwiera dwa strumienie (wejścia i wyjścia) SWI-Prolog dla gniazda, | * //tcp_open_socket(+SocketId,-InStream,-OutStream)// otwiera dwa strumienie (wejścia i wyjścia) SWI-Prolog dla gniazda, |
| * //tcp_accept(+Socket,-Slave,-Peer)// działa po stronie serwera, oczekuje na połączenie ze strony klienta, tworzy nowe gniazdo dla klienta o identyfikatorze //Slave//, zmienna logiczna //Peer// jest unifikowana z adresem IP klienta. |
* //tcp_close_socket(+SocketId)// zamyka gniazdo. Ten sam efekt można uzyskać zamykając strumienie gniazda predykatem //close/1//. | * //tcp_close_socket(+SocketId)// zamyka gniazdo. Ten sam efekt można uzyskać zamykając strumienie gniazda predykatem //close/1//. |
| |
FIXME - ciąg dalszy. | **__UWAGA!__ W poniższych ćwiczeniach z użyciem gniazd TCP proszę używać portów z zakresu 33700-33999.** |
| |
| ==== Klient i serwer ==== |
| |
| **W tym ćwiczeniu proszę zmienić numer portu na dowolny z zakresu 33700-33999, aby nie przeszkadzać kolegom.** |
| |
| <code prolog> |
| :- use_module(library(socket)). |
| |
| create_client :- |
| tcp_socket(Socket), |
| tcp_connect(Socket,localhost:33888), |
| tcp_open_socket(Socket,Read,Write), |
| write(Write,'matka(kasia,robert).'),nl(Write), |
| close(Read), |
| close(Write). |
| |
| create_server :- |
| tcp_socket(Socket), |
| tcp_bind(Socket,33888), |
| tcp_listen(Socket,5), |
| tcp_open_socket(Socket,_,_), |
| |
| tcp_accept(Socket, Slave, _), % Akceptacja połaczenia ze strony klienta. |
| tcp_open_socket(Slave, In, Out), |
| read(In,Msg), % Odczyt wiadomości. |
| write(Msg), |
| close(In), |
| close(Out). |
| </code> |
| |
| * Predykat //create_client/0// tworzy obsługę gniazda TCP po stronie klienta, wysyła do serwera komunikat w postaci termu, a następnie zamyka połączenie. |
| * Predykat //create_server/0// dzieli się na dwie części. Pierwsza tworzy gniazdo, a druga obsługuję przychodzące połączenie. Predykat //tcp_accept/3// oczekuje do momentu nawiązania połączenia przez klienta. |
| |
| **Ćwiczenie:** |
| |
| Proszę wczytać powyższy program, uruchomić serwer w osobnym wątku (//thread_create/3//) i nawiązać z nim połączenie. |
| |
| Następnie proszę tak zmodyfikować predykat //create_server/0//, aby był w stanie obsłużyć więcej niż jedno połączenie (niekoniecznie symultanicznie, może być jedno po drugim) i przy każdym dopisywał przesłany term do bazy wiedzy (//assert/1//). |
| |
| ==== Komunikator ==== |
| |
| Program {{komunikator.pl|komunikator}} wykorzystuje gniazda TCP w celu stworzenia w Prologu prymitywnej wymiany wiadomości między użytkownikami. Proszę się z nim zapoznać Jest podzielony na część klienta i serwera. W rzeczywistości jest to rozbudowana wersja prostego programu z przykładu zamieszczonego wyżej. Dodana jest odpowiednia interpretacja komunikatów. Owe komunikaty są przesyłane w postaci termów, więc każdy musi być zakończony kropką. |
| |
| **Ćwiczenie:** |
| |
| Po zapoznaniu z programem proszę się porozumieć z kolegami wykonującymi to samo ćwiczenie. Niech jeden ze studentów uruchomi serwer komunikatora na ustalonym porcie przy użyciu predykatu //start_server/0//. Pozostali niech się z nim połączą przy użyciu predykatu //start_client/1//. Np. //start_client(ania)//. Proszę przetestować działanie komunikatora. |
| |
| Przykładowa sesja po stronie klienta może wyglądać następująco: |
| <code prolog> |
| 1 ?- start_client(ania). |
| |: Server message: Hello! I am a communication server |
| Server message: Type commands: |
| |: who. |
| |: Users connected to the server: |
| - ania |
| - bartek |
| |: msg(bartek,"Cześć Bartek!"). |
| |: Message from bartek: Cześć Aniu! |
| |: quit. |
| |: Connection closed by server. |
| </code> |
| |
===== -. HTTP ===== | ===== -. HTTP ===== |
| |
<code prolog> | <code prolog> |
:- use_module(library(http/http_open). | :- use_module(library(http/http_open)). |
| |
view_site :- | view_site :- |
| |
<code prolog> | <code prolog> |
:- use_module(library(http/http_open). | :- use_module(library(http/http_open)). |
| |
view_date :- | view_date :- |
write(Reply). | write(Reply). |
</code> | </code> |
| |
FIXME - ciąg dalszy | |
| |
==== Dla zainteresowanych ==== | ==== Dla zainteresowanych ==== |
| |
SWI-Prolog udostępnia także bibliotekę HTTP od strony serwera. Pełna dokumantacja znajduje się na stronie: [[http://www.swi-prolog.org/pldoc/package/http.html|SWI-Prolog HTTP support]]. | SWI-Prolog udostępnia także bibliotekę HTTP od strony serwera. Pełna dokumantacja znajduje się na stronie: [[http://www.swi-prolog.org/pldoc/package/http.html|SWI-Prolog HTTP support]]. |
| |
===== -. SSL ===== | |
| |
FIXME - ciąg dalszy | |
| |
====== Uwagi, komentarze, propozycje ====== | ====== Uwagi, komentarze, propozycje ====== |