Quontas
Quontas

Reputation: 399

Golang timeout or return early

I'm attempting to build a realtime multiplayer game server in Golang using websockets as a learning project, and I'm having difficulty understanding how exactly I'm supposed to implement this concept:

All of the users in a game room are given a duration, MAX_TIMEOUT to respond to a prompt provided. Responses are submitted via websocket connections. If all of the users respond before MAX_TIMEOUT, then Action A should happen, using the responses. If MAX_TIMEOUT elapses before all of the prompts are submitted, then Action B should happen, using the responses available.

Coming from Node.JS, I could see myself implementing this with Promises, but in Golang, I'm rather lost.

Any advice?

Upvotes: 1

Views: 468

Answers (2)

Miguel
Miguel

Reputation: 20633

This example should give you a better understanding of how to implement a timeout. You need to use the select statement to wait on channels. The first channel that responds with a value is the case that gets executed.

package main

import (
    "fmt"
    "time"
)

func main() {
    maxTimeout := 2 * time.Second
    ready := make(chan bool, 1)
    go collectUserResponses(ready)

    select {
    case <-ready:
        fmt.Println("do action A")
    case <-time.After(maxTimeout):
        fmt.Println("do action B")
    }
}

func collectUserResponses(ready chan bool) {
    time.Sleep(1 * time.Second) // simulate waiting for users to respond
    ready <- true
}

https://play.golang.org/p/94jIo5tW6eG

Upvotes: 2

ataboo
ataboo

Reputation: 817

Checkout gorilla/websocket's chat example. It uses tickers and channels in client.go like mentioned above.

The server's prompt handling could be its own routine running parallel to the read/write pump routines.

go func() {
    for {
        for _, player := range players {
            player.Answered = false
            player.Send("prompt")
        }

        time.Sleep(time.Second * 10)

        for _, player := range players {
            if player.Answered {
               player.Send("You answered")
            } else {
               player.Send("Too slow")
            }
        }
    }
}()

// the reading routine sets `Answered` true when message received

Upvotes: 2

Related Questions