As the proper answer requires proper analysis, general suggestions:
1. Figure out what is the bare minimum resource usage (memory and cpu) without using any goroutines -- directly using sockets. This gives you the baseline for understanding what measurements are important in the grander schema. Also it (somewhat) shows you how good can you get in Go.
2. Figure out how much each part costs you in terms of resource usage. i.e. channels, bolt, tls, json encoding/decoding etc.
3. Optimize the things that matter relative to the baseline.
4. Consider batching messages sent to the client.
5. Consider using less allocations.
I suspect that using
Room: two inbound channels for messages and registration events
1 or 2 go-routines per User
1 go-routine per Room
PS: lock-free data-structures are good where you have high contention... but I suspect this is not the case for you -- it will be sufficient to use a mutex or rwmutex or channels.
+ Egon