golang 动态修改http handle路由注册

router代码 第一种

import (
	"net/http"
	"sync"
)

type Server struct {
	mu       sync.RWMutex
	handlers map[string]http.Handler
}

func NewServer() *Server {
	return &Server{
		handlers: make(map[string]http.Handler),
	}
}

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.mu.RLock()
	handler, ok := s.handlers[r.URL.Path]
	s.mu.RUnlock()

	if !ok {
		http.NotFound(w, r)
		return
	}

	handler.ServeHTTP(w, r)
}

func (s *Server) Handle(path string, handler http.Handler) {
	s.mu.Lock()
	s.handlers[path] = handler
	s.mu.Unlock()
}

应用

func main() {
    mux := NewServer()

    // 注册初始处理器
    mux.Handle("/path", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Initial handler")
    }))

    go func() {
        // 在另一个 goroutine 中修改处理器
        time.Sleep(10 * time.Second)

        mux.Handle("/path", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintln(w, "Updated handler")
        }))
    }()

    log.Fatal(http.ListenAndServe(":8080", mux))
}

router代码 第二种

package main

import (
	"net/http"
	"os"
	"path/filepath"
	"sync"
	"regexp"
	"github.com/mholt/archiver/v3"
)

type Server struct {
	mux  *http.ServeMux
	lock sync.RWMutex
}

func NewServer() *Server {
	return &Server{
		mux: http.NewServeMux(),
	}
}

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.lock.RLock()
	defer s.lock.RUnlock()

	s.mux.ServeHTTP(w, r)
}
var re = regexp.MustCompile(`^([^\.]*)`)
func (s *Server) LoadStaticWebHttpHandle(savePath, fixedPrefix string, urlPrefixAndFilepath map[string]string) error {
	s.lock.Lock()
	defer s.lock.Unlock()

	newMux := http.NewServeMux()
	pathA := filepath.Join(savePath, "A")
	pathB := filepath.Join(savePath, "B")
	if !util.Exists(pathA) {
		savePath = pathA
	} else {
		savePath = pathB
	}
	for prefix, file_path := range urlPrefixAndFilepath {
		// file_path 需要跟执行文件同个根目录下
		err := archiver.Unarchive(file_path, savePath)
		if err != nil {
			return fmt.Errorf("archiveFile failed, err: %v", err)
		}
		newPrefix := fixedPrefix + prefix
		prefix_archive_name := re.FindString(file_path)
		newMux.Handle(newPrefix, http.StripPrefix(newPrefix, http.FileServer(http.Dir(filepath.Join(savePath, prefix_archive_name)))))
	}
	if savePath != pathA {
		os.RemoveAll(pathA)
	} else {
		os.RemoveAll(pathB)
	}
	s.mux = newMux
	return nil
}

应用
func main() {
	s := NewServer()
	s.LoadStaticWebHttpHandle("static-path", "/url_prefix", map[string]string{"static": "test.zip"})
	laddr := "127.0.0.1:8080"
	svr := http.Server{Addr: laddr, Handler: http.TimeoutHandler(http.DefaultServeMux, 600*time.Second, "server timeout"), ReadTimeout: 600 * time.Second, WriteTimeout: 600 * time.Second}
	err = svr.ListenAndServe()
	if err != nil {
		log.Errorf("%v", err)
	}
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值