воскресенье, 27 июля 2014 г.

Живое общение: WebSocket (Часть первая)

После написания постов о связке WebSocket-JMS, я подумал, а почему бы не написать более подробный пост о WebSocket? Сам протокол вполне заслуживает отдельного внимания. В данном посте я опишу WebSocket, а так же работу с ним на серверной стороне при помощи Java EE.
WebSocket - это програмный протокол полнодуплексной связи, работающий поверх TCP, позволяющий обмениваться сообщениями между клиентом и сервером в реальном времени. Проще говоря, этот протокол предоставляет возможность отправки сообщений между клиентом и сервером в любом направлении, чего раньше очень не хватало (хотя был Comet, но это совсем другая история).
На данный момент стандарт протокола описан W3C и утверждён IETF в RFC 6455.
По информации из Википедии, следующие браузеры имеют поддержку WebSocket:
Google Chrome (начиная с версии 4.0.249.0);
Apple Safari (начиная с версии 5.0.7533.16);
Mozilla Firefox (начиная с версии 4);
Opera (начиная с версии 10.70 9067);
Internet Explorer (начиная с версии 10);

Клиентская сторона (JavaScript)

На сторое клиента всё достаточно просто: создаём объект класса WebSocket с указанием адреса для соединения (эндпоинт).
var ws = new WebSocket("ws://localhost:8080/sandbox-websocket/sandbox");

Обратите внимание, что протокол в адресе ws. Так же может быть wss в случае, если используется SSL-шифрование.
После того как объект создан, можно описать его поведение в методах onopen (при открытии соединения), onerror (при ошибке соединения), onclose (при закрытии соединения) и onmessage (при получении события).
ws.onopen = function(event) {
 console.log('Connection opened');
};

ws.onerror = function(event) {
 console.log('Error occcured');
};

ws.onclose = function(event) {
 console.log('Console closed');
};

ws.onmessage = function(event) {
 console.log('Message received: ' + event.data);
}; 
Проверить браузер на поддержку вебсокетов достаточно просто:
if ('WebSocket' in window) {
// do what you want with WebSocket
}

Во всех методах информация о событии передаётся в объекте event. При получении сообщения от сервера текст содержится в event.data. Если в сообщении передана JSON-строка, то её можно преобразовать в объект методом JSON.parse. Отправка сообщения серверу тоже не составит труда.
ws.send("Some text");// отправка текста

ws.send(JSON.stringify({foo:"bar"}));// отправка объекта

Серверная сторона (Java EE)

Подержка WebSocket была реализована в Java EE 7. Для создания серверного эндпоинта, который будет общаться с клиентом, достаточно создать класс с аннотацией @ServerEndpoint и методами, помеченными соответствующими аннотациями.
@ServerEndpoint(value = "/sandbox")
public class SandboxEndpoint {

    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        System.out.println("New Session opened");
    }
    
    @OnMessage
    public void onMessage(String message, Session session) {
        session.getBasicRemote().sendText("Client wrote: " + message);
    }
    
    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("Error occured: " + throwable.getMessage());
    }
    
    @OnClose
    public void onClose (Session session, CloseReason closeReason) {
        System.out.println("Session closed: " + closeReason.getReasonPhrase());
    }
    
}

Порядок агрументов в методах нестрогий. Так же путь, передаваемый в адресе эндпоинта, может содержать переменные пути:
@ServerEndpoint(value = "/sandbox/{chat}/{username}")

Данные переменные можно передавать в методы в качестве аргументов примитивных типов или объектов класса String. Особое внимание стоит обратить на метод, помеченный аннотацией @OnMessage. Набор его аргументов может разниться в зависимости от ситуации. Отправлять текстовые сообщения от сервера клиенту так же достаточно просто:
session.getBasicRemote().sendText("Some text message");

Код данного поста доступен на GitHub. В следующих постах я постараюсь описать все варианты использования метода @OnMessage на сервере, работу с энкодерами и декодерами, а так же использование веб-сокетов за пределами веб-приложений. Рекомендую ознакомиться со статьёй "Building a Smart Home Server by Using the Java EE 7 WebSocket API", где демонстрируется наглядное применение вебсокетов.

Полезные ссылки

Комментариев нет:

Отправить комментарий