отправленные сервером события Golang

Я хотел бы сделать одностороннюю потоковую передачу данных и экспериментирую с SSE vs Websockets.

Используя SSE для создания сервера golang, я не понимаю, как уведомить клиента о завершении сеанса. (например, сервер завершил отправку событий, или сервер внезапно отключается, или клиент теряет связь)

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

Многие примеры с SSE не могут показать клиенту хорошую обработку клиентского соединения.

Было бы проще с Websockets?

Любые предложения по опыту приветствуются.

Спасибо


person mcbain83    schedule 07.07.2015    source источник
comment
Не могли бы вы отправить сообщение с данными с сервера, указывающее, что клиент должен закрыть соединение, а затем заставить клиента окончательно вызвать закрытие соединения?   -  person dm03514    schedule 07.07.2015
comment
какой клиент sse вы используете? EventSource?   -  person dm03514    schedule 07.07.2015
comment
Я использовал github.com/JanBerktold/sse, но мой вопрос немного более общий, чем конкретная библиотека выполнение. Думаю, я мог бы попробовать разработать хороший пример клиент-сервер ...   -  person mcbain83    schedule 08.07.2015


Ответы (1)


Стандарт SSE требует, чтобы браузер автоматически переподключался через N секунд, если соединение потеряно или если сервер намеренно закрывает сокет. (N по умолчанию 5 в Firefox, 3 в Chrome и Safari, последний раз я проверял.) Итак, если это желательно, вам не нужно ничего делать. (В WebSockets вам придется реализовать такое переподключение для себя.)

Если такое повторное подключение нежелательно, вам следует вместо этого отправить сообщение клиенту, в котором говорится: «шоу окончено, уходите». Например. если вы транслируете финансовые данные в потоковом режиме, вы можете отправить их в пятницу вечером, когда рынки будут закрыты. Затем клиент должен перехватить это сообщение и закрыть соединение со своей стороны. (После этого сокет исчезнет, ​​поэтому серверный процесс автоматически закроется.)

В JavaScript и при условии, что вы используете JSON для отправки данных, это будет выглядеть примерно так:

var es = EventSource("/datasource");
es.addEventListener("message", function(e){
  var d = JSON.parse(e.data);
  if(d.shutdownRequest){
    es.close();
    es=null;
    //Tell user what just happened.
    }
  else{
    //Normal processing here
    }
  },false);

ОБНОВЛЕНИЕ:

Вы можете узнать, когда происходит повторное подключение, послушав событие "close", а затем посмотрев на e.target.readyState

es.addEventListener("error", handleError, false);
function handleError(e){
  if(e.target.readyState == 0)console.log("Reconnecting...");
  if(e.target.readyState == 2)console.log("Giving up.");
  }

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

Еще одна вещь, которую вы можете настроить, - это время повтора, если сервер отправит retry:NN сообщение. Поэтому, если вы не хотите быстрого переподключения, но вместо этого хотите, чтобы между любыми попытками переподключения было не менее 60 секунд, пусть ваш сервер отправит retry:60.

person Darren Cook    schedule 07.07.2015
comment
Хорошо, понятно, возможно, я просто работал в предположении, что в протоколе подключения есть что-то, что я мог бы использовать. По сути, мне нужно было бы создать какое-то сообщение об отключении для моего клиента, а затем обработать его. Я думаю, это может сработать. Моему конкретному клиенту может потребоваться более строгие правила обработки отключений, например, выключение приложения, если оно теряет соединение и т. Д. Спасибо за информацию! - person mcbain83; 08.07.2015
comment
Только что проверил мою книгу, она описана на стр.59 - с помощью обработчика ошибок. Это не очень полезно, и я не рекомендую вам использовать его в вашем случае, но я обновлю свой ответ. - person Darren Cook; 08.07.2015