问题

在使用beego构建带有database的Http server的时候遇到如下问题

  1. 需要从前端(Unity)处传输一个png格式的图片到后端,并将其存储在数据库里;
  2. 前端向后端发送HTTP GET请求的时候,需要同时传输一个json和多张png格式的图片

调研

C#读取PNG文件,并通过HTTP POST请求上传到服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var fileAddress = Path.Combine(Application.streamingAssetsPath, "Screenshots/Screenshot.png");
FileInfo fInfo0 = new FileInfo(fileAddress);
if (fInfo0.Exists)
{
var content = new MultipartFormDataContent();
content.Add(new ByteArrayContent(File.ReadAllBytes(fileAddress)), "screenshot", "Screenshot.png");
HttpResponseMessage response = await client.PostAsync(backendUrl, content);
string responseString = await response.Content.ReadAsStringAsync();
}
else
{
Debug.Log("No");
return;
}

关键函数

File.ReadAllBytes(fileAddress)): fileAddress是文件的地址,返回值为byte数组;

content.Add(new ByteArrayContent(byte[], "file", "filename"): 该函数用于将文件贴进http request body,其中第一个参数为文件的字节流,第二个参数相当于文件的一个唯一标志,在接受的时候也需要用该参数进行接受(在后面使用golang接收文件的时候有所体现),第三个参数表示接收到文件的时候的文件名;

client.PostAsync(backendUrl, content): 该函数用于发起post请求,client为HttpClient类型的对象,第一个参数为URL,第二个参数为HttpContent,包含了所有类型的request body

Unity设置Image组件的背景图片

1
ImageComponent.sprite = Resources.Load<Sprite>("filename");

ImageComponet即为Image组件,Resources.Load加载的资源均位于文件夹"Asserts/Resources"下

Golang接收Post请求传过来的文件

1
2
3
4
5
6
7
file, _, err := ctrl.GetFile("screenshot")
if err != nil {
fmt.Print("File retrieval failure")
} else{
defer file.Close()
_ = ctrl.SaveToFile("screenshot", "Screenshot.png")
}

关键函数

GetFile: 该函数用于获取Post所带的文件,注意这里的参数就是上文C#中content.Add函数的第二个参数;

SaveToFile: 该函数用于存储文件,第一个参数是上文C#中content.Add函数的第二个参数,第二个参数表示文件存储位置和名称,基础位置为项目文件夹的根目录;

解决方法

根据Beego的特性,其无法直接向数据库中存储BLOB格式的二进制数据,所以最终考虑直接存储在服务器端,采用唯一数字标识图片。在Get请求的传输过程中,采用将图片转化成byte数组,和之前的数据json合并,然后再传输过去,这样就只需要在客户端处处理byte数组,将起转化为图片即可。

1
2
3
4
Texture2D texture = new Texture2D(1024, 1024);
texture.LoadImage(byteArray);
Sprite prite = Sprite.Create(texture, new Rect(0, 0, 800, 531), new Vector2(0.5f, 0.5f));
ImageComponent.sprite = prite;

此处并不需要先将byte数组转化成图片保存下来,再load进image组件;我们只需要将byte数组读进Texture2D,然后转化成Sprite对象即可。