package fusenrender import ( "context" "encoding/json" "fmt" "io" "log" "net/http" "time" "github.com/gorilla/websocket" "github.com/lni/dragonboat/v4" ) var UidCreater = NewUniqueId(1) var PopChannel chan []byte = make(chan []byte, 3) // chan *QueueItem = make(chan *QueueItem, 1) var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, } func HttpStart(ns *dragonboat.NodeHost, port int) { http.HandleFunc("/api/queue/push", pushRenderTaskHandler) http.HandleFunc("/ws/pop/queue", queueHandler) http.HandleFunc("/ws/callback", callbackHandler) log.Printf(":%d", port) http.ListenAndServe(fmt.Sprintf(":%d", port), nil) } func queueHandler(w http.ResponseWriter, r *http.Request) { var err error conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println(err) return } defer conn.Close() log.Println("建立连接", DequeueHandler.RefCountAdd(1)) defer func() { log.Println("退出连接", DequeueHandler.RefCountAdd(-1)) }() for { // msgType, msg, err := conn.ReadMessage() // if err != nil { // log.Println(msgType, msg, err) // return // } itemdata := <-PopChannel // 写回消息 err = conn.WriteMessage(websocket.BinaryMessage, itemdata) if err != nil { log.Println(err) var item QueueItem err = item.Decode(itemdata) if err != nil { log.Println(err) return } log.Println("重新回队") stateClient.PushItem(&item) return } // 打印消息 fmt.Printf("%s len=%d sent: \n ", conn.RemoteAddr(), len(itemdata)) // 读取消息 // msgType, msg, err := conn.ReadMessage() // if err != nil { // log.Println(msgType, msg, err) // return // } } } func callbackHandler(w http.ResponseWriter, r *http.Request) { conn, _ := upgrader.Upgrade(w, r, nil) for { // 读取消息 msgType, msg, err := conn.ReadMessage() if err != nil { return } // 打印消息 fmt.Printf("%s sent: %s\n", conn.RemoteAddr(), string(msg)) // 写回消息 err = conn.WriteMessage(msgType, msg) if err != nil { return } } } func pushRenderTaskHandler(w http.ResponseWriter, r *http.Request) { // 1. 读取Body内容 body, err := io.ReadAll(r.Body) if err != nil { panic(err) } // 2. 定义结构体 item := QueueItem{} // 3. 解析JSON到结构体 err = json.Unmarshal(body, &item) if err != nil { panic(err) } stateClient.PushItem(&item) } type StateClient struct { nh *dragonboat.NodeHost } var stateClient *StateClient func (cli *StateClient) PushItem(item *QueueItem) { cs := cli.nh.GetNoOPSession(128) cmd := &CmdEnqueue{Command: Command{Group: "test"}} cmd.Item = item data, err := FsPasser.PackToBytes(cmd) if err != nil { log.Println(err) } ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) _, err = cli.nh.SyncPropose(ctx, cs, data) if err != nil { log.Println(err) } // log.Println("enqueue", len(result.Data)) cancel() }