2009-07-15 4 views
2

У меня есть простая игра ajax между двумя пользователями с бэкэндом java (tomcat, spring). Мне нужен хороший способ сообщить одному пользователю, что его противник сделал ход. Теперь все сделано через базу данных и ждет противника, чтобы закончить свою очередь выглядит следующим образом:Java: нужны эффективные уведомления между пользователями сайта

while(!timeout && !opponentIsDone) { 
    //...get the game record from db and check if opponent made turn 
    Thread.sleep(100); 
} 

Могу ли я как-то избавиться от этой петли со сном() и получить немедленно уведомлен без задержки (но с прерыванием) ? Я могу, вероятно, сделать некоторый глобальный статический var и обмениваться данными через него, но мне все равно понадобится подобный цикл, возможно, тайм-аут будет меньше.

Я не могу просто вызвать какой-либо метод, как только поворот будет завершен, потому что все нужно перейти в браузер через ajax, и я не могу выталкивать данные там, только тянуть. Поэтому мне нужно иметь процесс, который ждет противника.

Я ищу легкое и простое решение.

Спасибо.

+0

Если все сделано через базу данных, сообщая нам, какую систему базы данных вы используете, может быть идея. –

+0

(Хотя лучшим ответом, вероятно, будет что-то вроде использования JMS.) –

+0

база данных - это mysql (через спящий режим) – serg

ответ

2

Возможно, вы захотите ознакомиться с расширенной поддержкой ввода-вывода Tomcat (Comet).
http://tomcat.apache.org/tomcat-6.0-doc/aio.html

+0

Спасибо, я прочитал об этом, но кажется, что это излишний ... Я бы предпочел что-то максимально простое. – serg

+1

Перед Tomcat 6 я развернул свою систему уведомлений. Это было отнюдь не просто. Это сложная проблема из-за безгражданности http. – Jataro

2

Я думаю, что вы ищете распределенные события (ака подписчика/издатель) модель, и я считаю, Dojo Framework реализовал его: http://ajaxpatterns.org/Distributed_Events

+0

Если я правильно понял эту статью, она по-прежнему использует петлю, похожую на мою, но вместо проверки записи базы данных она проверяет события. Я мог бы сделать то же самое со статической переменной. – serg

+0

Прохладный. Был бы признателен за ответ на этот вопрос, если вы удовлетворены. – gravyface

1

Есть много способов, чтобы подтолкнуть уведомления веб клиент. IM-клиент Gmail - отличный пример такого рода вещей. Это часто достигается путем открытого HTTP-соединения каким-либо образом, и это семейство методов называется COMET. В Википедии есть статья об этом, и есть блоги, посвященные теме (http://cometdaily.com/).

Даже если вы не использовали эту технику, все еще есть много улучшений, которые вы можете внести в алгоритм, который вы определили в своем вопросе. Один из способов - использовать тип ожидания wait/notify или подход подписчика/издателя. Другим было бы немедленное возвращение страницы «ожидание другого игрока, чтобы сделать поворот», и эта страница автоматически обновляется каждые несколько секунд, пока другой игрок не сделает свою очередь.

Я думаю, что решение, которое вы ищете, является уведомлением о стиле COMET.

+0

Ну, я уже держу открытое http-соединение, ожидая соперника, поэтому я уже использую кометный подход (в вики они называют его Ajax длинным опросом). Меня беспокоит только то, что я хочу избавиться от сна и получить немедленное уведомление. Все эти подходы во втором абзаце используют в основном те же ожидания в технике цикла, которые у меня уже есть. – serg

1

Если вы имели глобальный статический вар какой-то, вы могли бы использовать java.util.concurrent.BlockingQueue <T>

< BlockingQueue Turn > эстафетной передачи = новый ArrayBlockingQueue <Turn> (1);

// противник
handoff.offer (myTurn);

// другая резьба можно использовать
Turn otherTurn = handoff.poll (90, TimeUnit.SECONDS);

если (otherTurn == NULL)
// то никакого поворота не сделал

Вы можете легко заставить людей ждать друг друга с помощью SynchronousQueue вместо ArrayBlockingQueue.

и, конечно же, он не должен быть глобальным статическим - он может быть любым доступным для обоих пользователей.

1

flex/flash имеет систему чата в реальном времени (с использованием программирования дистанционных объектов).

Вы должны установить BlazeDS (бесплатно) http://opensource.adobe.com/blazeds/, он поставляется с образцом приложения. Это называется технологией AMF. Я думаю, что Spring так или иначе поддерживает этот AMF.

http://www.adobe.com/devnet/livecycle/articles/blazeds_spring.html http://blog.springsource.com/2008/12/17/using-spring-blazeds-integration-m1/

Это хорошо для веб-сайта на основе флэш. Однако, если вы не хотите использовать flash, я думаю, что вы можете скрыть его или сделать его достаточно маленьким, просто чтобы использовать его как канал связи на своей странице.

Возможно, вам необходимо найти способ оповестить свою веб-страницу/javascript после получения флэш-данных с сервера.

Да, я знаю, что этот метод немного взломан, и это не чистый способ делать вещи :) просто для того, чтобы предоставить вам альтернативу.

1

DWR (Direct Web Remoting) - это пакет, который позволяет вам создавать Java-методы на сервере, непосредственно доступные Javascript (путем создания прокси-сервера). Он имеет функцию под названием «Обратный Ajax», которая является простым способом обработки push-сценариев.

Смежные вопросы