tags:

views:

38

answers:

1

Note: I'm more interested in understanding general Go concepts/patterns, rather than solving this contrived example.

The Go (golang) WebSocket package provides a trivial echo server example, which condenses down to something like this:

func EchoServer(ws *websocket.Conn) { io.Copy(ws, ws); }

func main() {
 http.Handle("/echo", websocket.Handler(EchoServer));
 http.ListenAndServe(":12345", nil);
}

The server handles simultaneous connections, and I'm trying to upgrade it to a basic chat server by echoing the input to all connected clients.

How would I go about providing the EchoServer handler access to each of the open connections?

+3  A: 

A quick little almost-functional example to give you an idea

var c = make(chan *websocket.Conn, 5) //5 is an arbitrary buffer size
var c2 = make(chan []byte, 5)
func EchoServer(ws *websocket.Conn) {
    buff := make([]byte, 256)
    c <- ws
    for size, e := ws.Read(buff); e == nil; size, e = ws.Read(buff) {
        c2 <- buff[0:size]
    }
    ws.Close()
}
func main() {
    go func() {
        var somekindofstorage
        for {
            select {
            case newC := <-c:
                somekindofstorage.Add(newC)
            case msg := <-c2:
                for _, v := range somekindofstorage {
                    if _, e := v.Write(msg); e != nil { //assuming the client disconnected on write errors
                        somekindofstorage.Remove(v)
                    }
                }
            }
        }
    }()
    http.Handle("/echo", websocket.Handler(EchoServer));
    http.ListenAndServe(":12345", nil);
}

This starts a goroutine that listens on two channels, one for new connections to add and one for messages to send to all active connection. somekindofstorage could be a map or a vector.

Edit:

Alternatively, you could just store all connections in a global map and write to each from EchoServer. But maps aren't designed to be accessed concurrently.

cthom06
Nice, thanks. I'd vote up your answer if I was allowed to.I'll check it out in more detail when I get home.Cheers!
Paul Annesley