user870339
user870339

Reputation:

Enforcing 1 unique websocket connection per client?

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

Answers (1)

Thundercat
Thundercat

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

Related Questions