Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Jetty WebSocket статус при обрыве соединения, Почему не не меняется статус? 
:(
    Опции темы
ZVano
  Дата 23.9.2016, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 258
Регистрация: 11.12.2006
Где: Украина, Кривой Р ог

Репутация: нет
Всего: 4



0. Имею рабочий WebSocketServer на "ws://localhost:8000".
Он запущен и готов к работе.
Для простоты считаем что это сервер чата.
1. Чат-клиент. Запускаю. Выполняется успешный коннект к серверу используя Jetty WebSocketClient wsClient 
2. Чат-клиент. Запрашиваю статус соединения.
wsClient.isStarted() // Возвращает true
3. Чат-сервер. Вручную выключаю.
4. Чат-клиент. Запрашиваю статус соединения
wsClient.isStarted() // Возвращает true

Класс-обертка для инициализвации соединения
Код

// Обрезанный чат-клент.
// Оставлен только метод запуска, который вызывается в п.1

import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;

public class ChatClient{
    /**
     * Таймаут соединений при простое. По-умолчанию равен длительности рабочего
     * дня.
     */
    protected long maxIdleTimeout = 8 * 60 * 60 * 1000; // HH * MM * SS * MI
    protected String wsUrl="ws://localhost:8000";
    /**
     * Это самописный класс с методами onConnect, onClose, onMessage
     * Его методы дергает Jetty
     */
    protected MyWebSocketClient ws = new MyWebSocketClient();
    protected WebSocketClient wsClient = new WebSocketClient();
    public void start() {
        add2log("Старт...");
        try {
            wsClient.setMaxIdleTimeout(this.maxIdleTimeout);
            wsClient.start();
            ClientUpgradeRequest wsRequest = new ClientUpgradeRequest();
            Future<Session> session = wsClient.connect(ws, new URI(wsUrl), wsRequest);
            Boolean isConnnected = ws.awaitConnected(10, TimeUnit.SECONDS);
            if (isConnnected) {
                add2log("Успех. Соединен с ").add2log(wsUrl);
            } else {
                add2log("Неудача. Сервер не ответил за заданное время.");
                wsClient.stop();
            }
        } catch (Exception e) {
            add2log("Неудача. Сообщение об ошибке: " + e.getMessage());
            wsClient.stop();
        }
    }
    public boolean getIsStarted() {
        add2log("getIsStarted/" + wsClient.isStarted());
        return wsClient.isStarted();
    }
}

Класс, который дергает Jetty
Код

public class MyWebSocketClient{
    @OnWebSocketClose
    public void onClose(int statusCode, String reason) throws Exception {...}
    @OnWebSocketConnect
    public void onConnect(org.eclipse.jetty.websocket.api.Session session) throws Exception {...}
    @OnWebSocketMessage
    public void onMessage(String msg) throws Exception {...}
}


Вопросы:
1. Почему после обрыва соединения вызов wsClient.isStarted() возвращает true?
2. Как правильно работать с WebSocket клиентом от Jetty, если подразумевается длительное соединение?
В родной документации приведен пример короткоживущего SimpleEchoClient приложения.
Буду премного благодарен, если кто-то запостит ссылки на примеры.

Это сообщение отредактировал(а) ZVano - 23.9.2016, 17:50


--------------------
НЕ ФЛУДИМ. Пользуемся кнопками "+" или "-" для выражения своего отношения к теме или сообщению.
Гуглим "Как правильно задавать вопросы"
PM MAIL Skype   Вверх
ZVano
Дата 28.9.2016, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 258
Регистрация: 11.12.2006
Где: Украина, Кривой Р ог

Репутация: нет
Всего: 4



Не знаю правильно сделал или нет, но теперь я проверяю сессию, которая приходит в onConnect моего MyWebSocketClient.


Код

// Тут session - то что пришло в onConnect
org.eclipse.jetty.websocket.api.Session session = ws.getSession();
if (session != null & session.isOpen()){
  return true;
}


Фрагмент из Session.java
Код

package org.eclipse.jetty.websocket.api;

public interface Session extends Closeable
{
    /**
     * Return true if and only if the underlying socket is open.
     * 
     * @return whether the session is open
     */
    abstract boolean isOpen();
}


Это сообщение отредактировал(а) ZVano - 28.9.2016, 17:45


--------------------
НЕ ФЛУДИМ. Пользуемся кнопками "+" или "-" для выражения своего отношения к теме или сообщению.
Гуглим "Как правильно задавать вопросы"
PM MAIL Skype   Вверх
ZVano
  Дата 24.10.2016, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 258
Регистрация: 11.12.2006
Где: Украина, Кривой Р ог

Репутация: нет
Всего: 4



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

Далее искуственный пример:
Код

@WebSocket(maxTextMessageSize = 64 * 1024)
public class MyWebSocketClient{
    @OnWebSocketConnect
    public void onConnect(org.eclipse.jetty.websocket.api.Session session) throws Exception {
        System.out.printf("Шаг 1. При коннекте сохраняем сессию в свойство класса.");
        this.session = session;
    }
    @OnWebSocketMessage
    public void onMessage(String msg) throws Exception {
        System.out.printf("Шаг 2. Обработка сообщения");
        System.out.printf("Шаг 2.1. Сохраняем текст сообщения.");  
        saveToStorage(msg); // Этот искуственный вызов "заморозит" приложение на минуту. На  20й секунде искуственно производится разрыв WSS соединения со стороны сервера.
        System.out.printf("Шаг 2.2. Оповещаем клиента о результате работы"); 
        if (this.session.isOpen()){
             System.out.printf("Шаг 2.2.1. isOpen = true"); 
             this.session.getRemote().sendString("{succes : 'true', message : 'Данные успешно сохранены'}");
        } else {
             System.out.printf("Шаг 2.2.2. isOpen = false"); 
        }
    }
    protected Session session;
    @OnWebSocketClose
    public void onClose(int statusCode, String reason) throws Exception {
        System.out.printf("Шаг 3. Произошел разрыв соединения/%d - %s", statusCode, reason); 
    }
}

Получим такой результат:
Код

Шаг 1. При коннекте сохраняем сессию в свойство класса.
Шаг 2.1. Сохраняем текст сообщения.
Шаг 2.2. Оповещаем клиента о результате работы
Шаг 2.2.1. isOpen = true
Шаг 3. Произошел разрыв соединения/1006 - WebSocket Read EOF


Вопрос остается прежним - Как определить состояние подключения?
Интересует готов WebSocket к передаче данных или нет.
Неприятной неожиданностью стал тот факт, что в данном случае отправка сообщения не вызывает исключения "this.session.getRemote().sendString(...)", а по документации должен свалиться.

Код

package org.eclipse.jetty.websocket.api;
public interface RemoteEndpoint {
    /**
     * Send a text message, blocking until all bytes of the message has been transmitted.
     * <p>
     * Note: this is a blocking call
     * 
     * @param text
     *            the message to be sent
     */
    void sendString(String text) throws IOException;
}


Это сообщение отредактировал(а) ZVano - 24.10.2016, 17:32


--------------------
НЕ ФЛУДИМ. Пользуемся кнопками "+" или "-" для выражения своего отношения к теме или сообщению.
Гуглим "Как правильно задавать вопросы"
PM MAIL Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Работа с сетью | Следующая тема »


 




[ Время генерации скрипта: 0.1014 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.