В этом примере, https://github.com/kljensen/golang-html5-sse-example/blob/d4eba81ddea2b4191f039adb6929086ca6b39c0f/server.go#L130, вы можете заблокировать канал. Но выполнение этого в моем HandleExecute
приводит к тому, что состояние подключения браузера / клиента остается в состоянии ожидания, и клиенту ничего не отправляется.
Если я удаляю for для l oop и использую команду select оператор с регистром по умолчанию не записывает никаких данных, затем он работает (execute
записывает и сбрасывает данные), за исключением того, что обработчик возвращается и клиент повторно соединяется каждые 5 секунд вместо поддержания соединения. Когда я делаю это таким образом, клиент получает потоковые данные только через интервалы переподключения.
Таким образом, в конечном итоге пользователи видят задержку, длящуюся менее 5 секунд, в зависимости от того, когда ударил HandleExecuteRequest
. HandleExecute
может быть готов к записи, но клиент, возможно, еще не подключился. Я надеюсь, что это имеет смысл.
Как мне написать эти обработчики, чтобы поддерживать постоянное соединение вместо повторного соединения?
func (s *Server) HandleExecuteRequest(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
log.Printf("Error parsing request: %v", err)
fmt.Fprintf(w, "Error parsing request: %v", err)
return
}
decoder := schema.NewDecoder()
var f Form
err = decoder.Decode(&f, r.PostForm)
if err != nil {
log.Printf("Error decoding form: %v", err)
fmt.Fprintf(w, "Error decoding form: %v", err)
return
}
s.clientMap[r.RemoteAddr] <- buildCommand(&f)
}
func (s *Server) HandleExecute(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
s.addClient(r)
for {
cmd := <-s.clientMap[r.RemoteAddr]
execute(w, cmd)
}
}
Javascript
var source = new EventSource('<host>/execute');
source.onmessage = function(e) {
document.querySelector("code").innerHTML +="<span class='font-weight-bold' style='white-space: pre-wrap; padding-left: 200px;'>" + e.data + "</span>" + "<br>"
};
Если я обновить HandleExecute
до ниже, я получаю непрерывное соединение, но затем HandleExecuteRequest
застревает в ожидании, когда это ударил. Может, как я настраиваю клиентов и обрабатываю каналы в этом случае.
func (s *Server) HandleExecute(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
s.addClient(r)
for {
select {
case cmd := <-s.clientMap[r.RemoteAddr]:
execute(w, cmd)
default:
fmt.Fprint(w, ": no data\n\n")
}
}
}