如何在net / http中取消注册处理程序? [英] How do I unregister a Handler in net/http?

查看:89
本文介绍了如何在net / http中取消注册处理程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个web服务器,我需要在运行时注册处理程序。例如。 / create会为所有网址创建一个新的处理程序,如/ 123 / *等等。我需要一个相应的/ destroy / 123来取消注册/ 123 / *的处理程序。



这里是处理/ create的代码

 包主
导入(
fmt
净/ http


类型MyHandler结构{
id int
}
func(hf * MyHandler)ServeHTTP(w http.ResponseWriter,r * http.Request){
fmt.Fprintln(w,r.URL.Path)
}

//创建MyHandler实例并在运行时将它们注册为处理程序
类型HandlerFactory struct {
handler_id int
$ b $ func(hf * HandlerFactory)ServeHTTP(w http.ResponseWriter,r * http.Request){
hf.handler_id ++
handler:= MyHandler {hf.handler_id }
句柄:= fmt.Sprintf(/%d /,hf.handler_id)
http.Handle(句柄&处理程序)
}

func main(){
factory:= HandlerFactory {0}
http.Handle(/ create,& factory)
http.ListenAndServe(localhost:8080,nil)
}

我试图通过嵌入 http.ServeMux 来实现自己的多路复用器,但它在一个私有变量( ServeMux.m )中保存了它的模式到处理器的映射。

解决方案

我会做的是创建一个自定义 ServerMux 。从 GOROOT / src / pkg / net / http / server.go 复制代码。它从837行开始,到939结束。

自定义的ServerMux需要一种注销方法。这应该很容易实现。只需抓住锁和 del()地图项即可。例如(所有代码都未经测试):

  // TODO:检查是否已注册,如果没有则返回错误。 
// TODO:可能删除/ dir和/ dir /之间的自动永久链接。
func(mux * MyMux)注销(模式字符串)错误{
mux.mu.Lock()
推迟mux.mu.Unlock()
del(mux.m,模式)
返回零
}

为了使用这个新的多路复用器,你可以这样做:

  mux:= newMux()
mux.Handle(/ create, & factory)

srv:=& http.Server {
Addr:localhost:8080
Handler:mux,
}
srv.ListenAndServe ()

通过调用 deregister()从另一个goroutine是完全安全的,并将修改 ListenAndServe()路由消息的方式。


I am writing a web server wherein I need to register handlers at runtime. E.g. "/create" would create a new handler for all URLs like "/123/*" and so on. I need a corresponding "/destroy/123" which would unregister the handler for "/123/*".

Here's the code for handling "/create"

package main
import (
    "fmt"
    "net/http"
)

type MyHandler struct {
    id int
}
func (hf *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, r.URL.Path)
}

// Creates MyHandler instances and registers them as handlers at runtime
type HandlerFactory struct {
    handler_id int
}
func (hf *HandlerFactory) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    hf.handler_id++
    handler := MyHandler{hf.handler_id}
    handle := fmt.Sprintf("/%d/", hf.handler_id)
    http.Handle(handle, &handler)
}

func main() {
    factory := HandlerFactory{0}
    http.Handle("/create", &factory)
    http.ListenAndServe("localhost:8080", nil)
}

I tried implementing my own multiplexer by embedding http.ServeMux but it holds its pattern-to-Handler mapping in a private variable (ServeMux.m)

解决方案

What I would do is create a custom ServerMux. Copy the code from GOROOT/src/pkg/net/http/server.go. It starts on line 837 and ends at 939.

The custom ServerMux would need a method for deregistration. This should be easy to implement. Just grab the lock and del() the map entry. For example (all code untested):

// TODO: check if registered and return error if not.
// TODO: possibly remove the automatic permanent link between /dir and /dir/.
func (mux *MyMux) Deregister(pattern string) error {
    mux.mu.Lock()
    defer mux.mu.Unlock()
    del(mux.m, pattern)
    return nil
}

In order to use this new mux, you would do something like this:

mux := newMux()
mux.Handle("/create", &factory)

srv := &http.Server {
    Addr: localhost:8080
    Handler: mux,
}
srv.ListenAndServe()

Modifying mux by calling deregister() from another goroutine is completely safe and will modify the way ListenAndServe() routes messages.

这篇关于如何在net / http中取消注册处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆