登录
首页 >  Golang >  Go问答

提升多网络请求效率

来源:stackoverflow

时间:2024-02-28 20:06:24 414浏览 收藏

“纵有疾风来,人生不言弃”,这句话送给正在学习Golang的朋友们,也希望在阅读本文《提升多网络请求效率》后,能够真的帮助到大家。我也会在后续的文章中,陆续更新Golang相关的技术文章,有好的建议欢迎大家在评论留言,非常感谢!

问题内容

我使用 python tornado 库制作了一个模型服务服务器,其唯一目的是接受带有负载的 http 请求并以 json 形式返回结果。可以使用 application/jsonmultipart/form-data 发出请求。

为了对用户进行身份验证和授权,我使用 golang echo 库创建了另一台服务器。因此所有用户请求都应该在到达我的资源服务器之前到达这里。

这里我有一个问题,因为我的程序需要图像作为输入,所以用户将使用 formdata 发送他们的请求。当它第一次到达我的 golang 服务器时,我需要执行以下步骤

  1. 阅读表单文件。
  2. 保存到本地磁盘。
  3. 加载文件并将其保存在字节缓冲区中。
  4. 初始化多部分编写器
  5. 向我的资源服务器发出请求
  6. 得到结果,返回给用户

我觉得这是多余的,因为我想象有一种方法可以将这些请求直接传播到我的资源服务器(在身份验证完成后),而不必通过 i/o 部分。

我的代码目前看起来像这样,此时身份验证是通过中间件完成的。有没有办法优化这个流程?

func (h Handler) ProcessFormData(c echo.Context) error {

    // some validation

    file, err := c.FormFile("file")
    if err != nil {
        return c.JSON(http.StatusBadRequest, response.Exception{
            Code:   errcode.InvalidRequest,
            Detail: "Invalid file uploaded",
            Error:  err,
        })
    }

    filePath, err := fileUtil.SaveNetworkFile(file)
    if err != nil {
        return c.JSON(http.StatusInternalServerError, response.Exception{
            Code:   errcode.SystemError,
            Detail: "Error when processing file",
            Error:  err,
        })
    }

    f, err := os.Open(filePath)
    if err != nil {
        return c.JSON(http.StatusInternalServerError, response.Exception{
            Code:   errcode.SystemError,
            Detail: "Error when processing file",
            Error:  err,
        })
    }
    defer f.Close()

    fi, err := f.Stat()
    if err != nil {
        return c.JSON(http.StatusInternalServerError, response.Exception{
            Code:   errcode.SystemError,
            Detail: "Error when processing file",
            Error:  err,
        })
    }

    var body bytes.Buffer
    writer := multipart.NewWriter(&body)
    part, err := writer.CreateFormFile("file", fi.Name())
    if err != nil {
        return c.JSON(http.StatusInternalServerError, response.Exception{
            Code:   errcode.SystemError,
            Detail: "Error when processing file",
            Error:  err,
        })
    }

    if _, err := io.Copy(part, f); err != nil {
        return c.JSON(http.StatusInternalServerError, response.Exception{
            Code:   errcode.SystemError,
            Detail: "Error when processing file",
            Error:  err,
        })
    }
    writer.Close()

    req, err := http.NewRequest("POST", fmt.Sprintf("%s", env.ResourceServer), &body)
    req.Header.Set("Content-Type", writer.FormDataContentType())
    if err != nil {
        return c.JSON(http.StatusInternalServerError, response.Exception{
            Code:  errcode.APIRequestError,
            Error: err,
        })
    }

    client := &http.Client{}
    res, err := client.Do(req)
    if err != nil {
        return c.JSON(http.StatusInternalServerError, response.Exception{
            Code:   errcode.APIRequestError,
            Detail: "Error when posting request to resource server",
            Error:  err,
        })
    }

    defer res.Body.Close()

    data, _ := ioutil.ReadAll(res.Body)

    if res.StatusCode != 200 {
        errorData := &model.PanicResponse{}
        err := json.Unmarshal(data, errorData)
        if err != nil {
            return c.JSON(http.StatusInternalServerError, response.Exception{
                Code:  errcode.UnmarshalError,
                Error: err,
            })
        }

        return c.JSON(res.StatusCode, errorData)
    }

    result := &model.SuccessResponse{}
    err = json.Unmarshal(data, result)
    if err != nil {
        return c.JSON(http.StatusInternalServerError, response.Exception{
            Code:  errcode.UnmarshalError,
            Error: err,
        })
    }

    if fileUtil.IsFileExists(filePath) {
        fileUtil.DeleteFile(filePath)
    }

    // track and update usage
    userData := c.Get("USER")
    user := userData.(model.User)
    db.UpdateUsage(h.Db, &user.ID)

    return c.JSON(200, result)
}

解决方案


感谢 @cerise-limón 的评论找到了解决方案

本质上,我只需要 2 行

f, err := file.Open()
if _, err := io.Copy(part, f); err != nil {
    return c.JSON(http.StatusInternalServerError, response.Exception{
        Code:   errcode.SystemError,
        Detail: "Error when processing file",
    })
}

终于介绍完啦!小伙伴们,这篇关于《提升多网络请求效率》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>