Wakacje mają to do siebie, że w czasie ich trwania często się gdzieś wyjeżdża. Ja w planie wyjazdów miałem i mam kilka, do całości doszedł jeden, którego nie przewidziałem - na Kaszuby. W tym czasie miałem zapieprzać u brata, tworząc serwis, o którym stale piszemy. Oczywiście, by czasu nadto nie marnować wziąłem ze sobą laptopa, z nadzieją, że gdzieś w pobliskiej wiosce (bo w chwili gdy to piszę mieszkam na totalnym zadupiu, które nawet wioską nie jest) znajdzie się dostęp do Internetu. Oczywiście pisząc “wiosce” mam na myśli małe miasteczko turystyczne zwane Kartuzami (każdemu polecam odwiedzenie ww.), zatem spodziewać by się można w nim jakiejś kafejki internetowej, czegokolwiek. Oj, naiwniaku!
To znaczy - owszem, internet był, jednak w totalnie niedostępnej formie - w czytelni jakiejś gminnej biblioteki, na dodatek tylko jedno stanowisko komputerowe. Zdziwienia nie było, gdy się okazało, że jest zarezerwowane do końca dnia. Podjąłem zatem prostą decyzję - spróbuję przez WAPa. Poszedłem do Orange zorientować się, co muszę zrobić, żeby się “zaWAPać”. Instalacja miała być debilnie prosta, potrzebny był tylko port IrDA. Szybko udałem się do najbliższego komputerowego, zakupiłem potrzebny adapter pod USB i już przeżywałem radość, że nie będę się musiał uzależniać od innych ludzi. Wróciłem do miejsca tymczasowego pobytu, rozpakowałem co trzeba, powkładałem gdzie trzeba, komórkę połączyłem w prosty sposób z komputerem. I zaczęło się piekło. Nie będę tutaj przytaczać wszystkich szczegółów, bo notka nie miała być o tym, jednak gdy wreszcie udało mi się podłączyć do sieci (po rozmowach z BOK, ściągnięciu w salonie Orange odpowiednich sterowników itp.), okazało się, że przepustowość nie wystarcza. Policzywszy w głowie wyszło mi, że miałem przepustowość około 16 kbps. Nawet mejle się nie chciały ściągać…
Co to jednak ma do programowania? W mądrości swej skończonej ściągnąłem sobie zawczasu API do Ruby on Rails, dzięki czemu mogłem spokojnie programować nasz projekt, oczywiście wszystkie dotąd wymyślone ficzery. Była to jednak tylko jedynka naszego serwisu, więc do roboty nie było jakoś dużo. Przyzwyczajony jestem przy tym (może to złe przyzwyczajenie?), że gdy mam zaprogramować jakąś stronę, to najpierw muszę znać jej layout, dzięki temu znam podstawowe funkcjonalności i mogę spokojnie wszystko oprogramować. Pomysł był taki, że będę co 1-2 dni ściągał odpowiednie layouty i robił co trzeba, jednak jak można wywnioskować, z powodu braku internetu spalił on na panewce.
W akcie desperacji stwierdziłem, iż nie będę się aż tak strasznie opieprzał i chociaż opracuję odpowiednie zachowania aplikacji, które wiem, jak mają działać. Jedno, o którym konkretniej nie napiszę, bo będzie to pewne novum w polskiej sieci, nie zostało jeszcze do końca opracowane, bo zawiera wiele niuansów, które trzeba odpowiednio zaprogramować. Drugi ficzer to Pingback, który ma być dostępny do każdego tekstu. Przeczytałem zatem specyfikację tej technologii, wydała mi się całkiem prosta, jeszcze prostsza, gdy doczytałem w API, że Railsy udostępniają wiele przydatnych narzędzi do stworzenia WebServices. Pragnę przy tym zaznaczyć, iż jestem święcie przekonany, że Pingback do takowych należy, więc jeśli jest inaczej to proszę o życzliwe uświadomienie mnie o prawdzie. Zaczęła się kolejna droga przez mękę. Na początek wziąłem się za dość dogłębną lekturę API i wszelkich README z gemów actionwebservice. Programowałem przy tym po omacku jakieś serwisy, walcząc z maszyną, gdzie tylko się da. Początkowo myślałem, że uruchamiając ruby script/generate web_service skrypt wygeneruje mi jakieś API (choć przypuszczałem, że może to być równie dobrze jakiś model danych), oprócz tego klasę dziedziczącą po ActionWebService::Base. No i się pomyliłem. Skrypt owszem, wygenerował API, ale oprócz niego stworzył kontroler do obsług WS. Tego się nie spodziewałem. Stwierdziłem, że skoro tak jest, to widocznie ten kontroler jest również tym WS. Napisałem proste API dla metody ping, przy czym niepotrzebnie stworzyłem strukturę zawierającą parametry wywołania. Utworzyłem do tego scaffold do wywoływania procedur. Po tych wszystkich operacjach coś się wywołało, jednak z tego co kojarzę nie zdefiniowałem samej metody ping. Nie przeszkadzało to aplikacji, uruchomiła się, chyba nic nie zwróciła (nie pamiętam już niestety, tak mnie szlag trafiał). Potem dopisałem w kontrolerze odpowiednią metodę i już się wyświetlało w wynikach, to co miało (oczywiście mówię tylko o testach). Nie wiedziałem jednak, na jakiej zasadzie działają te WS, gdzie mogę uzyskać dostęp do odpowiedniego skryptu interpretującego moje polecenia w XML-RPC. Po długich poszukiwaniach odnalazłem, że jest to akcja api mojego kontrolera. Wchodząc na nią przy pomocy przeglądarki zobaczyć można informację o błędzie - wiadomo, wszakże wejścia na nią powinny być POSTami z zawartością w formie XML-RPC. W międzyczasie zdążyłem sobie wszystko zepsuć, nie wiedzieć co się dzieje, doprowadzić do ustawienia Pingbacku jako metody pingback.ping z dwoma parametrami: sourceURI i targetURI. Przy wysyłaniu danych przez scaffolda generuje się kod XML-RPC bez nazw parametrów i nie wiem, czy jest to zgodne ze specyfikacją. W każdym razie moja metoda na to wywołanie reaguje poprawnie i zwraca co ma. No ok, ale trzeba by się nauczyć łączenia z Pingbackiem bez użycia scaffold, a przy użyciu np. ActionWebService::Client::XmlRpc. Niby do używania bardzo prosta klasa, wystarczy zainicjować obiekt, nadać odpowiednie parametry, takie jak API, którego WS używa i adres skryptu odpowiedzialnego za komunikację. Nadałem odpowiednie wartości tym parametrom (m. in. prawidłowy adres do skryptu wywołującego odpowiednią procedurę) i… dupa! Skrypt przy poprawnym wywołaniu zawiesza się, zgłaszając potem jakieś niezrozumiałe błędy. By się upewnić, że scaffold mnie nie oszukuje, że WS naprawdę działa i istnieje napisałem krótki programik w Javie, który miał wysyłać odpowiednie nagłówki i wartości przez HTTP i wyrzucać na sterr zwrócone wartości. Pierwsze wywołanie, bez XML-RPC zwrociło mi błędy, które można normalnie przeczytać wywołując w przeglądarce akcję api. Gdy wysłałem dane XML-RPC akcja zwróciła mi… to co powinna! Hura, znaczy się, że WS działa. Ale czemu, do jasnej cholery, klient XML-RPC nie działa - tego nie wiem.
Jeszcze 10 minut temu się zastanawiałem, dlaczego autorzy ActionWebService nie stworzyli specjalnego komunikatu dla api, gdy próbujemy się do niego dostać w sposób nieodpowiedni. Dopiero teraz domyśliłem się, że mogę to zrobić ja, używając before_filter. I tak powoli uczę się stylu myślenia zgodnego z Ruby on Rails. Co jest w sumie dla mnie najbardziej ciekawe to to, jak szybko potrafię przechodzić ze stanu nienawiści destrukcyjnej do gloryfikacji Railsów. Nauka jednak boli.