#Panics in matchmaking server
3 messages · Page 1 of 1 (latest)
Thought so.
I am trying to create a simple matchmaking server to match two clients to each other. Here's the structure
.
├── bootstrap-server
├── cert.pem.local
├── client.go
├── config.go
├── go.mod
├── go.sum
├── key.pem.local
└── main.go
1 directory, 8 files
main.go
package main
import (
"context"
"log"
"net/http"
"time"
_ "github.com/joho/godotenv/autoload"
)
var queue = NewClientQueue()
func main() {
cfg := newConfigFromEnv()
mux := http.NewServeMux()
mux.HandleFunc("GET /", handleFindPeer)
log.Println("Bootstrap server running on", cfg.serverAddr)
log.Fatal(http.ListenAndServeTLS(cfg.serverAddr, cfg.tlsCert, cfg.tlsKey, mux))
}
func handleFindPeer(w http.ResponseWriter, r *http.Request) {
const pairTimeout = time.Minute
client := Client{
addr: r.RemoteAddr,
respWriter: w,
peerMatchedCh: make(chan struct{}),
}
// Use 30 seconds timeout for finding a connection
ctx, cancel := context.WithTimeout(r.Context(), pairTimeout)
defer cancel()
go func() {
if queue.Len() > 0 {
peer := queue.Dequeue()
sendPairingResponse(client, peer)
close(client.peerMatchedCh)
close(peer.peerMatchedCh)
log.Printf("Paired %v and %v\n", client.addr, peer.addr)
} else {
queue.Enqueue(client)
log.Printf("Added %v to waiting queue\n", client.addr)
}
}()
select {
case <-client.peerMatchedCh:
return
case <-ctx.Done():
http.Error(w, "timeout waiting for peer", http.StatusRequestTimeout)
}
}
func sendPairingResponse(c1, c2 Client) {
c1.respWriter.WriteHeader(http.StatusOK)
c2.respWriter.WriteHeader(http.StatusOK)
c1.respWriter.Write([]byte(c2.addr))
c2.respWriter.Write([]byte(c1.addr))
}