Unity对接接口丨简单教学丨UnityWebRequest

news2024/9/30 7:30:01

新手制作接口对接

  • 前言
  • 使用过程
    • Postman测试
    • 第一次测试
    • 第二次测试
    • 第三次测试
    • 第四次测试
    • 第五次测试
    • 第六次测试
  • 总结

前言

提示:大体介绍今日功能介绍
介绍大概UnityWebRequest对接接口方式,博主也是作为刚开始对接口的使用,相当详细。

使用过程

这里为内容大体走向介绍
本文尝试过多种方式,每次修改都有小的收货,希望可以帮助到大家就是了
本文的目标是达到使用Postman的效果,可以拿到回来的数据。
(众所周知postman是一个跑接口的软件非常好用)

Postman测试

  • 本文首先尝试使用Postman
  • 非常明显可见我们的Postman使用需要两个Key分别是一个图片数据一个String数据
  • 其中图片数据接口端需要接收的是Byte数据
    在这里插入图片描述* 正常跑通没问题(因为写博客的时候我们的接口已经不允许我操作了,所以我没有成功截图)

第一次测试

  • 首先我们的代码使用的是
 public void SendForm()
    {
        byte[] myData = System.Text.Encoding.UTF8.GetBytes("Sample Data");
        string myString = "Sample String";

        StartCoroutine(PostRequest("https://www.example.com/api/submitform", myData, myString));
    }

    IEnumerator PostRequest(string url, byte[] data, string formData)
    {
        UnityWebRequest www = new UnityWebRequest(url, "POST");
        UploadHandlerRaw uploadHandler = new UploadHandlerRaw(data);
        uploadHandler.contentType = "application/octet-stream";
        www.uploadHandler = uploadHandler;

        Dictionary<string, string> headers = new Dictionary<string, string>();
        headers.Add("Content-Type", "application/x-www-form-urlencoded");
        byte[] formBytes = System.Text.Encoding.UTF8.GetBytes(formData);
        www.uploadHandler.data = formBytes;
        www.SetRequestHeader("Content-Length", formBytes.Length.ToString());

        yield return www.SendWebRequest();

        if (www.isNetworkError || www.isHttpError)
        {
            Debug.Log(www.error);
        }
        else
        {
            Debug.Log(www.downloadHandler.text);
        }
    }
  • 这种方法,完全不可以使用,完全在写的这种方法适合我们的只接收两个数据的接口比较合适,并且所有的数据最终都是也byte方式发送过去,当然也并不是这种接口完全就不能用,只是不适合我们本文中的选择罢了。

第二次测试

  • 这次尝试直接重构了使用方式
byte[] data1 = new byte[10];
byte[] data2 = new byte[20];

WWWForm form = new WWWForm();
form.AddField("stringKey1", "stringValue1");
form.AddBinaryData("byteArrayKey1", data1);
form.AddBinaryData("byteArrayKey2", data2);

UnityWebRequest request = UnityWebRequest.Post("your_url", form);
request.SetRequestHeader("Content-Type", "multipart/form-data");
request.SendWebRequest();
  • 本文也非常简单,适合挺多的接口对接的方式
  • 像是AddBinaryData这种方式可以直接传输一个Key一个byte的value数据
  • 另一个AddField方法可以直接传输过去为两个string的kek和value
  • 虽然看起来很符合我们的使用了,但是还是在接口调试的时候我们发现一个问题,Content-Type找不到一个叫boundary的参数
  • 这个boundary讲解一下,大概就是一个边界符,数据使用他用来做分割

第三次测试

byte[] data1 = new byte[10];
byte[] data2 = new byte[20];
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");

WWWForm form = new WWWForm();
form.AddField("stringKey1", "stringValue1");
form.AddBinaryData("byteArrayKey1", data1);
form.AddBinaryData("byteArrayKey2", data2);

UnityWebRequest request = UnityWebRequest.Post("your_url", form);
request.SetRequestHeader("Content-Type", "multipart/form-data: boundary="+boundary);
request.SendWebRequest();
  • 如代码中所示一样我们选择添加了个string boundary手动创建了一个
  • 然后按照格式添加进了boundary 所以我们的接口确实是如愿以常的获取到了
  • 但是依然出现了新的问题
  • 是的没错 我们Content-Type中的Boundary并没有被真正的使用
    在这里插入图片描述

第四次测试

  • 文中的我又在苦思冥想以后想到了个问题,有可能是在Post中我们已经把boundary的发送过去了
  • 是的没错我们看了下Post的API找到了一个可以满足我们的方法
    在这里插入图片描述
  • 现在的问题就是 List这个参数怎么传我们的数值
  • 其中我们的参数imagebytes为我们图片的Byte信息
  • AuqClass.imagename参数为我们图片的名字
List<IMultipartFormSection> multipartFormSections = new List<IMultipartFormSection>();
        multipartFormSections.Add(new MultipartFormFileSection("image", imagebytes, AuqClass.imagename,"image/png"));
        multipartFormSections.Add(new MultipartFormDataSection("module", "recognize"));
  • 可以看到我们的方法组的api为一个name 一个byte的data,一个fileName,一个contentType
    在这里插入图片描述

  • .要注意MultipartFormFileSection和MultipartFormDataSection的区别,最开始我就全部都用了MultipartFormDataSection这个方法,每次传输数据过去接口接收的都是String 并不是Byte格式,后来好不容易才发现还是另外一个方法是使用传输byte的。

  • 没错我们这样就可以在Post前完成了添加boundary了

  • 木前我们的代码是这样的

    public Void PostImageIE()
    {

        string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
        byte[] imagebytes = File.ReadAllBytes(AuqClass.imagepath);
        byte[] boundarybyte = System.Text.Encoding.UTF8.GetBytes(boundary);
        List<IMultipartFormSection> multipartFormSections = new List<IMultipartFormSection>();
        multipartFormSections.Add(new MultipartFormFileSection("image", imagebytes, AuqClass.imagename,"image/png"));
        multipartFormSections.Add(new MultipartFormDataSection("module", "recognize"));
        UnityWebRequest request = UnityWebRequest.Post(AuqClass.URl, multipartFormSections, boundarybyte);
        request.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
        request.SendWebRequest();
       
    }

第五次测试

  • 还有一个问题我们并没有获取到数据,我们接口返回的数据
  • 我们这个时候发现可以使用downloadHandler属性
 request.downloadHandler = new DownloadHandlerBuffer();
        if (request.isNetworkError || request.isHttpError)
        {
            Debug.Log(request.error);
        }
        else
        {
            string responseText = request.downloadHandler.text;
            byte[] responseData = request.downloadHandler.data;
            Debug.Log(responseText);
            //Debug.Log(responseData );

            
        }

第六次测试

  • 回调的数据已经解决了,但是我们在在在一次遇到了bug
  • 问题出现是数据并没有回调成功,原因在排查以后,发现原来是我们没有等待反应,直接debug的数据,操作流程太快了,也就是太着急了。
  • 这个解决方法就很简单了,我们直接使用一个协程制作一个等待的条件
  • 最终我们的结果:
public void PostImage()
    {
        StartCoroutine(PostImageIE());
    }
    IEnumerator  PostImageIE()
    {

        string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
        byte[] imagebytes = File.ReadAllBytes(AuqClass.imagepath);
        byte[] boundarybyte = System.Text.Encoding.UTF8.GetBytes(boundary);
        List<IMultipartFormSection> multipartFormSections = new List<IMultipartFormSection>();
        multipartFormSections.Add(new MultipartFormFileSection("image", imagebytes, AuqClass.imagename,"image/png"));
        multipartFormSections.Add(new MultipartFormDataSection("module", "recognize"));
        UnityWebRequest request = UnityWebRequest.Post(AuqClass.URl, multipartFormSections, boundarybyte);
        request.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
        request.downloadHandler = new DownloadHandlerBuffer();
        yield return request.SendWebRequest();
        //request.SendWebRequest();
        if (request.isNetworkError || request.isHttpError)
        {
            Debug.Log(request.error);
        }
        else
        {
            string responseText = request.downloadHandler.text;
            byte[] responseData = request.downloadHandler.data;
            Debug.Log(responseText);
            
        }
    }

总结

解决的过程,每一个环节都曾经让我崩溃掉,所以我最后决定,把解决过程制作出来,希望对大家有起到一定做用,哪怕问题出现的不一样,也可以借鉴这其中的解决方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/353302.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

你知道IP属地是怎么来的?

在互联网高速发展的时代&#xff0c;登录网络使用网络的过程当中&#xff0c;会存在非常独特的IP属地&#xff0c;这个独特的概念就是在互联网不断发展过程当中&#xff0c;对于大家来说非常熟悉而又陌生的一个必要设备&#xff0c;在使用各种电子设备上网的时候&#xff0c;都…

Flutter For Web实践

1 什么是Flutter Flutter是Google开源的一套UI工具包&#xff0c;帮助开发者通过一套代码库高效构建多平台精美应用&#xff0c;支持移动APP、web、桌面和嵌入式平台。Flutter和其他的跨平台解决方案的实现方式上有比较大的差异。 我们以React Native&#xff08;下文简称RN&…

kubernetes教程 --组件详细介绍

组件详细介绍 NameSpace 在 Kubernetes 中&#xff0c;名字空间&#xff08;Namespace&#xff09; 提供一种机制&#xff0c;将同一集群中的资源划分为相互隔离的组。 同一名字空间内的资源名称要唯一&#xff0c;但跨名字空间时没有这个要求。 名字空间作用域仅针对带有名字…

STM32单片机初学8-SPI flash(W25Q128)数据读写

当使用单片机进行项目开发&#xff0c;涉及大量数据需要储存时&#xff08;例如使用了屏幕作为显示设备&#xff0c;常常需要存储图片、动画等数据&#xff09;&#xff0c;单靠单片机内部的Flash往往是不够用的。 如STM32F103系列&#xff0c;内部Flash最多只能达到512KByte&a…

git安装与学习1(CSDN_0010_202201014)

目录 1. Git下载 2. git安装 3. 生成并添加SSH公钥 3.1 生成公钥 3.2 添加公钥 4. 代码备份 4.1 创建远程仓库 4.2 创建本地仓库 1. Git下载 Git下载官网&#xff1a;Githttps://git-scm.com/ 详细的下载教程见&#xff1a; https://blog.csdn.net/weixin_47638941/ar…

CHAPTER 5 自动发现、自动注册、分布式监控、SNMP监控

自动发现与自动注册5.1 自动发现与自动注册5.1.1 简介5.1.2 两种模式5.2 自动发现--被动模式5.3 自动注册--主动模式5.4 分布式监控5.4.1 介绍5.4.2 配置zabbix proxy5.5 SNMP监控5.5.1 使用范围5.5.2 安装snmp程序5.5.3 配置snmp程序5.5.4 测试snmp5.5.5 在web界面进行配置5.1…

LeetCode 203. 移除链表元素

原题链接 难度&#xff1a;easy\color{Green}{easy}easy 题目描述 给你一个链表的头节点 headheadhead 和一个整数 valvalval &#xff0c;请你删除链表中所有满足 Node.valvalNode.val valNode.valval 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&a…

如何利用Power Virtual Agents机器人获取OneNote教学资源

今天我们继续来介绍如何利用PVA聊天机器人来获取OneNote教学资源。设计思路是在PVA聊天机器人的对话框中输入触发短语后&#xff0c;PVA聊天机器人会将指定的OneNote教学资源发送到学生的电子邮箱中。 首先&#xff0c;在PVA聊天机器人中创建主题。 创建一个“问题”后&#x…

【Spring AOP】Spring AOP快速使用

文章目录前言1、相关注解类注解方法注解2、execution 表达式例一【execution 表达式 的限制使用】例二【execution 表达式 的通配使用】3、相关pom依赖4、案例创建接口Aop使用 方式一【Before 、After 、AfterRuturning、AfterThrowing版】Aop使用 方式二【Around版】前言 Aop…

【笔记】通过labview调用halcon

使用原因&#xff1a;手眼标定使用halcon的九点标定&#xff0c;但是整体系统是用labview的&#xff0c;机器人得到二维坐标后&#xff0c;需经过halcon算子计算得到机器人坐标系下坐标&#xff0c;在进行运动。 下载路径&#xff1a; 链接&#xff1a;https://pan.baidu.com/s…

「计算机组成原理」数据的表示和运算(上)

文章目录一、进位计数制1.1 其他进制转十进制1.2 十进制转其他进制1.3 二进制、八进制和十六进制1.3 真值和机器数二、BCD码2.1 8421码2.2 余3码2.3 2421码三、整数的表示和运算3.1 无符号整数3.1.1 无符号整数的表示3.1.2 无符号整数的运算3.2 有符号整数3.2.1 有符号整数的表…

聚观早报 | 微信也要下场做“外卖”?;《羊了个羊》营收破亿

今日要闻&#xff1a;微信也要下场做“外卖”&#xff1f;;《羊了个羊》营收破亿&#xff1b;苹果将新XR头显上市推迟至6月&#xff1b;“交个朋友”被爆欠薪暴力裁员&#xff1f;&#xff1b;微软解释ChatGPT Bing AI推出速度缓慢的原因微信也要下场做“外卖”&#xff1f;腾讯…

C语言返回类型为指针的一些经典题目(上)

大家好&#xff0c;今天和大家分享一下C语言返回类型为指针的一些重要题目&#xff0c;看完你会恍然大悟。原来我对指针的了解还停留在指针只是一个地址的位置上&#xff0c;看完后你会对指针的用法进一步得到提升。目录一.关于指针类型的基础概念二.题目剖析一.关于指针类型的…

Java反序列化漏洞——CommonsCollections6链分析

一、前因因为在jdk8u71之后的版本中&#xff0c;sun.reflect.annotation.AnnotationInvocationHandler#readObject的逻辑发生了变化&#xff0c;导致CC1中的两个链条都不能使用&#xff0c;所有我们需要找一个在高版本中也可用的链条。/* Gadget chain: java.io.ObjectInputStr…

35岁危机

人们对社会的期望是不断变更的&#xff0c;无论拥有高技能的人还是普通的白领&#xff0c;这种期望都让人们不断地励磁进步&#xff0c;以期实现自己的理想。但是&#xff0c;当人们达到35岁时&#xff0c;多数人就会陷入一种状态&#xff0c;这被称之为“35岁危机”。 在35岁…

时间轮和时间堆管理定时器

高性能定时器 时间轮 由于排序链表定时器容器有这样一个问题&#xff1a;添加定时器的效率偏低。而即将介绍的时间轮则解决了这个问题。一种简单的时间轮如下所示。 如图所示的时间轮内&#xff0c;指针指向轮子上的一个slot&#xff08;槽&#xff09;&#xff0c; 它以恒定…

Linux操作系统-线程互斥,线程同步,生产者消费者模型

线程互斥线程互斥及相关概念线程互斥&#xff08;Mutual Exclusion&#xff09;是指在多线程环境下&#xff0c;同一时刻只能有一个线程访问共享资源&#xff0c;以避免对该资源的不正确访问&#xff0c;造成数据不一致等问题。例如&#xff0c;如果有多个线程都要同时对同一个…

web端元素各种尺寸示意图

1.偏移尺寸 offsetHeight 元素在垂直方向上占用的尺寸(height,border,水平滚动条高度) offsetWidth 元素在垂直方向上占用的尺寸(height,border,水平滚动条高度) offsetTop 元素上边框外侧距离包含元素上边框内侧的尺寸 offsetLeft 元素左边框外侧距离包含元素左边框内侧的尺寸…

Python-第八天 Python文件操作

Python-第八天 Python文件操作一、文件的编码1. 什么是编码&#xff1f;2. 为什么需要使用编码&#xff1f;二、文件操作1.文件的操作步骤2. 打开文件3.mode常用的三种基础访问模式4.关闭文件三、文件的读取1.文件对象有如下读取方法&#xff1a;2.练习&#xff1a;单词计数三、…

nextTick 的使用和原理(面试题)

答题思路&#xff1a; nextTick 是做什么的&#xff1f;为什么需要它&#xff1f;开发时什么时候使用&#xff1f;介绍一下如何使用nextTick原理解读&#xff0c;结合异步更新和nextTick生效方式 1. nextTick是做什么的&#xff1f; nextTick是等待下一次DOM更新刷新的工具方法…