英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论