Autor: nme · poniedziałek, 20 Luty, 2012 · Brak komentarzy · Tagi: django ·
W połowie roku 2011 na Uniwersytecie Śląskim w Katowicach zrodził się pomysł aby utworzyć własną telewizję internetową. Na jego czele stanął były redaktor naczelny studenckiego radia Egida. Trzy miesiące później naczelnemu udało się skompletować sprzęt potrzebny do rozkręcenia całego przedsięwzięcia, a w międzyczasie, ja stworzyłem dla nich całą platformę oraz aplikację webową (strumieniowanie w oparciu o open-source, silnik aplikacji webowej w Django).
Telewizja wystartowała na początku października i działa całkiem prężnie. Codziennie pojawiają się nowe materiały, a na Facebooku przybywają fani. Rosnący zespół nawiązuje współpracę z innymi jednostkami, m.in. Centrum Kształcenia na Odległość Uniwersytetu Śląskiego.
Ostatnio nieco ich zaniedbywałem, skupiając się jedynie na krytycznych poprawkach i absolutnie koniecznych usprawnieniach, ale jako, że serwis funkcjonuje całkiem sprawnie podjęliśmy decyzję o dalszej rozbudowie. Oto jedna z nich — umożliwienie osadzania bloku polecanych materiałów w innych serwisach
Przykład:
Kto wie, może niebawem zabiorę się za optymalizację podglądu 
Autor: nme · piątek, 29 Lipiec, 2011 · Brak komentarzy · Tagi: websocket, android ·
Kilka dni temu kolega śledząc moje eksperymenty z WebSocketami wspomniał o tym, że jako fallback dla przeglądarek nie wspierających natywnie WebSocketów można wykorzystać Flasha. Faktycznie — jak się okazało miałem nawet lokalnie sklonowane potrzebne repozytorium. Przez ten cały czas wgłębiania się w temat — zupełnie o nim zapomniałem. Efekty pracy autora zaskoczyły mnie bardzo pozytywnie.
Szczegóły
Aplikacja jest obecnie zgodna z Hybi-16.
Testowałem rozszerzone o Flashowy fallback demo opisane w poprzednim wpisie — nowa wersja dostępna jest tutaj. Wykonywałem testy zarówno dla ws:// jak i wss:// (TLS). Zarówno serwerowa implementacja, jak i web-socket-js pracują w oparciu o wersję protokołu WebSocket hixie-76. Fallback wymaga Adobe Flash 10+.
| System | Przeglądarka | WebSocket | Flash WebSocket |
| OS X Lion | Safari 5.1 | działa | - |
| Ubuntu 11.04 | Chrome / Chromium 12, 13, 14, 15, 16 | działa | - |
| Debian 6.0 | Firefox / Iceweasel 9 | działa | - |
| Ubuntu 11.04 | Firefox 5, 6 * | nie działa | działa |
| Ubuntu 11.04 | Opera 11.50 | nie działa | działa |
| Windows XP, SP3 | Internet Explorer 8 | nie działa | działa |
| Windows XP, SP2 | Internet Explorer 7 | nie działa | działa |
| Windows XP, SP1 | Internet Explorer 6 | nie działa | działa |
| Android 2.3.3 | Internet | nie działa | działa |
| Android 2.3.3 | Dolphin Browser HD 6.0 | nie działa | nie działa |
| Android 2.3.3 | Opera Mobile 11.1 | nie działa | nie działa |
| Android 2.3.3 | Firefox for Android 6.0 | nie działa | nie działa |
* Firefox 6 wspiera nieaktualną wersję protokołu — Hybi-07
Notatki
Firefox 6 wspiera WebSockety, ale w wersji protokołu Hybi-07, a obiekt nazywa się tam MozWebSocket.
Internet Explorer 8 ma wbudowanego Flasha — rozwiązanie działa bez instalacji Flash Playera.
Firefox, Dolphin i Opera na Androida — z drugiej strony — nawet pomimo instalacji wtyczki — nie obsługują Flasha. Szczerze powiedziawszy to nie wiem dla kogo ten problem jest większy — dla mnie, czy dla zespołów rozwijających te przeglądarki...
Z tego co wyczytałem Internet Explorer w wersji 6 może nie działać. Ale jak się okazuje — działa (być może dlatego, że pracujemy na domyślnym porcie — 80). Aktywność projektu web-socket-js jest zadowalająca — kilka problemów jest rozwiązywanych, np. Opera nie specjalnie radzi sobie z połączeniami nawiązanymi przez dłuższy czas.
Osobiście bardzo cieszy mnie fakt, że łącznie z domyślnym Androidowym Browserem — we wszystkich ważnych przeglądarkach — WebSockety działają! 
Wspomnę na koniec, że web-socket-js ma już gotowy branch dostosowany pod nowszy draft — wersję protokołu hybi-07 — stanie się on domyślnym kiedy Chrome przejdzie na nowszą wersję.
Autor: nme · piątek, 15 Lipiec, 2011 · Brak komentarzy · Tagi: django, twisted, websocket ·
W poprzednim wpisie przedstawiłem architekturę server-side której obecnie używam oraz obiecałem zaprezentować przykładową aplikację Twisted która jej używa i jednocześnie:
- komunikuje się z klientem z użyciem WebSocketów
- łączy się do bazy za pośrednictwem
Django ORM
Proste demo dostępne jest tutaj (zgodne z hixie-76 oraz hybi-10). Polecam otworzenie go w przeglądarce Google Chrome oraz jednocześnie — w oknie incognito — aby przetestować komunikację między nimi.
Kod aplikacji Twisted wygląda następująco:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from twisted.application import service
from worker import Client, WorkerService, Django
import sys,setproctitle
class testclient (Client):
def onOpen (self,reconnect=False):
if reconnect:
print 'Client '+self.ident+' reconnected'
else:
print 'Client '+self.ident+' connected'
def onClose (self):
print 'Client '+self.ident+' disconnected'
def onRecv (self, ident, mesg):
if mesg == 'die':
# send message to self
self.send ('ok')
# and die
self.kill()
elif mesg == 'hello':
# send message to everyone including self
self.broadcast ('hi')
elif mesg == 'whoami':
if self.user:
self.send (self.user)
else:
self.send ('dunno')
else:
# send message to everyone else
self.unicast (mesg)
class demoapp (WorkerService):
def onStart(self):
print 'app has been started'
def onStop(self):
print 'app is being stopped'
def onTimer(self):
print '5 secs has been gone'
# setup
appname = 'demoapp.py'
Django.setdsm ('/srv/venv/blog')
application = service.Application (appname)
setproctitle.setproctitle (appname)
demoapp (testclient,terminate=False,onTimer=5).setServiceParent (application)
Kilka słów komentarza
from worker import Client, WorkerService, Django
worker to moja biblioteka dla aplikacji klienckich całej przedstawionej architektury. Składa się ze 150 linii kodu.
Użycie Django.setdsm z argumentem będącym scieżką do aplikacji Django umożliwia importowanie dowolnych bibliotek z tej konkretnej aplikacji.
Opcjonalny argument terminate=False w demoapp zapobiega rozłączanie klientów z frontendowego serwera, jeśli aplikacja jest wyłączana (lub restartowana). Po restarcie aplikacji "oczekujący klienci" są w do niej automatycznie łączeni (reconnect=True w onOpen).
onStart i onStop w klasie demoapp wywoływane są wiadomo kiedy, a dodatkowo można ustawić dowolną ilość timerów z dowolnymi nazwami i interwałami — przykładowo onTimer=5 spowoduje wywołanie funkcji onTimer klasy demoapp co 5 sekund.
Z poziomu obiektu klienta jest możliwy dostęp na parametrów sesji oraz użytkownika Django.
Do czego można to wykorzystać? Chociażby do czatów, live feedów czy do wyświetlania jakiegoś wykresu w czasie rzeczywistym.
Wszelkie opinie mile widziane!
Autor: nme · piątek, 15 Lipiec, 2011 · Komentarze: 2 · Tagi: django, twisted, websocket ·
Nigdy nie przypuszczałem, że pracowanie nad architekturą rozwiązań po stronie serwera sprawi mi tyle frajdy, a jednak
Pod koniec lutego zaprezentowałem tutaj demo czata (kto sobie przetestował ten miał szczęście — obecnie demo jest wyłączone) ponieważ odkrywałem technologię long polling. Na jej poznawanie jest teraz trochę za późno (o jakieś 5 lat), ale warto było dowiedzieć się ile problemów ona stwarza. Postanowiłem teraz wybiec trochę do przodu i zaimplementować sobie obsługę WebSocketów.
To że powstał ten wpis — oznacza to, że się udało. Moje rozwiązanie okazało się być całkiem fajne i praktyczne. Zamierzam zatem przedstawić ewolucję architektury server-side z której korzystam.
Początki
Ten blog to nie Wordpress — to aplikacja w Django. Na serwerze nie ma Apache'a, jest Nginx — fenomenalny serwer www. Kiedy uruchamiałem wszystko pod koniec grudnia 2010 roku, architektura wyglądała tak:

Stabilność i niesamowita wydajność przy niewielkim użyciu pamięci umożliwił nginx wraz z uwsgi serwującym aplikacje.
Ewolucja...
Aby mieć możliwość pracy z Comet musiałem wykorzystać Nginx Http Push Module. Byłem przy okazji ciekaw jak z tą techologią będzie współpracował haproxy. Ruch https został dodatkowo przepuszczony przez również zmodyfikowany stunnel (nałożona łata umożliwiająca http_x_forwarded_for). Po stronie aplikacji Django konieczne było dodanie własnego autorstwa middleware'a do obsługi http_x_forwared_for.
Long polling wymagał też lekkiego tuningu ustawień haproxy i serwera nginx.

Taka architektura ma jeszcze jeden niesamowicie praktyczny ficzer, który warto w tym momencie wymienić: jeśli jakaś aplikacja pracuje w trybie debugowania (w nginx zamiast uwsgi jako reverse proxy, a aplikacja jest uruchamiana komendą django-admin runserver), a zależy nam na prawdziwym adresie IP — dzięki middleware obsługującemu http_x_forwared_for nie będziemy widzieć 127.0.0.1 tylko prawdziwy adres IP. Było to dla mnie niezwykle przydatne podczas testowania uwierzytelniania oAuth.
Aplikacje działające na serwerze pracowały równie stabilnie i wydajnie, a całe rozwiązanie wymagało jednocześnie bardzo mało pamięci oraz umożliwiło bardziej elastyczne skanowanie.
Jako, że zamierzałem poznać bliżej WebSockety oraz postawiłem sobie za priorytet, aby działały one na tych samych adresach IP i portach (http i https) co sam serwer www (wykorzystanie http-alt jakoś nie wydaje mi się być właściwym rozwiązaniem). Z przeprowadzonych testów ustaliłem, że z już gotowych rozwiązań — taką funkcjonalność oferuje jedynie komercyjny Kaazing WebSocket Gateway.
Wykorzystanie komercyjnego serwera nie wchodziło w grę — bo przecież mogę sobie coś takiego samemu napisać. Konieczne było napisanie czegoś co stało by "od frontu", co byłoby świadome WebSocketów. Ponieważ haproxy niestety nie jest w stanie sobie z tym zadaniem na tą chwilę (i być może nigdy) poradzić — wymagana było wprowadzenie zmian. Najnowszy na tą chwilę draft WebSocketów — hixie 76 — uniemożliwia nawiązanie całego handshake'u przez serwer reverse-proxy. Należało zatem pójść o krok dalej.
Wykorzystanie Twisted
Konieczne było wykorzystanie serwera "event-driven".
Z pomocą przyszedł silnik Twisted oraz znaleziona na githubie biblioteka txWebSocket którą lekko poprawiłem. Tutaj zaczęła się prawdziwa frajda — zacząłem poznawać Twisted. Poszło szybko i sprawnie.
Zanim zabrałem się za WebSockety uruchomiłem reverse-proxy dla obecnych serwisów www (rozszerzając je o http_x_forwarded_for), skonfigurowałem sobie logowanie do poszczególnych facility, dodałem obsługę https i przygotowałem sobie skrypt startowy w oparciu o twistd.
Kiedy WebSockety zaczęły działać, zacząłem zastanawiać się w jaki sposób:
- umożliwić dalszą komunikację z klientami WebSocketów
- odseparować właściwe aplikacje od głównego serwera frontend'owego
Trochę poszukałem, poczytałem i znalazłem RabbitMQ — napisany w erlangu serwer implementujący protokół kolejkowania AMQP. To wystarczyło aby zamknąć krąg, który wygląda następująco:

Kod minimalistycznej aplikacji (wykorzystującej przygotowaną bibliotekę umożliwiającą komunikację z klientami za pośrednictwem WebSocketów poprzez serwer frontendowy) jest krótki i bardzo czytelny — przedstawię go w następnym wpisie. Na tą chwilę aplikacje Twisted pracują w trzeciej warstwie (połączeniowej). Aby pracowały w warstwie czwartej (sesji) wykorzystując cookie sessionid ustawiane przez Django będę musiał wprowadzić kilka drobnych modyfikacji — myślę, że jeden wieczór wystarczy
Aplikacje Twisted są również w stanie łączyć się do bazy za pośrednictwem Django ORM jeśli tylko jest zastosowany w nich model standalone (wystarczy z poziomu aplikacji ustawić odpowiednio DJANGO_SETTINGS_MODULE oraz odpowiednie ścieżki — bułka z masłem).
Nie sądziłem, że się tak stanie, a jednak — system który w połowie 2007 roku ujrzał światło dzienne doczekał się drugiego wdrożenia! Z tej okazji postanowiłem trochę powspominać i powiedzieć na jego temat kilka słów. Bedą też screeny 
Kiedy studiowałem — pamiętam, że do naszego administratora sieci w akademiku chodziło się z karteczką z adresem mac, aby się zarejestrować. Jako, że to była politechnika, akademik męski w zasadzie — było to do przełknięcia.
Niedługo potem przeniosłem się do Katowic, jako absolwent zamieszkałem w akademiku i nagle jakimś dziwnym zbiegiem okoliczności zacząłem "po godzinach" mojej podstawowej pracy administrować siecią na uniwersyteckim osiedlu akademickim — trzy domy studenckie, w 1/4 obcokrajowcy — było bardzo ciekawie
Studentki filologii i psychologii potrafiły przynieść na karteczce różne numerki, ale nie zawsze były to adresy mac
Widok zagubionego spojrzenia kiedy uparcie trwałem w stwierdzeniu, że bez adresu mac się nie obędzie — bezcenny 
Początki
Na kolanie powstał wtedy pierwszy system do zarządzania siecią — narzędzie commandline'ówe, co nóż poprawiane i wzbogacane o nowe "wyjątki", obsługę anomalii, możliwych problemów i inne konieczne poprawki. Był totalnie niewydajny — przepisałem go od nowa i wszystko zaczęło działać świetnie. Kiedy kształtowanie pasma również zaczęło działać jak należy — pomyślałem o frontendzie webowym oraz — o automatyzacji rejestracji studentów.
Pamiętam pewien upalny dzień, w środku lata, kiedy to siedziałem w domu, na L4 — załatwiłem się klimatyzacją w samochodzie — i pisałem ten portal
Dzięki między innymi temu — w semestr 2007/2008 osiedle akademickie weszło z nowym systemem rejestracji i obsługi problemów — automatycznie pobierającym adresy mac rejestrowanych stacji roboczych. Portal rejestracyjny był dwujęzyczny oraz jednocześnie zawierał takie rzeczy jak czat z administratorem, bazę wiedzy — najczęstszych problemów czy komunikaty z dostępnym kanałem rss. Jeśli temat graficzny komuś coś przypomina (zrzuty ekranu poniżej) — wzorowany na dawnym projekcie strony frameworka jQuery 
Od tamtego czasu...
Od tamtego czasu system działa bardzo sprawnie, doczekał się nawet rozbudowy o obsługę wifi (wstyd się przyznać — nie znałem wtedy radiusa i nie wiedziałem co to WPA2 Enterprise, nie wierzyłem i nadal nie wierzę w bezpieczeństwo szyfrowania WPA2 Personal — więc zrobiłem wifi w oparciu o OpenVPN'a), dodatkowe skrypty wykrywające pewne konkretne rodzaje problemów w sieci, automatyzację samonaprawiania się sieci, automatyzacji "rozmawiania" z zarządzalnymi switchami — słowem — wszystko co było potrzebne. System sam rozwiązywał problemy o których informował mnie smsami, a dodatkowo jeśli wymagał mojej reakcji — wysyłał mi smsy czy później — po prostu maile.
Bardzo fajnie się go używało — wszystko wyklikiwalne — prawie jak Farmorama
Uświadamiałem sobie, że przecież dużo jest takich ośrodków które nadal ręcznie rejestrują userów — stwierdziłem, że to strzał w dziesiątkę i może ktoś będzie chciał to kupić lub wdrożyć
Przygotowałem dokumentację... i wtedy nauczyłem się tego, że na marketingu totalnie się nie znam 
Żal mi tego systemu było — a jako że pojawiła się sposobność — pomogłem koledze który dopiero uruchamia sieć na osiedlu akademickim — w Cieszynie. Wdrożenie potrwało 4 dni z całkowitym dostosowania do potrzeb — oczywiście po godzinach. Ale warto zobaczyć jak własne dziecko działa
Szczególnie na znacznie nowszej platformie sprzętowej. Środowisko zostało zdeployowane jako maszyna wirtualna kvm i wydaje mi się, że "uciągnie" — póki co zachowuje się obiecująco
Tak btw. tutaj jest opis (również mój wpis, ale po angielsku) jednego ze świeżych narzędzi które użyłem — polecam).
Zanim jednak Cieszyn osiągnie liczby które mam na swoim podwórku (100Mbit/s), upłynie trochę czasu 
Tak poza tym — dodam, że, nie tak dawno bo jakieś pół roku temu powstała nowa wersja portalu, przepisana na Django, z dużą ilością JavaScriptowych fajerwerków. Na wdrożenie (a w zasadzie odpluskwianie na żywo w środowisku produkcyjnym) brakło mi chwilowo chęci. Grunt, że stary działa, a nowy czeka 
Swoją drogą — jestem ciekaw — jakiego systemu Ty / Twój administrator używa do zarządzania siecią? A może znasz się na marketingu i mnie czegoś nauczysz? 