#Panics in matchmaking server

3 messages · Page 1 of 1 (latest)

quasi tiger
#

can you explain the problem? people are most likely not going to click that URL

rapid linden
#

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))
}