是否为每个客户端执行1个唯一的Websocket连接?

我有一个与服务器建立websocket连接的网页。 我必须确保该站点的用户只能建立一个连接,因此打开一个新选项卡并导航到同一页面将关闭以前的连接。</ p>

我在想 维护以会话ID为键的地图; 但是,随着越来越多的客户端连接,必须不断调整地图的大小,我担心它会出现性能问题,并且由于同时访问它,您可能必须进行某种锁定。</ p>

对确保每个客户端唯一连接的性能有效方式有何想法? 很想听听建议,谢谢。</ p>
</ div>

展开原文

原文

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.

dousigan0499
dousigan0499 大卫·布德沃思(DavidBudworth)提出了一些要点。我没有考虑多个浏览器和扩展问题。我结束了通过数据库中的标志进行操作,因为无论如何都必须对其进行访问和写入,因此它可以减轻负载,并且它的含义是一致的。
接近 5 年之前 回复
doukezi4576
doukezi4576 认为这种行为可能不是您的用户所期望的。人们期望打开一个新的浏览器并拥有一个功能齐全的页面。您可能正在用脚射击自己。
接近 5 年之前 回复
dtcu5885
dtcu5885 这不会阻止某人在隐身模式或Firefox+Chrome中使用Chrome。另外,内存中的映射不允许您扩展到超过1台服务器……除非您有一种方法可以执行基于src地址的粘性平衡或类似的操作
接近 5 年之前 回复
dousenjue3214
dousenjue3214 我想我可以做得到。感谢您的建议,不胜感激!
接近 5 年之前 回复
dtvnnhh8992
dtvnnhh8992 您在服务器上进行检查。cookie是HTTPOnly,因此唯一可以删除的方法是用户清除cookie,在这种情况下,无论如何会话都可能被关闭,因此您必须为其提供新的连接。将HTTPOnlycookie视为服务器端资源,因为这确实是它的本质。您控制它,浏览器随身携带,没有人可以触摸它,这是您的存储空间。
接近 5 年之前 回复
douwu8524
douwu8524 我明白您的意思,您将检查该cookie是否存在。但是,我宁愿执行服务器端检查,很容易删除特定的cookie并建立新的连接。
接近 5 年之前 回复
dongtang1910
dongtang1910 您是否考虑过将连接唯一标识符存储在安全的HTTPOnlycookie中?如果不存在,请发出一个新的连接,如果您知道它们的连接是什么。您可以通过依赖浏览器以安全方式维护该状态来避免维护其填充服务器端。
接近 5 年之前 回复

1个回答



我不会担心问题中概述的解决方案的性能。 如果要关闭以前的连接,则无法维护服务器端映射。 假设一台服务器,并且您使用的是Gorilla websocket软件包,则以下代码应能解决问题:</ p>

  var(
mu sync.Mutex
conns map [string ] * websocket.Conn

func addConn(sessionID字符串,conn * websocket.Conn){
mu.Lock()
上一页:= conns [sessionID]
conns [sessionID] = conn
mu.Unlock()
如果prev!= nil {
// Close将停止并发读写。
prev.Close()
}
}

func removeConn(sessionID string,conn * websocket .Conn){
mu.Lock()
//我们不会简单地删除(conns,session)以避免清理。
如果conns [sessionID] == conn {
delete(conns,sessionID) )
}
mu.Unlock()
}
</ code> </ pre>

与接受传入的网络连接相比,更新此映射的成本很小, 完成websocket握手以及方案中发生的所有其他事情。 </ p>
</ div>

展开原文

原文

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.

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐