Пока все браузеры и веб- серверы не будут должным образом поддерживать протокол Websocket , будет сложно писать переносимые приложения. Больше нет, используя новый плагин JQuery Atmosphere, который может автоматически определять, какой транспорт (Websocket или Comet) использовать, основываясь на том, что поддерживают браузер и веб-сервер.
Поскольку протокол Websocket является относительно новым, не все веб-серверы и браузеры поддерживают его, что означает написание приложения websocket, которое всегда будет блокировать ваших пользователей с помощью ограниченного набора браузеров и веб-сервера. Например, на сегодняшний день только Jetty 8, Resin 4 и GlassFish 3.1 поддерживают Websocket на стороне сервера, а Chrome 4 и Safari 5 на стороне клиента. В конечном итоге все они могут поддерживать протокол, но пройдет несколько лет, прежде чем это произойдет. Нельзя сказать, что Internet Explorer, вероятно, будет реализовывать его подмножество или поврежденную версию, просто чтобы продолжить то, что они начали с IE 6. На стороне сервера, как я обсуждал здесьПотребуются годы, прежде чем Java Community Process (JCP) разработает спецификацию для всех веб-серверов Java. Хорошей новостью является то, что у нас уже есть решение для серверной части под названием Atmosphere , которое позволяет создавать портативные приложения Async / Real Time, поддерживающие как Websocket, так и / или Comet одновременно.
Существует ли переносимая библиотека на стороне клиента, например, возможность писать приложение, которое может использовать Websocket, когда доступно, и аварийное восстановление / понижение для использования техники Comet (потоковая передача по протоколу http или длинный опрос)? Насколько я могу судить, сегодня нет такой доступной библиотеки с открытым исходным кодом, которая поддерживала бы и Websocket, и Comet (не стесняйтесь указывать мне на них). Больше нет, с новым плагином Atmosphere JQuery.
Представляем плагин Atmosphere JQuery
Плагин Atmosphere JQuery легко позволяет писать асинхронные приложения и приложения в реальном времени, не дожидаясь принятия Websocket. Подключаемый модуль Atmosphere JQuery можно использовать с любым веб-сервером, поддерживающим Websocket и Comet. Атмосфера Framework не является обязательной на стороне сервера, но вы что-то упустите, если не будете использовать ее, как я продемонстрирую в этом посте. Это означает, что вы можете использовать его с node.js или любой существующей платформой Comet, такой как Grizzly Comet, Jetty Continuation и Servlet 3,0 Async.
Использование его с серверным приложением, построенным поверх Atmosphere, позволяет плагину определять, что поддерживает веб-сервер, и оптимально выбирать Websocket или любой метод Comet . Например, вы можете установить транспорт по умолчанию для Websocket, развернуть в Jetty 8 и использовать Chrome для запуска вашего приложения. В этом случае будет использоваться протокол Websocket. Теперь, если вы попробуете использовать Firefox, плагин перейдет на Comet без каких-либо изменений на стороне клиента или сервера. Вы также можете развернуть свое приложение в Tomcat 7, который не поддерживает Websocket, и все же приложение будет работать без каких-либо изменений. Хорошая новость заключается в том, что как только Tomcat начнет поддерживать Websocket, ваше приложение будет по-прежнему работать без каких-либо изменений кода, автоматически обновится и будет использовать протокол Websocket.
Написание приложения PubSub, которое поддерживает как Websocket, так и Comet.
Чтобы продемонстрировать, как работает плагин Atmosphere JQuery, напишем простое приложение PubSub, которое может поддерживать WebSocket и Comet (длинный опрос и потоковую передачу по http). Если вы не можете ждать, вы можете просмотреть весь код здесь . На стороне клиента давайте создадим очень простую HTML-страницу, которая позволит нам:
- Выберите тему, на которую мы хотим подписаться.
- Выберите транспорт для использования: Автоопределение, Websocket, Long-Polling или Http Streaming. Автоопределение означает, что плагин Atmosphere JQuery попытается выбрать для нас лучший.
- Опубликовать сообщение в теме, на которую мы подписались.
Цель здесь — написать простой PubSub, который вы можете развернуть в любом месте, использовать с любыми браузерами, не заботясь об используемом транспорте. Что-то типа:
Сначала пользователю необходимо ввести тему. Далее следует выбрать транспорт, который будет использоваться для связи с веб-сервером. По умолчанию давайте использовать Websocket и использовать http-потоковую передачу в случае, если браузер или сервер не поддерживает Websocket.
$ .atmosphere. подписаться (
document.location.toString () + ‘ pubsub /’ + getElementByIdValue (‘topic’),
обратный вызов : ноль
$ .atmosphere. request = { transport : getElementByIdValue (‘transport’)});
Функция подписки принимает три параметра:
- Расположение серверного приложения, включая значение темы. Подробнее о серверной части в следующем разделе.
- Функция обратного вызова, которая вызывается, когда сервер получает сообщения темы.
- Объект Request, который можно использовать для настройки подключаемого модуля.
В объекте «Запрос» можно настроить подключаемый модуль. Значения объекта по умолчанию:
подключено : false, время
ожидания : 60000,
метод : ‘GET’,
заголовки : {},
contentType : «text / html; charset = ISO-8859-1»,
кэш-память : true,
асинхронно : true,
ifModified : false,
обратный вызов : null ,
dataType : »,
url : url,
data : »,
suspend : true,
maxRequest : 60,
logLevel : ‘info’,
requestCount : 0,
fallbackTransport : ‘long-polling’,
транспорт : ‘websocket’
Здесь вы можете настроить HTTP-запрос, аналогичный функции JQuery.ajax (), с дополнительной конфигурацией, такой как transport, fallbackTransport и callback. В описанной выше конфигурации подключаемый модуль сначала попытается использовать Websocket и, если клиент сервера (или оба) не поддерживает Websocket, будет использовать fallbackTransport в качестве второго варианта. Далее необходимо определить обратный вызов, который будет вызван, когда сервер отправит нам обновление о нашей подписанной теме:
function callback(response)
{
var data = response.responseBody
if (data.length > 0) {
$('ul').prepend($('<li></li>').text(" Message Received: " + data + " using transport: " + response.transport));
}
}
Важной частью здесь является объект ответа, который определяется как:
статус : 200,
responseBody : »,
заголовки : [],
состояние : «messageReceived»,
транспорт : «websocket»,
push : [],
ошибка : ноль
В поле responseBody содержится то, что сервер только что отправил нам. Вы также можете получить некоторые заголовки в зависимости от того, какой транспорт используется, если есть ошибка и т. Д. Функция push является ключевой частью, поскольку она позволяет публиковать сообщение в сообщении веб-сервера. Подключаемый модуль будет либо повторно использовать текущий транспорт для отправки сообщений на веб-сервер, либо открыть новый, если текущий транспорт не поддерживает его. Все это сделано волшебным образом плагином. Для нашего примера функция push определяется как:
response.push(document.location.toString() + 'pubsub/' + getElementByIdValue('topic'),
null,
$.atmosphere.request = {data: 'message=' + getElementByIdValue('phrase') })
Эта функция будет вызываться каждый раз, когда вы нажимаете кнопку «Push Message».
Сделать это весело
В качестве примера вы можете развернуть приложение на Jetty 8, использовать Chrome и Firefox, чтобы посмотреть, как оно работает ( скачать здесь ). Вы можете переключать транспорт на лету, выбирая транспорт, используя выпадающее меню. Если вы используете Chrome, весь транспорт будет работать там, где Firefox подделывает Websocket (используя значение по умолчанию fallbackTransport). Сделайте то же самое на Tomcat, и теперь Chrome будет по-прежнему работать, если вы установите транспорт в Websocket.
Хм … а как на стороне сервера?
Не вдаваясь в детали того, как написать приложение Atmosphere (скачайте технический документ или поищите в этом блоге), серверная часть для этого образца JUST состоит из:
@Path("/pubsub/{topic}")
@Produces("text/html;charset=ISO-8859-1")
public class JQueryPubSub {
private @PathParam("topic") Broadcaster topic;
@GET
public SuspendResponse<String> subscribe() {
return new SuspendResponse.SuspendResponseBuilder<String>()
.broadcaster(topic)
.outputComments(true)
.addListener(new EventsLogger())
.build();
}
@POST
@Broadcast
public Broadcastable publish(@FormParam("message") String message) {
return new Broadcastable(message, "", topic);
}
}
Карта проста:
- Вызов $ .atmosphere.subscribe вызовет метод подписки () на стороне сервера. Этот метод скажет Атмосфере приостановить соединение и создать тему (Broadcaster). Трансляция похожа на очередь. Как только вы предложите ему сообщение, оно будет отправлено всем абонентам этой очереди. В нашем случае это означает все браузеры, связанные с этой темой.
- Вызов response.push вызовет метод publish () на стороне сервера. Значение будет передано всем подписанным соединениям, независимо от используемого транспорта.
Все просто ? Вы заметили, что нет упоминания о Comet или Websocket на стороне сервера? С Atmosphere Framework вы пишете приложение, не заботясь об этом.
По любым вопросам или для загрузки подключаемого модуля Atmosphere JQuery перейдите на наш основной сайт и воспользуйтесь нашим форумом Nabble (подписка не требуется) или подпишитесь на команду или меня и напишите свои вопросы там! Вы также можете проверить код на Github . Или загрузите нашу последнюю презентацию, чтобы получить общее представление о структуре.
Первоначально опубликовано на jfarcand.wordpress.com