Szybsze PHP–wydanie PHP 5.4

Nareszcie, 2 lata oczekiwania ale stało się. Wersja PHP oznaczona numerami 5.4 wprowadziła całkiem miły element języka jakim są traits czy też nowy sprytny sposób zapisywania tablic ($array = [1 ,3 ,5] zamiast starego $array = array(1, 3, 5) ), ale nie o tym chciałem pisać. Według wielu testów przeprowadzanych przez niezależnych programistów oraz twórców języka interpreter został pozbawiony wielu zbędnych, starych i obciążających elementów oraz kod leżący u jego podstaw został gruntownie zoptymalizowany. Dzięki temu szacuje się wzrost wydajności parsowania PHP o ok 40% (rachunki wstępne).

Wydarzenie to bardzo pozytywnie nastawia na przyszłość tej technologii, która zaczęła tracić przy jej “konkurentach” – ASP.NET czy JSF. Czekamy na dalsze optymalizacje (i sam w głębi duchu błagam o lepszą kontrolę typów danych w programowaniu obiektowym – choćby typ zwracany przez funkcję…).

Krótko podsumowując – PHP FTW!

[JAVA] Struktura Serwer-Klienci z obustronną komunikacją on demand(…) część 2–implementacja serwera

Spora przerwa podczas pisania bloga była spowodowana nawałem pracy (sporo projektów do ukończenia), nauki (matura…) i hobby (Day of Riot). W ferie udało mi się znaleźć odrobinę czasu aby ukończyć ten rozgrzebany poradnik w sposób (dla mnie) zadowalający.

Od czego zacząć

 

W poprzednim poście napisałem jak projektowo będzie wyglądać nasz serwer. Niestety, podczas tworzenia kodu nieco zmienił się także sam projekt, jednak główna idea działania pozostała niezmienna i testy pokazały, że jest to naprawdę solidnie zaprojektowany system (aczkolwiek jestem świadom że dużo jest w nim błędów).

Cały projekt (zalecam pracę w środowisku NetBeans) będzie można pobrać w całości poniżej, ja natomiast wymienię tutaj tylko kluczowe dla działania kawałki kodu.

Fundamenty

 

Cała implementacja serwera opiera się na jednej fundamentalnej klasie SocketDistributor, która zarządza komunikacją z klientami oraz przechowuje obiekty reprezentujące indywidualne połączenia z nimi.

Aby uruchomić nasłuchiwanie serwera wystarczy utworzyć obiekt tej klasy podając port jako parametr konstruktora (domyślny port to 6660 i w większości przypadków tak może pozostać). Przykładowy kod uruchamiania serwera z na porcie 6789:

SocketDistributor socketDistributor = new SocketDistributor(6789);

Kod ten jest asynchroniczny, zatem zaraz po utworzeniu obiektu serwer działa w tle jako osobny wątek.

Trochę o klasie SocketDistributor. Podczas tworzenia się obiektu klasa ta tworzy w tle wątek SocketDistributorThread, który obsługuje podłączających się klientów wywołując metodę addClient klasy SocketDistributor. Ta kluczowa funkcja wykonuje szereg istotnych operacji:

  • Tworzy obiekt klienta, którego reprezentuje omówiona niżej klasa ClientObject. Za proces tworzenia tego obiektu odpowiada statyczna metoda createClientObject klasy ClientFactory
ClientObject clientObject = ClientFactory.createClientObject(client);

 

  • Przypisuje obiektowi klienta metodę nasłuchującą dla przychodzących z klienta komunikatów. Odpowiada za to interfejs RecievedStringHandler który posiada metodę recievedString(String Text, ClientObject sender). W przykładowym kodzie obsłużyłem tę metodę wyświetlając przychodzący tekst na ekranie konsoli razem z ip wysyłającego klienta, jednak użytkownik może zaimplementować własną obsługę tej metody.

clientObject.setRecievedStringHandler(new RecievedStringHandler(){
      @Override
      public void recievedString(String Text, ClientObject sender) {
        System.out.println("Message recieved from client " + sender.getSocketAdress() + " : " + Text);
      }      
    });
  • Dodaje obiekt klienta do wewnętrznej tablicy (co pozwala na dalsze zarządzanie klientami).

Takie przygotowanie klasy SocketDistributor pozwala na bardzo łatwą obsługę nawet dużej ilości podłączonych klientów. Klasa ta zawiera do tego takie funkcje jak:

  • public ClientObject getClientByIP(String IP) – Zwraca obiekt klienta na podstawie podanego adresu ip. Na obiekcie takim można wykonać np. wysłanie komunikatu do klienta
  • public void SendToAll(String Message) – Wysyła komunikat (podany jako parametr) do wszystkich aktualnie podłączonych klientów
  • public void CloseAll() – Zakańcza wszystkie aktywne połączenia z klientami

Funkcje te to tylko przykład co można zrobić na liście podłączonych klientów. Każdy może zdefiniować sobie swoje własne metody, bazujące na potrzebach.

A co z klasą ClientObject?

 

No właśnie, działanie SocketDistributor ogranicza się do zarządzania inną kluczową klasą jaką jest ClientObject. Ma ona za zadanie obsługiwać strumienie przychodzące i wychodzące od/do klienta oraz przechowywać informacje na jego temat. Podobnie jak w klasie SocketDistributor konstruktor klasy ClientObject tworzy w tle wątek. Jednak zadaniem wątku ClientInputThread jest obsługa strumieni przychodzących od klienta. Działa to na bardzo prostej zasadzie nasłuchiwania na przyjście obiektu, odebrania go i wysłania odebranego tekstu do funkcji recievedString interfejsu RecievedStringHandler. Kod tej obsługi wygląda bardzo prosto:

@Override
  public void run() {
    try {
      String stream;
      while(true){
        stream = in.readObject().toString();
        if(stream.equals("CLOSECONNECTION")){
          new ClientCloseThread().start(clientObject);
          break;
        }
        clientObject.recievedFromClient(stream);
        if(clientObject.isEnd()) break;
      }
    } catch (IOException ex) {
      System.out.println("Wyjątek podczas obsługi strumieni przychodzących: " + ex.toString());
    } catch (ClassNotFoundException ex) {
      System.out.println("Wyjątek podczas obsługi strumieni przychodzących: " + ex.toString());
    }
  }

 

Nieskończona pętla oczekuje na obiekt wysłany przez klienta, następnie rzutuje go na typ String. Jeżeli wysłany został komunikat “CLOSECONNECTION” klient rozpoczyna zamykanie obiektu ClientObject. Tworzy w tym celu osobny wątek, co jest wymagane aby uniknąć zakleszczenia (kod wątku ClientCloseThread jest w pakiecie całości w załączniku). Jeśli komunikat jest inny niż zakańczający połączenie to wątek wysyła obsługę komunikatu przychodzącego z powrotem do obiektu ClientObject wywołując jego funkcję recievedFromClient(String Text). Następnie sprawdza czy klasa SocketDistributor nie ustawiła flagi końca połączenia.

Funkcja recievedFromClient Jedyne co robi to sprawdza czy został zaimplementowany interfejs RecievedStringHandler. Jeśli tak, to wywołuje jego funkcję recievedString.

Klasa ClientObject definiuje także kilka przydatnych funkcji:

  • public void closeConnection() – zamyka połączenie z danym klientem
  • public void sendToClient(String Text) – Wysyła komunikat (podany jako parametr) do klienta

Tutaj także pozostawiam wiele możliwości dla przyszłych implementacji w zależności od potrzeb programisty.

Podsumujmy

 

Jak widać system stworzony przeze mnie jest prosty i przejrzysty, a w 100% spełnia swoją funkcję komunikacji obustronnej. Zastosowań takiego systemu jest multum, od komunikatorów internetowych po skomplikowane systemy firmowe. Wszystko zależy od wyobraźni programisty.

Proszę was o wyrozumiałość jako iż jest to mój pierwszy poradnik tego typu. Proszę o zgłaszanie zauważonych błędów merytorycznych (oraz także projektowych – wciąż uczę się programowania zorientowanego obiektowo więc na pewno coś w tym projekcie da się zrobić lepiej :) ). Dzięki wam następny poradnik może być o wiele lepszy!

PS. Ostatnia część poradnika będzie przedstawiać implementacje bardzo prostego klienta do tego systemu, jednak zachęcam do próbowania napisania go samemu – w ramach ćwiczeń i zrozumienia działania tego projektu :)

Upgrade serwera

Kilka dni temu zdecydowałem się skorzystać z wyjątkowo atrakcyjnej oferty i kupić używany, aczkolwiek bardzo dobry serwer od HP: workstation x4000. Parametry tego serwera są nierówne. Dwa procesory Intel Core Xeon 2.4 GHz, każdy po 2 rdzenie daje poczucie niesamowitej mocy obliczeniowej. W zestawie dostałem także 1GB RAMu, jednak z samą pamięcią wiąże się problem. Mianowicie jest to bardzo stara pamięć RDRAM, znana też jako RIMM. Slotów na pamięć jest 8, w zestawie otrzymałem 4 kości po 256 MB ramu każda. Upgrade pamięci wiąże się z dużym kosztami, nowa kość 512 kosztuje ok 250 dolarów.

Co jednak bardziej mnie zmartwiło to łącze danych. Serwer jest przygotowany do obsługi dysków przez złącze ATA lub SCSI. W zestawie nie otrzymałem żadnego dysku a w domu jednym wolnym dyskiem był 1TB samsung. Nic to, zainwestowałem 20 zł w przejściówkę ATA –> SATA (BIOS pozytywnie mnie zaskoczył bezproblemowo obsługując terabajtowy dysk) i pomimo iż boli mnie zbędna utrata wydajności nic na to nie poradzę.

Bardzo pozytywnie wypadła obudowa. Duża, bardzo przestrzenna i dobrze zorganizowana. Jeden z procesorów jest mocno schowany, jednak nie uznaję tego jako wielki problem. Sloty na kości pamięci są na osobnej płytce, umieszczonej prostopadle do płyty głównej. Obudowa waży 8 kg i ma możliwość zamknięcia na kluczyk (blokada Biosu przed uruchomieniem oraz fizyczne zamknięcie obudowy, co uważam za naprawdę duży plus).

Zasilacz 500W, 4 duże wiatraki (generujące spory hałas, ale to niestety uroki silniejszych maszyn). Do tego jakiś stary CD-ROM oraz GeForce 4.

Z kartą graficzną wywiązał się pewien problem. Podczas próby instalacji Ubuntu bios nie był w stanie wyświetlić ekranu graficznego instalacji. Znalazłem w Internecie podobny problem, który rozwiązany został właśnie przez wymianę karty graficznej. Slot jest jednak AGP, więc nie powinno być problemów ze znalezieniem jakiejś taniej karty zastępczej. Po instalacji systemu zamieszczę info co do wydajności maszyny.

Bios zaskakuje szczegółowością. Mnogość opcji, łącznie z Remote PowerOn oraz innymi przydatnymi bajerami + dużo testów sprzętowych podczas uruchomienia serwera sprawia iż komputer uruchamia się od 5-8 minut, jednak po uruchomieniu nie ma możliwości aby coś nie działało.

Innymi słowy, każdemu kto ma okazję kupić taki sprzęt – z całego serca polecam.

[JAVA] Struktura Serwer–Klienci z obustronną komunikacją on-demand w javie część 1

Jak wcześniej obiecałem opublikuję na blogu serię tutoriali dotyczących komunikacji sieciowej w strukturze Serwer – Klienci (szczegóły w poprzednim poście). Zacznę od mojego ulubionego języka silnie typowanego (przynajmniej jeśli chodzi o rozwiązania sieciowe) – JAVY. Wszystkie umieszczone przykłady zostały skompilowane w JDK wersji 1.6.0_25 oraz uruchomione w Java SE wersji 1.7.0_1.


Zacznę od opisu działania kodu.

Serwer – posiadać będzie (poza wątkiem głównym) jeden wątek przyjmujący i sortujący połączenia z klientami, nieskończenie wiele wątków przypisanych połączeniu z klientem (obiekt klienta o którym zaraz napiszę będzie obsługiwał po 2 wątki – jeden obsługujący strumienie przychodzące, a drugi, tworzony przez obiekt klienta dynamicznie, obsługujący strumienie wychodzące). Jako że w rozwiązaniach serwerowych bardzo ważna jest wydajność nie będę wprowadzać dodatkowych wątków a sama aplikacja będzie konsolowa. Ilość wątków: 1 główny, 1 porządkujący, po 2 x liczba klientów. Obsługa klientów będzie opierała na klasie Klient, posiadającej pola danych pozwalające na identyfikację i obsługę klientów, obsługę wątków wychodzących i przychodzących, kontrolę wątków nasłuchujących oraz posiadających metody pozwalające serwerowi na wysyłanie żądań do konkretnych klientów.

Klient – prosta aplikacja graficzna, która poza wątkami GUI będzie posiadała dodatkowe 2 wątki: jeden obsługujący strumienie przychodzące (stale nasłuchujący) oraz drugi (tworzony dynamicznie) obsługujący strumienie wychodzące.

Ważna sprawą jest rozwiązanie struktury żądań sieciowych. Wszystko tutaj zależy od preferencji programisty oraz zastosowań tej struktury. Ja wykorzystam najłatwiejszy sposób, czyli komunikacja obustronna przez polecenia zbierane (czyli jedna linia wychodząca z socketa = jedno pełne polecenie sieciowe, zawierające wszystkie niezbędne informacje). Zależnie od zastosowań można rozwiązanie to przerobić np na dialogi (np serwer ftp), jednak nie będzie to tematem niniejszego tutoriala.

Dodam jeszcze że podczas tworzenia aplikacji korzystam z IDE NetBeans, które polecam każdemu programiście JAVY (i PHP ;)).


Część pierwszą artykułu zakończę mapą myśli przedstawiającą zasadę działania serwera. Możliwe że ktoś będzie chciał zaimplementować to samemu (mam nadzieję że mapa myśli jest przejrzysta).

servermap

Struktura Serwer–Klienci z obustronną komunikacją on-demand

W dzisiejszych czasach wiele rozwiązań klient – serwer odpiera się na strukturze REST. Jest to związane z dynamicznym rozwojem tej struktury i jej szerokim zastosowaniem w Internecie (wszystkie strony internetowe opierają swoje działania właśnie na tej strukturze). Struktura ta opiera się na banalnym pomyśle. Komunikacja odbywa się na bazie krótkiego dialogu. Klient wysyła prośbę o dane na serwer, ewentualnie wysyła przy tym także swoje dane. Serwer w odpowiedzi zwraca mu swoje zasoby (np. w przypadku stron internetowych jest to kod html). Całość opiera się na tekście. Największą wadą tej struktury jest jednokierunkowe wywołanie. Zastanówmy się co moglibyśmy zrobić gdybyśmy chcieli wywołać funkcję u klienta wywołując ją od strony serwera? Oczywiście można zrobić po stronie klienta wywołanie serwera co określony czas, które pytałoby się serwera czego ten od klienta oczekuje, jednak takie rozwiązanie wymaga stałego obciążania aplikacji klienckiej i zbędnego ruchu w sieci (w przypadku kiedy serwer nie ma żadnych żądań dla klienta).

Rozwiązaniem takiego problemu są popularne ostatnio rozwiązania Cloud Computing, jednak na chwilę obecną “Przetwarzanie w chmurze” jest kosztowne. Jak zatem zrobić obustronną komunikację klient – serwer? Odpowiedzią na to są sockety. Jest to niższa warstwa programowania sieciowego. Każde rozwiązanie sieciowe przechodzi przez sockety. Jednak nie oznacza to wcale że programowanie socketów musi być ciężkie. Dodatkowo, wysyłanie danych przez sockety pozwala nam wysłać dane w dowolnej postaci, nie tylko tekst. Można wysłać Obiekt (zserializowany lub nie). Jedynym wymogiem są identyczne nagłówki tych danych po obu stronach.

W następnych artykułach opiszę rozwiązanie tego typu już pod kątem konkretnych języków. Na pewno pojawi się Java i Delphi. Następnie spróbuję to także przedstawić w C++ (na multiplaformowych bibliotekach QT).

BeKIC

Z dumą informuję iż w dniu dzisiejszym sprzedaż najnowszego produktu The First Path Technologies  o nazwie BeKIC ruszyła. Zainteresowane osoby mogą go nabyć na stronie aplikacji BeKIC.pl , lub zamówić u naszego oficjalnego wdrożyciela OEPD .

Cennik dla aplikacji umieszczony jest na stronie internetowej.

Dziękujemy wszystkim osobom zaangażowanym w projekt i zapraszamy do testowania (wersja TRIAL na 31 dni do pobrania na bekic.pl).

Więcej informacji o aplikacji BeKIC na stronie bekic.pl.

 

Jakub Syty

The First Path Technologies

 

PS. Po polskich szkołach będzie jeździł i prezentował projekt przedstawiciel handlowy firmy TFPTMateusz Matuszczyk. Można umówić wizytę pisząc na adres email naszej firmy TheFirstPath@TheFirstPath.com

Sukcesy dnia 15 Kwietnia 2011

Niniejszy post będzie bardzo zwięzły, gdyż ilość informacji do przekazania jest przytłaczająca.

Na początek chciałem poinformować o sukcesach firmy The First Path Technologies.

15 Kwietnia 2011 w Katowicach na Międzynarodowych Targach Innowacji Gospodarczych i Naukowych (INTARG)  2 pracowników firmy The First Path Technologies (Jakub Król oraz Jakub Syty) otrzymało tytuł “Młody Lider Innowacji Województwa Śląskiego w kategorii Programowanie” za program BeKIC (Program do zarządzania pracowniami komputerowymi – już niedługo w sprzedaży. Można pobrać wersję DEMO ze strony http://BeKIC.pl). Poniżej zdjęcia dyplomu oraz statuetki:

P1100879_mP1100880_m

Na drugim zdjęciu można zauważyć drugi dyplom, który otrzymała nasza firma. Jest to 2 miejsce w konkursie “Młody Lider Innowacji Województwa Śląskiego” tym razem w kategorii wynalazek. Dyplom ten otrzymaliśmy za projekt Your Computer Assistant – Future Computer o którym nie raz wspominałem na tym blogu.

Tego samego dnia zespół rockowy Day of Riot wystąpił na międzynarodowym konkursie Talenty Sobieskiego. Co prawda nie wygraliśmy żadnej nagrody, jednak zapewniliśmy sobie wielu szkolnych fanów i fanek oraz przyjaźń z czeskim zespołem Only For Life (serdecznie zapraszam was do posłuchania ich utworów na YouTube).

P1100881_m

Pod koniec chciałem przy okazji opisać moje stanowisko pracy. W związku z ostatnim przemeblowaniem (niedługo zmiany dobiegną końca) oraz wyruszeniem mojego prywatnego serwera (The First Path Tech. Test Server) ukształtowałem coś na kształt mojego idealnego stanowiska pracy. W dalszym ciągu brakuje mi nieco miejsca oraz wygodnego krzesła, jednak poniższe zdjęcie powinno obrazować moje upodobania.

P1100884_m

 

Na samym końcu zamieszczę połączone zdjęcie sukcesów oraz trofeów dnia 15 kwietnia:

P1100877_m

Pozdrawiam

Nekromancer

 

PS. Chciałem jeszcze dodać iż otrzymaliśmy bardzo wartościowe podarunki od Prezesa Firmy Novell, za które serdecznie dziękujemy!

P1100878_m

BeKIC wygrał!

Mam zaszczyt poinformować iż produkt Firmy The First Path Technologies – BeKIC (program do zarządzania pracowniami komputerowymi) zdobyła pierwsze miejsce na ogólnośląskim konkursie młodych wynalazców, dając nam tym samym tytuł “Młodych Liderów Innowacji Województwa Śląskiego – 2011 – w Kategorii programowanie” .

Myślę iż to wydarzenie pomoże nam rozpocząć sprzedaż tego produktu w najbliższym czasie i rozkręcić Firmę :).

Pozdrawiam

Nekromancer

The First Path Technologies

Mam zaszczyt poinformować iż dnia 1 marca 2011 firma The First Path Technologies rozpoczęła swoją działalność.

Zainteresowani mogą korzystać już z naszych usług, do czego gorąco zachęcamy. Myślę iż w najbliższym czasie wyruszy stronka firmy, do której oczywiście umieszczę adres.

Maile w sprawie zamówień można pisać pod adres:

Jakub.Syty@TheFirstPath.com

Pozdrawiam

Nekromancer

 

PS. Wszystkim kobietom wszystkiego najlepszego oczywiście :)

Brama Special Build 0.1.3

W dniu dzisiejszym wydałem wersję bramy, która oddaliła się od założeń rozwojowych, dlatego oznaczyłem ją jako Special Build. Oznacza to nie mniej nie więcej iż jest to wersja eksperymentalna, która nie dodaje funkcjonalności, jednak drastycznie zmienia działanie aktualnych funkcji.

W dzisiejszym przypadku padło na wydajność. Jak można było zauważyć we wcześniejszych wersjach wyświetlanie chatu było bardzo toporne. Okienko migało i zajmowało to bardzo dużo czasu. Była to wina niedopracowanego portu silnika html znanego z Firefoxa. Dzięki Amidamaru6669 znalazłem rozwiązanie na ten problem – mianowicie zmiana tego silnika na WebKit (znany z przeglądarki Google Chrome). Zastosowanie tego silnika oraz kilku poprawek wyświetlania chatu pozwoliło uzyskać niesamowitą stabilność wyświetlania chatu oraz szybkość większą o około 300%.

Enjoy! :)

Do pobrania jak zawsze pod linkiem:

http://bramabeta.4shared.com/

 

Zawsze do usług: Nekromancer