#go
#Вперед
Вопрос:
Я хочу создать соединение с Websocket через GO. Это соединение следует четко определенному шаблону: клиент должен «аутентифицироваться» (вводить данные) самостоятельно сразу после создания соединения. Если клиент этого не сделает, соединение будет закрыто через короткий промежуток времени.
Мой текущий код содержит этот начальный тайм-аут (initTimeout) и максимальный тайм-аут для всех подключений. Хотя эти таймеры можно легко проверить, я не уверен, как я могу объединить таймеры с ожиданием сообщения, которое блокирует выполнение.
ws, err := upgrader.Upgrade(w, r, nil)
initTimeout := time.NewTicker(time.Duration(30) * time.Second)
maxTimeout := time.NewTicker(time.Duration(45) * time.Minute)
for {
select {
case <- initTimeout.C:
ws.WriteMessage(websocket.TextMessage, []byte("No input received"))
ws.Close()
case <- maxTimeout.C:
ws.WriteMessage(websocket.TextMessage, []byte("Maximum timeout"))
ws.Close()
default:
mt, message, err := c.ReadMessage()
// will this block the timers?
}
}
Ответ №1:
Используйте крайний срок чтения для реализации таймаутов:
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
// handle error
}
// Read the initial message with deadline of 30 seconds
ws.SetReadDeadline(time.Now().Add(30 * time.Second))
mt, message, err := ws.ReadMessage()
if err != nil {
// Handle the error which might be a deadline exceeded error.
}
// process the initial message
// ...
for {
// Read next message with deadline of 45 minutes
ws.SetReadDeadline(time.Now().Add(45 * time.Minute))
mt, message, err = ws.ReadMessage()
if err != nil {
// Handle the error which might be a deadline exceeded error.
}
// process message
// ....
}