Работая над циклом, который получает сообщения и обрабатывает их соответствующим образом, в основном это эхо-эхо-сервер веб-сокета с поддержкой активности и аутентификацией, и я некоторое время застрял в части поддержки активности.
Концепция проста: когда сервер запускается, я создаю горутин с тикером и инициализирую указатель uint64, каждый раз, когда тиккер тикает (каждые 2 секунды), я увеличиваю указатель с помощью atomic.AddUint64(clockTicks, 1), затем для каждой горутины подключения к веб-сокету я проверяю переменную каждый тик с помощью сравнения и atomic.LoadUint64 (clockTicks) и отправляю сообщение ping/pong.
Изменить: похоже, что что-то блокирует цикл for до тех пор, пока не будет получено сообщение, результат:
i := atomic.LoadUint64(clockTicks)
if i != cur {
cur = i
if act != true {
fmt.Println("Quit Nao U filthy bot.")
return
} else {
fmt.Println("Keep Going.")
act = false
}
}
В этом фрагменте я := atomic.LoadUint64(clockTicks) и весь блок if запускается только при отправке сообщения i (печатает «Продолжить» в msg), а это не то, что я хочу, я хочу, чтобы фрагмент выполнялся каждый раз. для итерации и «Продолжить». & "Quit nao ...", чтобы запускать каждый раз, когда clockTicks увеличивается
Вот важные части кода, я использую библиотеку веб-сокетов Go и Gorilla:
func Clock() {
clockTicks = new(uint64)
*clockTicks = 0
clock := time.NewTicker(authIntervals).C
for {
<-clock
atomic.AddUint64(clockTicks, 1)
}
}
var wsu = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: OriginHandler,
}
func serveWS(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
http.Error(w, "Method not allowed", 405)
return
}
ws, err := wsu.Upgrade(w, r, nil)
if err != nil {
fmt.Println(err)
return
}
defer ws.Close()
cur := atomic.LoadUint64(clockTicks)
var act, val = true, false
for {
i := atomic.LoadUint64(clockTicks)
if i != cur { /* Only triggers when I receive a msg */
cur = i
if act != true {
fmt.Println("Quit Nao U filthy bot.")
return
} else {
fmt.Println("Keep Going.")
act = false
}
}
mtype, p, err := ws.ReadMessage()
if err != nil {
return
}
...
}
Редактировать 2: кто-то в IRC предположил, что, возможно, блокирует ws.ReadMessage, но я не совсем уверен (он говорит, что ioutil.ReadAll, используемый в реализации ws.ReadMessage, блокирует его, и он в этом почти уверен)