Something like this pseudo-code:
ch1 := make(chan []byte)
go socketHandler(ch1, addr1)
ch2 := make(chan []byte)
go socketHandler(ch2, addr2)
for {
select {
case req1 := <- ch1:
handleRequest(req1)
case req2 := <- ch2:
handleRequest(req2)
}
}
...
func socketHandler(ch chan []byte, addr AddrType) {
// listen and accept omitted
b := make([]byte, bufferLen)
for {
conn.Read(b)
ch <- b
}
}
There’s lots of error handling missing, and close handling, etc. You could add another channel for each socket to return results to socketHandler, etc.
For dynamic connections that can’t be determined at compile time, use reflect package - reflect - Go Packages
Possibly this doesn’t solve your lockups, but it puts all the request handling logic on the main goroutine (which could be bad or good) where it might not cause race conditions if your separate server goroutines had accessed shared state.