Why two (or three) go routines per connection? Why not one net socket (for reads) and two channels (one for writes, other for pub/sub) and select() between them? It seems like the OP is trying too hard to avoid event loops.
Please upvote parent. This is the first thing that struck my mind too. golang offers `select` for non-blocking calls. Deeply skeptical that node.js is the best solution for a chat service. (unless the backend is serving rendered UI's)