我想创建一个HTTP处理程序来处理一个会话:
func init(){
http.HandleFunc("/sess/215489598", func(w http.ResponseWriter, r *http.Request) {
//do something
})
}
当会话结束(过期)时,需要将其删除。
我该怎么做?
我想创建一个HTTP处理程序来处理一个会话:
func init(){
http.HandleFunc("/sess/215489598", func(w http.ResponseWriter, r *http.Request) {
//do something
})
}
当会话结束(过期)时,需要将其删除。
我该怎么做?
这是不可能直接实现的:HTTP多路复用器(ServeMux类型)没有暴露删除操作。
使用HTTP多路复用器进行会话管理最终证明是个坏主意。当前的HTTP服务实现相当低效。它为每个URL扫描整个多路复用器表格,所以处理程序越多,性能就越差。对于一些路径来说还好,但你不能以这种方式管理几百个甚至数十万个会话。
HTTP多路复用器需要某种同步才能用作会话管理工具。想象一下有一个Unhandle方法。如果你取消处理某个路径,你希望多路复用器不再使用其先前的数据处理该路径。但是,不同的goroutine在没有某种同步的情况下无法看到彼此对同一数据所做的更改。因此,HTTP处理程序仍然可以看到多路复用器的旧视图,然后使用你认为已经注销的处理程序响应请求。
因此,HTTP处理程序本身无法为您执行此操作,也不应该这样做,因为您没有任何手段来同步会话的生命周期。"/sess/"
的单个处理程序。 该处理程序应负责委派到各个会话。 它可以使用map [sessionID] sessionHandler
来高效地执行此操作,并且可以通过管道将所有会话管理交给单个goroutine来跟踪被创建和销毁的会话,或者根据读写锁的传统方法使用会话映射。 这样,您可以确保在删除会话处理程序后不会尝试分派新请求到它。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]
}
}