Reputation:
I have a webpage that establishes a websocket connection with the server. I have to make sure that a user of the site can only establish a single connection, so opening a new tab and navigating to the same page will close the previous connection.
I was thinking of maintaining a map with the session id as the key; however, as the map would have to be constantly adjusted in size as more and more clients connect I am afraid of it having performance problems, and since it's accessed concurrently you would probably have to do some kind of locking.
Any ideas for performance efficient ways of ensuring a unique connection per client? Would love to hear suggestions, thank you.
Upvotes: 0
Views: 912
Reputation: 120960
I wouldn't be concerned about the performance of the solution outlined in the question. If you want to close the previous connection, there's no way around maintaining server side maps. Assuming a single server and that you are using the Gorilla websocket package, the following code should do the trick:
var (
mu sync.Mutex
conns map[string]*websocket.Conn
)
func addConn(sessionID string, conn *websocket.Conn) {
mu.Lock()
prev := conns[sessionID]
conns[sessionID] = conn
mu.Unlock()
if prev != nil {
// Close will stop concurrent reads and writes.
prev.Close()
}
}
func removeConn(sessionID string, conn *websocket.Conn) {
mu.Lock()
// We don't simply delete(conns, session) to avoid race on cleanup.
if conns[sessionID] == conn {
delete(conns, sessionID)
}
mu.Unlock()
}
The cost of updating this map is small compared to the cost of accepting an incoming network connection, completing websocket handshake and everything else that's happening in scenario.
Upvotes: 1