如何取消订阅 http 处理程序?

alp*_*pav 5 session http handler go unsubscribe

我想创建 http 处理程序来处理一个会话:

func init(){
    http.HandleFunc("/sess/215489598", func(w http.ResponseWriter, r *http.Request) {
        //do something
    })
}
Run Code Online (Sandbox Code Playgroud)

然后在会话结束(过期)时将其删除。

我怎样才能做到这一点 ?

Ada*_*erg 4

这不可能直接实现:HTTP 多路复用器(ServeMux 类型)不会公开删除操作。

使用 HTTP 多路复用器进行会话管理结果证明是一个坏主意。当前 HTTP 服务的实现效率较低。它会扫描整个多路复用器表中的每个 URL,因此处理程序越多,性能就越差。对于一些路径来说这很好,但是您甚至无法以这种方式管理数百个会话,更不用说数十万个会话了。

HTTP 多路复用器需要某种同步才能用作会话管理工具。想象一下有一个 Unhandle 方法。如果您取消处理路径,您会期望多路复用器不再使用其先前的数据处理您的路径。但是,如果没有某种同步,不同的 goroutine 不能保证看到彼此对相同数据的更改。因此,HTTP 处理程序仍然可以看到多路复用器的旧视图,然后使用您认为已取消注册的处理程序响应请求。

因此,HTTP 处理程序本身无法为您执行此操作,也不应该这样做,因为您没有任何方法来同步会话生命周期。

"/sess/". 该处理程序应负责委派给各个会话。它可以使用 amap[sessionID]sessionHandler来有效地做到这一点,并且可以通过通道管理所有会话管理,让单个 goroutine 跟踪正在创建和销毁的会话,或者采用更传统的方法,在会话映射周围使用读写器锁。这样,您可以确保在删除会话处理程序后不会尝试将新请求分派给会话处理程序。

当然,您可以随时收到 HTTP 请求,因此如果在您决定要执行操作后指令中发生上下文切换,那么在您锁定地图以删除会话之前,有人可能会跳入并连接到会话。在实际操作之前锁定地图,因此请仔细管理您的锁定和会话策略。这里要做的“正确的事情”主要取决于您个人应用程序的需求。

  • 如果您使用 Gorilla takeit,它不需要为每个请求扫描整个路由表。 (2认同)