每个客户端强制使用1个唯一的WebSocket连接?

huangapple go评论130阅读模式
英文:

Enforcing 1 unique websocket connection per client?

问题

我有一个网页,它与服务器建立了一个 WebSocket 连接。我必须确保网站的用户只能建立一个连接,所以打开一个新标签页并导航到同一个页面将关闭之前的连接。

我考虑维护一个以会话 ID 为键的映射;然而,由于映射的大小需要不断调整以适应越来越多的客户端连接,我担心它会有性能问题,并且由于它是并发访问的,可能需要进行某种形式的锁定。

有没有关于确保每个客户端唯一连接的性能高效方法的想法?很想听听建议,谢谢。

英文:

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.

答案1

得分: 1

我不会担心问题中概述的解决方案的性能。如果你想关闭之前的连接,没有办法绕过维护服务器端的映射。假设只有一个服务器,并且你正在使用Gorilla websocket包,下面的代码应该可以解决问题:

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()
}

与接受传入的网络连接、完成websocket握手以及其他发生的一切相比,更新这个映射的成本很小。

英文:

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.

huangapple
  • 本文由 发表于 2015年10月29日 00:45:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/33396842.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定