You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

hub_io.go 5.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. package cdsapi
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "mime/multipart"
  7. "net/http"
  8. "net/url"
  9. "strings"
  10. "gitlink.org.cn/cloudream/common/consts/errorcode"
  11. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec"
  12. "gitlink.org.cn/cloudream/common/utils/http2"
  13. "gitlink.org.cn/cloudream/common/utils/serder"
  14. )
  15. // TODO2 重新梳理代码
  16. const GetStreamPath = "/hubIO/getStream"
  17. type GetStreamReq struct {
  18. PlanID exec.PlanID `json:"planID"`
  19. VarID exec.VarID `json:"varID"`
  20. SignalID exec.VarID `json:"signalID"`
  21. Signal exec.VarValue `json:"signal"`
  22. }
  23. func (c *Client) GetStream(planID exec.PlanID, id exec.VarID, signalID exec.VarID, signal exec.VarValue) (io.ReadCloser, error) {
  24. targetUrl, err := url.JoinPath(c.baseURL, GetStreamPath)
  25. if err != nil {
  26. return nil, err
  27. }
  28. req := &GetStreamReq{
  29. PlanID: planID,
  30. VarID: id,
  31. SignalID: signalID,
  32. Signal: signal,
  33. }
  34. resp, err := http2.GetJSON(targetUrl, http2.RequestParam{
  35. Body: req,
  36. })
  37. if err != nil {
  38. return nil, err
  39. }
  40. if resp.StatusCode != http.StatusOK {
  41. // 读取错误信息
  42. body, _ := io.ReadAll(resp.Body)
  43. resp.Body.Close()
  44. return nil, fmt.Errorf("error response from server: %s", string(body))
  45. }
  46. return resp.Body, nil
  47. }
  48. const SendStreamPath = "/hubIO/sendStream"
  49. type SendStreamReq struct {
  50. PlanID exec.PlanID `json:"planID"`
  51. VarID exec.VarID `json:"varID"`
  52. Stream io.ReadCloser `json:"stream"`
  53. }
  54. func (c *Client) SendStream(planID exec.PlanID, varID exec.VarID, str io.Reader) error {
  55. targetUrl, err := url.JoinPath(c.baseURL, SendStreamPath)
  56. if err != nil {
  57. return err
  58. }
  59. body := &bytes.Buffer{}
  60. writer := multipart.NewWriter(body)
  61. _ = writer.WriteField("plan_id", string(planID))
  62. _ = writer.WriteField("var_id", string(rune(varID)))
  63. fileWriter, err := writer.CreateFormFile("file", "data")
  64. if err != nil {
  65. return fmt.Errorf("creating form file: %w", err)
  66. }
  67. // 将读取的数据写入 multipart 的文件部分
  68. _, err = io.Copy(fileWriter, str)
  69. if err != nil {
  70. return fmt.Errorf("copying stream data: %w", err)
  71. }
  72. // 关闭 writer 以结束 multipart
  73. err = writer.Close()
  74. if err != nil {
  75. return fmt.Errorf("closing writer: %w", err)
  76. }
  77. // 创建 HTTP 请求
  78. req, err := http.NewRequest("POST", targetUrl, body)
  79. if err != nil {
  80. return fmt.Errorf("creating HTTP request: %w", err)
  81. }
  82. req.Header.Set("Content-Type", writer.FormDataContentType())
  83. // 发送请求
  84. cli := http.Client{}
  85. resp, err := cli.Do(req)
  86. if err != nil {
  87. return fmt.Errorf("sending HTTP request: %w", err)
  88. }
  89. defer resp.Body.Close()
  90. // 检查响应状态码
  91. if resp.StatusCode != http.StatusOK {
  92. return fmt.Errorf("server returned non-200 status: %d", resp.StatusCode)
  93. }
  94. return nil
  95. }
  96. const ExecuteIOPlanPath = "/hubIO/executeIOPlan"
  97. type ExecuteIOPlanReq struct {
  98. Plan exec.Plan `json:"plan"`
  99. }
  100. func (c *Client) ExecuteIOPlan(plan exec.Plan) error {
  101. targetUrl, err := url.JoinPath(c.baseURL, ExecuteIOPlanPath)
  102. if err != nil {
  103. return err
  104. }
  105. req := &ExecuteIOPlanReq{
  106. Plan: plan,
  107. }
  108. resp, err := http2.PostJSON(targetUrl, http2.RequestParam{
  109. Body: req,
  110. })
  111. if err != nil {
  112. return err
  113. }
  114. contType := resp.Header.Get("Content-Type")
  115. if strings.Contains(contType, http2.ContentTypeJSON) {
  116. var codeResp response[any]
  117. if err := serder.JSONToObjectStream(resp.Body, &codeResp); err != nil {
  118. return fmt.Errorf("parsing response: %w", err)
  119. }
  120. if codeResp.Code == errorcode.OK {
  121. return nil
  122. }
  123. return codeResp.ToError()
  124. }
  125. return fmt.Errorf("unknow response content type: %s", contType)
  126. }
  127. const SendVarPath = "/hubIO/sendVar"
  128. type SendVarReq struct {
  129. PlanID exec.PlanID `json:"planID"`
  130. VarID exec.VarID `json:"varID"`
  131. VarValue exec.VarValue `json:"varValue"`
  132. }
  133. func (c *Client) SendVar(planID exec.PlanID, id exec.VarID, value exec.VarValue) error {
  134. targetUrl, err := url.JoinPath(c.baseURL, SendVarPath)
  135. if err != nil {
  136. return err
  137. }
  138. req := &SendVarReq{
  139. PlanID: planID,
  140. VarID: id,
  141. VarValue: value,
  142. }
  143. resp, err := http2.PostJSON(targetUrl, http2.RequestParam{
  144. Body: req,
  145. })
  146. if err != nil {
  147. return err
  148. }
  149. contType := resp.Header.Get("Content-Type")
  150. if strings.Contains(contType, http2.ContentTypeJSON) {
  151. var codeResp response[any]
  152. if err := serder.JSONToObjectStream(resp.Body, &codeResp); err != nil {
  153. return fmt.Errorf("parsing response: %w", err)
  154. }
  155. if codeResp.Code == errorcode.OK {
  156. return nil
  157. }
  158. return codeResp.ToError()
  159. }
  160. return fmt.Errorf("unknow response content type: %s", contType)
  161. }
  162. const GetVarPath = "/hubIO/getVar"
  163. type GetVarReq struct {
  164. PlanID exec.PlanID `json:"planID"`
  165. VarID exec.VarID `json:"varID"`
  166. SignalID exec.VarID `json:"signalID"`
  167. Signal exec.VarValue `json:"signal"`
  168. }
  169. func (c *Client) GetVar(id exec.PlanID, varID exec.VarID, singalID exec.VarID, signal exec.VarValue) (exec.VarValue, error) {
  170. targetUrl, err := url.JoinPath(c.baseURL, GetVarPath)
  171. if err != nil {
  172. return nil, err
  173. }
  174. req := &GetVarReq{
  175. PlanID: id,
  176. VarID: varID,
  177. SignalID: singalID,
  178. Signal: signal,
  179. }
  180. resp, err := http2.GetJSON(targetUrl, http2.RequestParam{
  181. Body: req,
  182. })
  183. if err != nil {
  184. return nil, err
  185. }
  186. body, _ := io.ReadAll(resp.Body)
  187. if resp.StatusCode != http.StatusOK {
  188. // 读取错误信息
  189. resp.Body.Close()
  190. return nil, fmt.Errorf("error response from server: %s", string(body))
  191. }
  192. return nil
  193. }