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

时间:2013-04-10 03:03:52

标签: http session go handler unsubscribe

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

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

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

我该怎么做?

2 个答案:

答案 0 :(得分:4)

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

使用HTTP多路复用器进行会话管理是一个坏主意。 HTTP服务的当前实现是kind of inefficient.它扫描整个多路复用器表中的每个URL,因此您拥有的处理程序越多,性能就越差。对于一些路径来说这很好,但你不能用这种方式管理几百个会话,更不用说数十万个了。

HTTP多路复用器需要某种同步才能用作会话管理工具。想象一下,有一种Unhandle方法。如果您取消处理路径,您可能希望多路复用器不再使用其先前的数据处理路径。但是,不同的goroutine aren't guaranteed to see each other's changes to the same data without some kind of synchronization.因此,HTTP处理程序仍然可以看到多路复用器的旧视图,然后使用您认为已取消注册的处理程序来响应请求。

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

"/sess/"创建一个处理程序。该处理程序应负责委派给各个会话。它可以使用map[sessionID]sessionHandler来有效地执行此操作,并且可以通过通道管道所有会话管理,让单个goroutine跟踪正在创建和销毁的会话,或者使用更常规的方法使用读写器锁定你的会话地图。这样,您可以确保在删除会话处理程序后不会尝试将新请求分派给会话处理程序。

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

答案 1 :(得分:2)

我担心golang http包没有实现删除或修改http处理程序的方法,请阅读:

src/pkg/net/http/server.go

http://golang.org/src/pkg/net/http/server.go?s=28409:28496#L962

type ServeMux
func NewServeMux() *ServeMux
func (mux *ServeMux) Handle(pattern string, handler Handler)
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request)

它刚刚实现了寄存器功能HandleFunc()

您有两种解决方法:

1修改源代码以实现取消注册功能。这是不可取的,因为直接使用ServerMux不是一个好主意。

或者:

2也许你让事情变得更加复杂。您只需在常规处理函数中解析/sess/215489598,例如:

func Handler(response http.ResponseWriter, request *http.Request) {
  modules := strings.Split(request.URL.Path, "/")

  if modules[1] == "sess" {
    session_id := modules[2]
  }
}

然后你知道下一步该怎么做:)

相关问题