package main import ( "context" "errors" "io/ioutil" "log" "net/http" "strings" "time" "git.wishpal.cn/wishpal_ironfan/xframe/base/conf" "git.wishpal.cn/wishpal_ironfan/xframe/component/queue/asynq" "git.wishpal.cn/wishpal_ironfan/xframe/component/storage/redis" "git.wishpal.cn/wishpal_ironfan/xframe/serving_base/http/frame" "git.wishpal.cn/wishpal_ironfan/xframe/serving_base/http/frame/ctrl" "git.wishpal.cn/wishpal_ironfan/xframe/serving_base/http/frame/errcode" ) func main() { ctx := context.Background() err := asynq.Init(ctx, &asynq.Config{ RedisConf: redis.RedisConf{ Host: "127.0.0.1:6379", Type: redis.NodeType, }, }) if err != nil { log.Fatal(err) } rds, err := redis.NewRedis(redis.RedisConf{ Host: "127.0.0.1:6379", Type: redis.NodeType, }) if err != nil { log.Fatal(err) } const configYaml = ` Name: foo Host: localhost Port: 8888 ` var cnf frame.RestConf err = conf.LoadFromYamlBytes([]byte(configYaml), &cnf) if err != nil { log.Fatal(err) } svr, err := frame.NewServer(cnf) if err != nil { log.Fatal(err) } svr.AddRoutes( []frame.Route{ { Method: http.MethodPost, Path: "/sync", Handler: func(w http.ResponseWriter, r *http.Request) { var req struct { Name string `json:"name"` Age int `json:"age"` } if err := ctrl.Parse(r, &req); err != nil { ctrl.ErrorCtx(r, w, errcode.Wrapf(errcode.FrameBadRequestError, "ctrl.Parse:%v", err)) return } log.Printf("[Handler] sync handler param:%+v", req) ctrl.OkJsonCtx(r, w, map[string]any{ "data": "sync_data", }) }, }, { Method: http.MethodPost, Path: "/auto_async", Async: true, Handler: func(w http.ResponseWriter, r *http.Request) { var req struct { Name string `json:"name"` Age int `json:"age"` } if err := ctrl.Parse(r, &req); err != nil { ctrl.ErrorCtx(r, w, errcode.Wrapf(errcode.FrameBadRequestError, "ctrl.Parse:%v", err)) return } time.Sleep(500 * time.Millisecond) val, _, err := rds.Helper().Get(r.Context(), "test_key").Result() if err != nil { log.Printf("redis get err:%v", err) } else { log.Printf("redis get success, val:%s", val) } log.Printf("[Handler] auto_async handler param:%+v", req) ctrl.OkJsonCtx(r, w, map[string]any{ "data": "auto_async_data", }) }, }, { Method: http.MethodPost, Path: "/case_fake_resp", Async: true, AsyncFakeResp: func(w http.ResponseWriter, r *http.Request) { ctrl.ErrorCtx(r, w, errors.New("fake resp error")) }, Handler: func(w http.ResponseWriter, r *http.Request) { var req struct { Name string `json:"name"` Age int `json:"age"` } if err := ctrl.Parse(r, &req); err != nil { ctrl.ErrorCtx(r, w, errcode.Wrapf(errcode.FrameBadRequestError, "ctrl.Parse:%v", err)) return } log.Printf("[Handler] case_fake_resp handler param:%+v", req) ctrl.OkJsonCtx(r, w, map[string]any{ "data": "case_fake_resp_data", }) }, }, }, frame.WithPrefix("/test"), ) // 启动异步模块,注意一定要在svr.AddRoutes之后执行,否则会发生task找不到对应handler的错误 err = asynq.Start() if err != nil { log.Fatal(err) } go func() { time.Sleep(5 * time.Second) request() }() svr.Start() } func request() { var ( client = &http.Client{} url = "http://127.0.0.1:8888" uriList = []string{"/test/auto_async", "/test/case_fake_resp", "/test/sync"} payloadList = []string{"{\"name\":\"zhangsan\",\"age\":18}", "{\"name\":\"lisi\",\"age\":19}", "{\"name\":\"wangwu\",\"age\":20}"} ) for idx, uri := range uriList { req, err := http.NewRequest(http.MethodPost, url+uri, strings.NewReader(payloadList[idx])) if err != nil { log.Fatal(err) } req.Header.Add("Content-Type", "application/json") res, err := client.Do(req) if err != nil { log.Fatal(err) } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { log.Fatal(err) } log.Printf("uri:%s, payload:%s, resp body:%s", uri, payloadList[idx], string(body)) } }