Ответ 1
Воспроизведение включает пример приложения чата, который демонстрирует, как использовать комету. Пример не объясняет, что происходит, поэтому вот что я понял.
Model
Чтобы другие могли найти новые обновления, которые вы отправляете, их нужно будет где-то хранить. По-видимому, это может быть в кеше или даже в самом контроллере, но база данных будет самой безопасной ставкой, поэтому вам понадобится модель. Им также понадобится способ определить, какие обновления для них новы, а это значит, что вам, вероятно, понадобится поле даты (см. Также: Временная метка последнего обновления с JPA)., В примере чата используется простая модель:
@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();
}
}
контроллер
Контроллер нуждается в двух методах, чтобы облегчить комету. Там, где публикуются новые данные, что не делает ничего особенного:
public static void postMessage(String message) {
new Message(session.get("nick"), message).save();
}
и один для получения обновлений:
public static void newMessages() {
List<Message> messages = Message.find("date > ?", request.date).fetch();
if (messages.isEmpty()) {
suspend("1s");
}
renderJSON(messages);
}
Ключевым битом здесь является suspend("1s")
, который является тем, что содержит HTTP-запрос, открытым, проверяя новые данные один раз в секунду.
Вид
В представлении есть три обязанности - отправка новых данных, выборка обновлений и последующее предоставление этих обновлений.
Отправка, как и соответствующее действие контроллера, не делает ничего особенного:
$('#send').click(function(e) {
var message = $('#message').val();
$('#message').val('');
$.post('@{postMessage()}', {message: message});
});
Получение обновлений - это волшебный бит:
// Retrieve new messages
var getMessages = function() {
$.ajax({
url: '@{newMessages()}',
success: function(messages) {
$(messages).each(function() {
display(this);
});
},
complete: function() {
getMessages();
},
dataType: 'json'
});
}
getMessages();
getMessages()
вызывается один раз, чтобы начать все, а затем он вызывает себя рекурсивно после каждого успешного запроса. Он ПОЛУЧИТ действие newMessages()
, которое ищет новые сообщения, и если они отсутствуют, запрос остается открытым до тех пор, пока он не сможет что-то сообщить. Когда новые сообщения обнаружены, данные JSON передаются функции display
:
var display = function(message) {
$('#thread').append(tmpl('message_tmpl', {message: message}));
}
Функция display
применяет JavaScript-шаблон для JavaScript к данным JSON для визуализации новых сообщений. Использование микро шаблонов не требуется, но это работает очень хорошо. Они включены прямо в шаблон страницы, которая будет их использовать:
<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"
заставляет браузеры, поисковые системы и устройства чтения с экрана игнорировать весь блок script
. Результат намного легче читать и поддерживать, чем использовать jQuery для сборки узлов или объединения строк. В целом это довольно просто, как только вы знаете, какие биты имеют значение.