Как сохранить соединения WebSocket открытыми после возврата функции обработчика HTTP? - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь написать код для потоковой передачи данных по теме, например, радиостанции (один вещатель, несколько слушателей).Я застрял на том, как обработать новый запрос на соединение WebSocket, не имея процедуры для каждого открытого WebSocket (который начинает становиться ресурсоемким для многих "слушателей" одной и той же "станции").

НаНа данный момент у меня есть карта структур dataStream, которая выглядит следующим образом:

struct dataStream {
  data chan byte[]
  conns []*websocket.Connection
}

И вот псевдокод для обновления запроса до WebSocket, а затем для попытки добавить соединение WebSocket в conns dataStreams:

func process_request(w http.ResponseWriter, r *http.Request) {
  // hundred lines of business logic...
  c := upgrade websocket connection
  defer c.Close()
  if dataStream exists {
    append the new connection c to the dataStream.conns slice
  } else {
    create new dataStream
    append the new connection c to the dataStream.conns slice
    stream(dataStream)
  }
}

И вот функция stream, упомянутая в приведенном выше блоке кода.Один из них выполняется в фоновом режиме для каждого dataStream (не для каждого соединения WebSocket).

func stream(ds *dataStream) {
  ticker := time.NewTicker(poll every ~10 seconds)
  go func() { // this is to poll and remove closed connections
  for _ = range ticker.C {
    for traverse ds.conns {
      ping all connections, remove any closed ones and free memory
      if len(ds.conns == 0){ // no more connections are listening to this dataStream
        delete the ds dataStream and free the memory
        stop ticker
        return // kill goroutine and free the memory
      }
    }
  }}()
  while len(ds.conns) != 0 { // while there are open connections
    fetch any available <-ds.data from channel
    write the data as websocket message to each connection
  }
}

Проблема этого подхода заключается в том, что в функции process_request, как только поток достигает дна if statement 2-го и последующих подключений, после того, как новое подключение добавлено к срезу dataStream.conns, функция завершает закрытие соединения WebSocket! В результате stream() работает в фоновом режиме и опрашивает, чтозакрытое соединение было добавлено к срезу ds.conns и удаляет его.

Отсюда мой вопрос:

Какой подход я должен использовать, чтобы сохранить соединение WebSocket открытым длядаже после того, как функция обработчика process_request вернется, предпочтительно без запуска отдельной процедуры для каждого соединения?

1 Ответ

0 голосов
/ 21 сентября 2018

Приложение должно явно закрывать соединение Gorilla.Соединение не закрывается автоматически, когда возвращается функция обработчика HTTP.

В этом случае приложение использует оператор defer для закрытия соединения при возврате из обработчика.Удалите оператор defer, чтобы избежать закрытия соединения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...