Chat w jQuery - teoria

0

Witam ponownie,
na początku mam nadzieję, że moi ulubieńcy dołączą się do wypowiedzi, czyli unikalna_nazwa i dzek69 :)

Zacznę trochę od paplaniny, ale tutaj każdy skrawek wiedzy jest ważny. Chciałbym zadać pytanie, którym z pewnością się ośmieszę:
Czy są wątki w javascript/jQuery?

Na moje oko to są, ponieważ:
a) Mamy Ajax, który działanie niesynchronicznie co by wskazywało na wątek.
b) Patrząc na działanie niektórych funkcji np.: $.ajax - po wysłaniu zapytania na stronie można nadal coś robić czekając na odpowiedź.

Teraz wracając do tematu: Chciałbym napisać chat, ale nie jest trudnością wykonanie tego pod względem funkcjonalnym, ale pod względem obciążeniowym. Najważniejszym elementem jest odczytywanie wiadomości w czasie rzeczywistym co wymaga wątku, bo inaczej będzie blokowało działanie strony.

Jak dobrze rozumiem jQuery(document).ready(function(){}); czyli inaczej $(function(){}); jest wątkiem (niezależnym procesem)?
Jeżeli mam rację to znaczy, że mogę spokojnie napisać coś tego typu:

$(function(){
  var state = false;
  if(!state){
    state = true;
    $.ajax({
      dataType: "json",
      url: url,
      data: data,
      success: function(){
        state = false;
        // tutaj aktualizuję wiadomości
      }
    });
  } 
});

Oczywiście ten kod to zarys, mimo to wszelkie uwagi wskazane :)

0

Zanim zaczniesz wynajdywać koło od nowa poszukaj haseł:

  • "node.js chat"
  • "WebSocket chat"

Przykład:
http://net.tutsplus.com/tutorials/javascript-ajax/real-time-chat-with-nodejs-socket-io-and-expressjs/
http://www.andrewgreig.com/609/

Edit - jest gorzej niż myślałem - jest pierdylion rozwiązań dla jQuery:
http://www.jquery4u.com/widgets/10-crazy-jquery-chat-chat-box-plugins/
http://css-tricks.com/jquery-php-chat/
http://runnable.com/UXl9axZnE6ggAAMa/a-chat-example-using-codeigniter-and-jquery-php-php
http://www.jqueryscript.net/other/jQuery-Facebook-Like-Chat-Plugin-Pusher-Chat.html

Nawet komercyjne:
http://jquerychat.net/

Co do pytania:

  1. czy w JavaScript są wątki: nie, do HTML5 nie było. W HTML5 (właściwie równolegle do) masz Web Workers.

Jak to obejść bez HTML5:
http://www.sitepoint.com/multi-threading-javascript/

Coś o Web Workers:
http://www.html5rocks.com/en/tutorials/workers/basics/

  1. czy procesowanie asynchroniczne to wielowątkowość: nie
    Można przetwarzać asynchronicznie bez wątków. W takiej sytuacji gdy przetwarzasz dane zadanie reszta procesowania stoi.
0

a w temacie:
setTimeout(function(){ /* akcje */ }, 0); - powiedzmy ze tu treść funkcji będzie działać jako "wątek".

0

Muszę wyjaśnić kilka kwestii:
1. Zacznę od Pana poniatowski, który jeszcze przed skasowaniem postu mógł pomyśleć o tym co pisze. Nie traktuj mnie jak idioty bo w javie pisałem już nie raz podobne aplikacje. Dodatkowo nigdzie nie napisałem o tym jak będę się łączył, tylko o pobieraniu wiadomości.

2. Tutaj nie chodzi o wynalezienie koła - chat nie będzie publiczny lecz prywatny (wewnątrz firmy) i chcę przetrzymywać wszystko w bazie danych. Nie opowiadajcie mi o strukturach, ponieważ wiem jak ma być to zbudowane.

Porównując działanie websocketów z pierwotnym ajaxem wychodzi na to, że jest takie samo (tylko do innego zastosowania). Jak dla mnie każde działanie asynchroniczne jest objawem działania wątku. Mylę się?

Dla mnie najważniejsze jest to, żeby mieć pewność, że przy użyciu $.ajax() cały proces będzie zachodził poza działaniem reszty kodu (tak jak wątek)?
I jeszcze czy $(function(){...}) działa jak listener, czy jak pętla? Zdaje mi się, że jak listener...

Dodatkowo nie dostałem odpowiedzi na pytanie. Czy w JS istnieją wątki?

0

bo w javie pisałem już nie raz

Ale wciąż nie wiesz, ze Java to nie JavaScript (mają tyle wspólnego, co fragment nazwy)

I jeszcze czy $(function(){...}) działa jak listener

Tak.

Dodatkowo nie dostałem odpowiedzi na pytanie. Czy w JS istnieją wątki?

Nie do końca. Możesz stworzyć zapętlony "wątek" przez setInterval, albo pojedynczo przez setTimeout. Możesz ubić powtarzany "wątek" przez clearTimeout - ale nie przerwie to jego działania w środku, tylko się dokończy do pełnej pętli. // Mnie to wystarcza, Tobie też powinno.

A jak uruchomić część kodu, która będzie sobie pracować jako-tako niezależnie to pisałem w poprzednim poście.

0

Dobra dostałem odpowiedź w trakcie pisania postu.

Czytałem już o multi-threading i jeszcze jeden artykuł, oraz wiem o web workerach, ale dzięki wielkie za odpowiedź na najważniejsze pytanie. Co do gotowców to nie chcę korzystać bo to dobry moment na naukę.

Natomiast nie rozumiem w takim razie określenia asynchronicznie. Jeżeli jeden proces blokuje działanie drugiego, aż do zakończenia wykonywania samego siebie to jest to mylne ze znaczeniem słowa asymchroniczne (oczywiście nie mówię o tym jak sam procesor komputera to przetwarza).
Dodatkowo jak kiedyś dla sprawdzenia odpaliłem cięższy kod do przeanalizowania poprzez $.ajax() to mogłem normalnie działać na stronie - po zakończeniu zadania dodał nowe elementy do strony.

0

Tak, ajax działa asynchronicznie, inne rzeczy na stronie działają, a w międzyczasie przychodzi odpowiedź (najłatwiej to zasymulować php-owym sleep). Podobnie możesz zadziałać przez setTimeout.

dostałem odpowiedź w trakcie pisania postu.

Chodzi o moją odpowiedź? Jest różnica 42 minut między naszymi postami ;)

0

dzek69 - proszę nie utrudniaj mi odpisywania. Wiem, że Java i JS nie maja nic ze sobą wspólnego. Chodziło mi o zasadę działania (w javie pisałem to przy użyciu socketów i wątków, które czekały na odpowiedź), bo poniatowski pisze zanim przeczyta treść postu.

Chodziło o odpwiedź vpiotra

(połącz posty proszę)
I jeszcze jedno. Działanie setInterval() też mi wystarczy, po prostu sądziłem że używanie tego jest trochę przestarzałe... mój błąd.

Powiem, że utrudnieniem dla którego zadaję takie pytania jest to, że chcę by chat chodził niezależnie do strony. Nie będzie zakładki chat, tylko wysuwające się okno - trochę jak na fb.

0

Rozumiem. Co do przestarzałości setInterval - to integralna część javascriptu i raczej nigdy nie będzie przestarzała. Jedynie przestarzałe tutoriale sugerują wpychanie pierwszego argumentu jako string zawierający kod, który potem się przeliczy evalem - to jest bardzo brzydkie. Funkcja anonimowa, albo po prostu nazwa funkcji i będzie dobrze.

edit: Może czas zarejestrować konto na 4p? ;)

0

Muszę coś z tym zrobić bo miałem kiedyś konto, ale zapomniałem danych, a co gorsze było to po tym jak usunąłem mail na jaki go rejestrowałem... :D Przyzwyczaiłem się do takiego działania.

Kiedyś zarejestruję - obiecuję!

0

Funkcje $ajax/success oraz setInterval / setTimeout wg mojego bardzo ogólnego rozumienia nie tworzą żadnych dodatkowych wątków.
Przynajmniej nie na poziomie API. Być może wewnętrznie jest wykorzystywany jakiś wątek do tego, ale nie widać tego w API.

$ajax/success wskazuje na funkcję która się uruchomi na wypadek gdybyśmy jakimś cudem dostali poprawną odpowiedź.

Procesowanie wygląda mniej więcej tak:

  • $ajax: wysłanie żądania oraz rejestracja handlera do obsługi odpowiedzi
  • potem na kliencie może się dziać cokolwiek
  • potem przychodzi odpowiedź i JavaScript uruchamia funckcję success
  • w momencie uruchomienia tej funkcji działa tylko ta funkcja - success
  • po jej wyjściu klient wznawia normalne procesowanie

Nie ma tu wątków, bo w trakcie obsługi success wszystko jest blokowane, dlatego nie możesz w nim w nieskończoność np. sobie coś liczyć. Powinieneś zareagować na rezultat i wyjść z funkcji.

To jest tak jak ja to rozumiem wg swojej mizernej wiedzy o jQuery / JavaScript.
BTW $ajax.success jest "deprecated" i trzeba używać "done".

http://api.jquery.com/jQuery.ajax/

Co do timerów to jest podobnie - rejestrujesz funkcję która kiedyś tam będzie wykonana, po tej rejestracji proces wraca do normalnego przetwarzania aż do wystąpienia zdarzenia timera. W środku obsługi timera powinieneś wykonać krótką operację i ew. znowu zarejestrować timer (setTimeout).

http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/

0

działa to mniej więcej na takiej zasadzie jak w winapi - jest nieskończona pętla sprawdzająca czy są w kolejce jakieś komunikaty
jeśli są to wywoływana jest funkcja która oczekiwała na ten komunikat (listener czy jak to tam nazywać)

w jednym czasie jest wykonywana jedna linia programu
jeśli minął na przykład czas ustalony w setInterval to zostaje dodany do listy komunikat o tym, ale nie wykonuje się żadna funkcja, tylko dopiero po wyjściu z aktualnie wykonywanej funkcji, sprawdzana jest kolejka komunikatów i wywoływana odpowiednia funkcja
tak samo wywołując żądanie asynchronicznego pobrania danych nie uruchamia się żaden nowy wątek tylko przeglądarka zajmuje się pobraniem danych a gdy je pobierze dodaje komunikat do kolejki
niewątpliwie przeglądarka sama w sobie ma osobne wątki do pobierania danych, ale z punktu widzenia skryptu javascript wszystko się dzieje w jednym wątku

dzięki temu że zdarzenia nie działają jak przerwania, tylko kolejkują się - nie musisz się martwić o atomowość operacji i blokowanie wątków, tj. że na przykład odczytasz dane do zmiennej, a w tym czasie zacznie się wykonywać funkcja która zmieni te dane; skrypt wróci do poprzedniej funkcji i będzie operować na starych danych, które potem zapisze, a bardziej aktualne dane zostaną utracone

osobne wątki jedynie tworzą się jedynie przez webworkers

0

Dziękuję za odpowiedź, ale z tego wynika że $ajax/done jest lepszym rozwiązaniem, ponieważ teoretycznie setInterval ustawiony na np.: 5 sec będzie bardziej uciążliwy niż $ajax/done.

Zobaczymy co wyjdzie w praniu :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1