Jak grać!prace nad kometą?

Widziałem opis modułu Akka mówi, że Play ma świetne wsparcie dla komet, ale nigdy wcześniej nie korzystałem z Comet i nie mogę znaleźć żadnej wzmianki o tym w dokumentacji Play. Jak to działa w Play?


Spędziłem kilka godzin w ciągu dwóch dni zastanawiając się nad tym, więc chciałem podzielić się tymi informacjami dla innych początkujących graczy.

Author: Brad Mace, 2010-12-22

3 answers

Play zawiera przykładową aplikację do czatu, która pokazuje, jak korzystać z Comet. Przykład nie wyjaśnia jednak, co się dzieje, więc oto, co odkryłem.

Model

Aby inni mogli znaleźć nowe aktualizacje, które wysyłasz, muszą być gdzieś przechowywane. Możliwe, że może to być w pamięci podręcznej lub nawet w samym kontrolerze, ale baza danych będzie najbezpieczniejszym zakładem, więc będziesz chciał modelu. Będą również potrzebować sposobu, aby określić które aktualizacje są dla nich nowe, co oznacza, że prawdopodobnie będziesz potrzebował pola daty(zobacz także: last update timestamp with JPA ). Przykład czatu używa prostego modelu:

@Entity
public class Message extends Model {     
    public String user;
    public Date date;
    public String text;

    public Message(String user, String text) {
        this.user = user;
        this.text = text;
        this.date = new Date();
    }       
}

Controller

[[14]}kontroler potrzebuje dwóch metod, aby ułatwić kometę. Takie, w którym publikowane są nowe dane, które nie robią nic specjalnego:
public static void postMessage(String message) {
    new Message(session.get("nick"), message).save();
}

I jeden do pobierania aktualizacji:

public static void newMessages() {
    List<Message> messages = Message.find("date > ?", request.date).fetch();
    if (messages.isEmpty()) {
        suspend("1s");
    }
    renderJSON(messages);
}

Kluczowym bitem jest suspend("1s"), który utrzymuje otwarte żądanie HTTP, sprawdzając nowe dane raz na drugi.

Widok

Widok ma trzy obowiązki-wysyłanie nowych danych, pobieranie aktualizacji i renderowanie tych aktualizacji.

Wysyłanie, podobnie jak odpowiednia akcja kontrolera, nie robi nic specjalnego:

$('#send').click(function(e) {
    var message = $('#message').val();
    $('#message').val('');
    $.post('@{postMessage()}', {message: message}); 
});

Pobieranie aktualizacji jest magicznym bitem:

// Retrieve new messages
var getMessages = function() {
    $.ajax({
        url: '@{newMessages()}',
        success: function(messages) {
            $(messages).each(function() {
                display(this);
            });
        },
        complete: function() {
            getMessages();
        },
        dataType: 'json'
    });
}
getMessages();

getMessages() jest wywoływany raz, aby rozpocząć, a następnie wywołuje się rekurencyjnie po każdym pomyślnym żądaniu. Otrzymuje akcję newMessages(), która szuka nowych wiadomości, a jeśli nie ma żadnych, które przechowuje żądanie otwarte, dopóki nie ma czegoś do zgłoszenia. Po znalezieniu nowych wiadomości dane JSON są przekazywane do funkcji display:

var display = function(message) {
    $('#thread').append(tmpl('message_tmpl', {message: message}));
}

Funkcja display stosuje mikro-szablon JavaScript do danych JSON w celu renderowania nowych wiadomości. Korzystanie z mikro szablonów nie jest konieczne, ale działa całkiem dobrze. Są one zawarte w szablonie strony, która będzie z nich korzystać:

<script type="text/html" id="message_tmpl">
    <div class="message <%= message.user == '${session.nick}' ? 'you' : '' %> <%= message.user == 'notice' ? 'notice' : '' %>">
        <h2><%= message.user %></h2>
        <p><%= message.text.replace('\n', '<br/>') %></p>
    </div>
</script>

type="text/html" powoduje, że przeglądarki, wyszukiwarki i czytniki ekranu do ignorowania całego bloku script. Wynik jest znacznie łatwiejszy do odczytania i utrzymania niż używanie jQuery do budowania węzłów lub łączenia łańcuchów. Ogólnie rzecz biorąc, jest to dość proste, gdy wiesz, które bity są istotne.

 20
Author: Brad Mace,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:16:58

Istnieje wiele sposobów na uzyskanie server-push lub Comet w aplikacjach internetowych, a jedną z najczęstszych jest Long ankietowanie ze względu na to, że jest dobrze obsługiwane w większości nowoczesnych przeglądarek.

Play osiąga długie sondowanie głównie poprzez funkcję suspend(time);. Ta funkcja robi dwie bardzo ważne rzeczy

  1. Utrzymuje otwarte żądanie HTTP i powtarza akcję w określonym czasie. Pozwala to na wstrzymanie żądania HTTP i kontynuowanie próby operacji, dopóki coś się nie stało się, że chcesz poinformować przeglądarkę o

  2. I co bardzo ważne, wątek jest zwolniony, gdy żądanie jest zawieszone. Oznacza to, że żądanie http nie utrzymuje otwartego wątku dla każdego zawieszonego żądania.

Gdy play jest w trybie DEV, działa tylko na jednym wątku, ale możesz (i próbowałem) uruchomić dziesiątki użytkowników na przykładowej aplikacji czatu bez zawieszania się serwera lub blokowania żądań.

Metoda zawieszania jednak to jedyna rzecz, którą play naprawdę robi, aby pomóc z Comet. Jeśli uruchomisz aplikację przykładowego czatu i zostawisz klienta otwartego, zauważysz, że po 120 sekundach żądanie zostanie przekroczone. Przykładowa aplikacja nie próbuje ponownie żądania. Po stronie klienta technologii long-ankietowej, którą musisz zbudować sam.

Guillaume wspomniał na forach, że przykładowa aplikacja czatu jest tylko demo, jak długo można użyć ankiety. Więc nie sądzę, że gra może poświadczyć posiadanie wielkie wsparcie Comet, to tylko krok w dobrym kierunku.

 7
Author: Codemwnci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-22 20:01:50

Możesz użyć Mist w Akce dla server-push (Comet) wspieranego przez Servlet 3.00 lub Jetty7: http://doc.akkasource.org/http#Mist%20-%20Lightweight%20Asynchronous%20HTTP

 1
Author: Viktor Klang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-26 19:17:30