package api import ( "fmt" "io" "net/url" "gitlink.org.cn/cloudream/common/consts/errorcode" "gitlink.org.cn/cloudream/common/utils/http2" "gitlink.org.cn/cloudream/common/utils/io2" "gitlink.org.cn/cloudream/common/utils/serder" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch/exec" ) const GetStreamPath = "/hubIO/getStream" type GetStreamReq struct { PlanID exec.PlanID `json:"planID"` VarID exec.VarID `json:"varID"` SignalID exec.VarID `json:"signalID"` Signal exec.VarValue `json:"signal"` } func (c *Client) GetStream(req GetStreamReq) (io.ReadCloser, error) { targetUrl, err := url.JoinPath(c.cfg.URL, GetStreamPath) if err != nil { return nil, err } body, err := serder.ObjectToJSONEx(req) if err != nil { return nil, fmt.Errorf("request to json: %w", err) } resp, err := http2.GetJSON(targetUrl, http2.RequestParam{ Body: body, }) if err != nil { return nil, err } cr := http2.NewChunkedReader(resp.Body) _, str, err := cr.NextPart() if err != nil { return nil, fmt.Errorf("reading response: %w", err) } return io2.DelegateReadCloser(str, func() error { cr.Close() return nil }), nil } const SendStreamPath = "/hubIO/sendStream" type SendStreamReq struct { SendStreamInfo Stream io.ReadCloser } type SendStreamInfo struct { PlanID exec.PlanID `json:"planID"` VarID exec.VarID `json:"varID"` } func (c *Client) SendStream(req SendStreamReq) error { targetUrl, err := url.JoinPath(c.cfg.URL, SendStreamPath) if err != nil { return err } pr, pw := io.Pipe() errCh := make(chan error, 1) go func() { cw := http2.NewChunkedWriter(pw) infoJSON, err := serder.ObjectToJSONEx(req) if err != nil { cw.Abort(fmt.Sprintf("info to json: %v", err)) errCh <- fmt.Errorf("info to json: %w", err) return } if err := cw.WriteDataPart("info", infoJSON); err != nil { cw.Close() errCh <- fmt.Errorf("write info: %w", err) return } _, err = cw.WriteStreamPart("stream", req.Stream) if err != nil { cw.Close() errCh <- fmt.Errorf("write stream: %w", err) return } err = cw.Finish() if err != nil { errCh <- fmt.Errorf("finish chunked writer: %w", err) return } }() resp, err := http2.PostChunked2(targetUrl, http2.Chunked2RequestParam{ Body: pr, }) if err != nil { return err } err = <-errCh if err != nil { return err } codeResp, err := ParseJSONResponse[response[any]](resp) if err != nil { return err } if codeResp.Code == errorcode.OK { return nil } return codeResp.ToError() } const ExecuteIOPlanPath = "/hubIO/executeIOPlan" type ExecuteIOPlanReq struct { Plan exec.Plan `json:"plan"` } type ExecuteIOPlanResp struct { Result exec.ExecutorResult `json:"result"` } func (c *Client) ExecuteIOPlan(req ExecuteIOPlanReq) (*ExecuteIOPlanResp, error) { targetUrl, err := url.JoinPath(c.cfg.URL, ExecuteIOPlanPath) if err != nil { return nil, err } body, err := serder.ObjectToJSONEx(req) if err != nil { return nil, fmt.Errorf("request to json: %w", err) } resp, err := http2.PostJSON(targetUrl, http2.RequestParam{ Body: body, }) if err != nil { return nil, err } codeResp, err := ParseJSONResponse[response[ExecuteIOPlanResp]](resp) if err != nil { return nil, err } if codeResp.Code == errorcode.OK { return &codeResp.Data, nil } return nil, codeResp.ToError() } const SendVarPath = "/hubIO/sendVar" type SendVarReq struct { PlanID exec.PlanID `json:"planID"` VarID exec.VarID `json:"varID"` VarValue exec.VarValue `json:"varValue"` } func (c *Client) SendVar(req SendVarReq) error { targetUrl, err := url.JoinPath(c.cfg.URL, SendVarPath) if err != nil { return err } body, err := serder.ObjectToJSONEx(req) if err != nil { return fmt.Errorf("request to json: %w", err) } resp, err := http2.PostJSON(targetUrl, http2.RequestParam{ Body: body, }) if err != nil { return err } jsonResp, err := ParseJSONResponse[response[any]](resp) if err != nil { return err } if jsonResp.Code == errorcode.OK { return nil } return jsonResp.ToError() } const GetVarPath = "/hubIO/getVar" type GetVarReq struct { PlanID exec.PlanID `json:"planID"` VarID exec.VarID `json:"varID"` SignalID exec.VarID `json:"signalID"` Signal exec.VarValue `json:"signal"` } type GetVarResp struct { Value exec.VarValue `json:"value"` } func (c *Client) GetVar(req GetVarReq) (*GetVarResp, error) { targetUrl, err := url.JoinPath(c.cfg.URL, GetVarPath) if err != nil { return nil, err } body, err := serder.ObjectToJSONEx(req) if err != nil { return nil, fmt.Errorf("request to json: %w", err) } resp, err := http2.GetJSON(targetUrl, http2.RequestParam{ Body: body, }) if err != nil { return nil, err } jsonResp, err := ParseJSONResponse[response[GetVarResp]](resp) if err != nil { return nil, err } if jsonResp.Code == errorcode.OK { return &jsonResp.Data, nil } return nil, jsonResp.ToError() }