创造你的世界
多人游戏
来自Multiplay服务器的HTTP请求
14分
您可以使用 zepeto multiplay httpservice 模块从 zepeto world multiplay 服务器发出 http 请求。将外部网络服务集成到您的业务逻辑操作、数据存储、统计分析、错误跟踪等中。 请确保仅使用 https 协议,而 http 仅在开发环境中支持。 仅允许在 80 和 443 端口上发出请求。 请求和响应主体的最大大小限制为 16kb。 每分钟的请求数量应保持在 500 以下,以避免在发生过多请求时对世界服务施加潜在限制。 如果外部网络服务在 5 秒内未响应,请求将失败。 确保响应头中的内容类型与 httpcontenttype 枚举中定义的值匹配;否则,请求将失败。 考虑到网络请求可能因各种原因失败,建议采取防御性编码。 zepeto multiplay httpservice 📘 请参考以下指南。 \[ zepeto multiplay httpservice api https //developer zepeto me/docs/multiplay server/interfaces/zepeto multiplay httpservice httpservice ] 方法 方法 描述 httpservice getasync(url string, headers? httpheader) promise 异步执行 http get 请求。 \[参数] \ url 发送请求的网页地址。 \ headers http 请求头。 (可选) \[返回值] \ promise\<httpresponse> 返回一个 httpresponse 对象,包含有关响应的信息作为 promise httpservice postasync(url string, body httpbodytype, headers? httpheader) promise 异步执行 http post 请求。 \[参数] \ url 发送请求的网页地址。 \ body 请求体内容。 \ headers http 请求头。 (可选) \[返回值] \ promise\<httpresponse> 返回一个 httpresponse 对象,包含有关响应的信息作为 promise httpservice postasync(url string, body httpbodytype, httpcontenttype httpcontenttype, headers? httpheader) promise 异步执行 http post 请求。 \[参数] \ url 发送请求的网页地址。 \ body 请求体内容。 \ httpcontenttype 指定请求的 content type 头。 \ headers http 请求头。 (可选) \[返回值] \ promise\<httpresponse> 返回一个 httpresponse 对象,包含有关响应的信息作为 promise。 使用此签名时,如果您在 headers 中添加 'content type',它将被 httpcontenttype 中指定的内容覆盖。 其他声明 声明 描述 httpcontenttype 指定http头的content type的常量枚举。 \ applicationjson 'application/json' \ applicationxml 'application/xml' \ applicationurlencoded 'application/x www form urlencoded' \ textplain 'text/plain' \ textxml 'text/xml' httpbodytype http请求体内容的类型,可以是字符串或具有字符串键和任意值的对象。 httpheader 用于定义http请求头的类型,其中属性值可以是字符串或对象中的数字。 httpresponse 包含有关http请求结果和响应数据的信息的接口。 \ statuscodehttp 表示响应状态码的数字。通常,200表示请求成功。 \ statustexthttp 表示响应状态消息的字符串。通常,"ok"表示请求成功。 \ response 包含http响应体数据的字符串。 📘 http状态 https //developer mozilla org/en us/docs/web/http/status https //developer mozilla org/en us/docs/web/http/status 代码示例 基本的 get 请求 让我们使用 httpservice getasync 当一个新客户端连接到 multiplay 房间时,我们将向外部网络服务发送一个 http 请求并记录结果。 restcountries com https //restcountries com/ 是一个开放的api,提供有关各国的信息。我们将使用此服务来查找日本的首都。 设置multiplay,然后打开world multiplay/index ts并按如下方式编写服务器脚本。 📘 请参考以下指南。 \[ 多人游戏 docid\ vrcnxwq2u9dbmamyi6 9d ] import { sandbox, sandboxoptions, sandboxplayer } from "zepeto multiplay"; import { httpservice } from "zepeto multiplay httpservice"; export default class extends sandbox { oncreate(options sandboxoptions) { } onjoin(client sandboxplayer) { this findcapitalcity() } onleave(client sandboxplayer, consented? boolean) { } findcapitalcity() { // make the request to the restcountries api httpservice getasync("https //restcountries com/v3 1/name/japan?fields=capital") // handler for the http response then((httpresponse) => { // parse the json response data from the api (which is nested in http response) let countries = json parse(httpresponse response); console log("日本的首都城市是 "); console log(`${countries\[0] capital}`); }); } } 代码描述 当客户端连接到multiplay房间时, onjoin 函数被触发,并调用 findcapitalcity 。 如果对restcountries api的 getasync 调用成功,您可以在 httpresponse 对象中访问 then 回调。 解析 httpresponse response 以将api响应(以json格式)转换为对象。 通过参考api响应的结构,您可以访问所需的属性,然后打印它们的值。 当您在unity编辑器中运行multiplay服务器并播放场景时,控制台将显示以下内容。 日本的首都城市是: 东京 防御性编码实践 同时,如引言中的预防措施所提到的,网络请求可能因各种原因而失败,包括网络地址或api响应格式的变化。 未能正确处理这些请求可能对世界游戏产生各种不利影响,因此建议进行防御性编码,特别是在处理http请求时。 以下是将几种防御性编码技术应用于上述代码的示例。 findcapitalcity() { // 向restcountries api发出请求 httpservice getasync( "https //restcountries com/v3 1/name/japan?fields=capital", { 'accept' httpcontenttype applicationjson }) // http响应的处理程序 then((httpresponse) => { // 检查api调用是否返回200(ok) if (httpresponse statuscode != 200) { // 如果不是200(ok),则不继续并引发自定义错误 throw (`api错误 ${httpresponse statuscode} ${httpresponse statustext}`); } // 返回api的json响应数据 return httpresponse response; }) // api的json响应数据的处理程序 then((response) => { // 解析json响应数据 let countries = json parse(response); // 检查api响应数据是否有效 if (!array isarray(countries) || !countries length) { // 如果不是数组,或为空 // 不继续并引发自定义错误 throw (`api错误 响应数据无效`); } let country = countries\[0]; // 检查'capital'字段是否有效 if (!country capital) { // 如果'capital'字段不存在,或为空 // 不继续并引发自定义错误 throw (`api错误 'capital'字段无效`); } console log("日本的首都城市是 ") console log(`${country capital}`); }) // 处理在getasync调用和'then'子句中发生的错误。 catch((reason) => { console log("api请求错误"); console log(reason); }); } 这里应用的防御性编码技术包括以下内容: 使用 accept 头部: accept 头部用于指定响应体的预期 content type。根据服务器的不同,响应的 content type 可以根据 accept 头部进行调整。 检查 httpresponse statuscode httpresponse statuscode 属性用于验证请求的成功。 验证 json 数据结构:您确认使用 json parse 解析的对象的数据结构是否与预期结构匹配。 验证属性存在性:您确保您打算使用的属性在对象中确实存在。 利用 promise 的 catch 方法:promise 的 catch 方法用于处理在 api 请求和响应处理过程中可能发生的错误。 这些技术保护代码在面对意外错误时可靠运行,增强了其稳健性。 通过房间消息与客户端集成 http 请求仅能从 multiplay 服务器发出。 然而,通过使用 multiplay 房间消息,您可以触发服务器从客户端向外部网络服务发送 http 请求,并在客户端中利用响应。 以下示例演示了客户端与服务器的集成。在此演示中,当客户端 ui 上的按钮被按下时,显示与该按钮对应的国家首都。 📘 请参考以下指南。 \[ multiplay room message docid\ wwza8fxwmtcm7xkfepebd ] 客户端代码 import { zepetoscriptbehaviour } from 'zepeto script' import { room } from 'zepeto multiplay' import { zepetoworldmultiplay } from 'zepeto world'; import { button, text } from 'unityengine ui' export default class samplescript extends zepetoscriptbehaviour { public multiplay zepetoworldmultiplay; public room room; public countrybuttons button\[]; public capitaltext text; start() { interface response { capitals string\[] } for (const countrybutton of this countrybuttons) { countrybutton onclick addlistener(() => { if (this room !== null) { // 发送国家名称作为 '客户端到服务器' 类型消息到服务器 this room send("client to server", countrybutton getcomponentinchildren\<text>() text); } }); }; this multiplay roomcreated += (room room) => { this room = room; // 处理以 '服务器到客户端' 类型接收的消息 this room addmessagehandler("server to client", (message response) => { // 对于拥有多个首都城市的国家, // 将字符串元素用 ', ' 连接并在场景中显示 this capitaltext text = message capitals join(", "); }); }; } } 代码描述: 我们定义了一个监听器,遍历显示国家名称的按钮。当点击时,这个监听器向multiplay服务器发送一个房间消息。 这个监听器将按钮上显示的国家名称作为 '客户端到服务器' 类型消息发送。 为了处理响应,我们还定义了一个监听器,用于处理作为 '服务器到客户端' 类型接收的房间消息。 这个监听器在屏幕上显示从服务器接收到的首都城市名称。如果有多个首都城市,它们将在屏幕上显示,并用逗号分隔。 服务器代码 import { sandbox, sandboxoptions, sandboxplayer } from "zepeto multiplay"; import { httpservice } from "zepeto multiplay httpservice"; export default class extends sandbox { oncreate(options sandboxoptions) { // 处理接收到的 'client to server' 类型的消息 this onmessage("client to server", (client, message) => { console log(`客户端 ${client userid} 发送请求。消息 ${message}`); this findcapitalcity(message, client); }); } onjoin(client sandboxplayer) { } onleave(client sandboxplayer, consented? boolean) { } findcapitalcity(countryname string, client sandboxplayer) { // 使用 countryname 作为路径参数请求 api // countryname 是客户端作为房间消息发送的 httpservice getasync(`https //restcountries com/v3 1/name/${countryname}?fields=capital`) then((httpresponse) => { if (httpresponse statuscode != 200) { throw (`api 错误 ${httpresponse statuscode} ${httpresponse statustext}`); } return httpresponse response; }) then((response) => { let countries = json parse(response); if (!array isarray(countries) || !countries length) { throw (`api 错误 响应数据无效`); } let country = countries\[0]; if (!country capital) { throw (`api 错误 'capital' 字段无效`); } // 向客户端发送 'server to client' 类型的消息 // 消息是一个包含首都城市名称的对象 client send("server to client", { "capitals" country capital }); }) catch((reason) => { console log("api 请求错误"); console log(reason); }); } } 代码描述: 我们定义一个监听器,当接收到 'client to server' 类型的 multiplay room message 时,调用 findcapitalcity 。 我们使用国家名称构建 multiplay room message 的地址,并进行 getasync 调用。 如果 getasync 调用成功,响应将像之前的示例一样处理。 从 restcountries api 的响应中获得的首都城市名称作为 'server to client' 类型的 room message 发送给客户端。 post请求 最后,让我们使用 httpservice postasync postman echo https //postman echo com/ 是一个提供结构化响应的服务,显示从网络请求中接收到的内容,使其有效地验证客户端是否正确配置了请求。 通过这个例子,我们将设置一个带有查询参数、请求体和头部的post请求,并确保请求配置正确。 设置 multiplay,然后打开 world multiplay/index ts 并按如下方式编写服务器脚本。 import { sandbox, sandboxoptions, sandboxplayer } from "zepeto multiplay"; import { httpcontenttype, httpservice } from "zepeto multiplay httpservice"; export default class extends sandbox { oncreate(options sandboxoptions) { } onjoin(client sandboxplayer) { this echopost() } onleave(client sandboxplayer, consented? boolean) { } echopost() { httpservice postasync( // api 端点和查询参数 "https //postman echo com/post?argkey=argvalue", // json 请求体 { "datakey" "datavalue" }, // 请求内容类型 httpcontenttype applicationjson, // http 头 { "header key" "header value" }) then((httpresponse) => { if (httpresponse statuscode != 200) { throw (`api 错误 ${httpresponse statuscode} ${httpresponse statustext}`); } return httpresponse response; }) then((response) => { let parsed = json parse(response); console log(`查询参数 argkey ${parsed args argkey}`); console log(`请求体 datakey ${parsed data datakey}`); console log(`请求头 header key ${parsed headers\["header key"]}`) }) catch((reason) => { console log("api 请求错误"); console log(reason); }); } } 代码描述: 当客户端连接到multiplay room时, echopost 函数从 onjoin 触发器被调用。 在发起 postasync 请求时: 在第一个参数中,我们构造带有查询参数的url字符串。 在第二个参数中,我们设置请求体内容。 在第四个参数中,我们配置请求头。 为了指定请求体为json格式,我们在第三个参数中设置'application/json'的content type。 如果 postasync 调用成功,我们可以在 httpresponse 对象中访问 then 回调。 我们解析 httpresponse response 以将api响应的json格式转换为对象。 参考api响应的结构,我们使用控制台输出验证我们的http请求的查询参数、请求体和请求头是否正确配置。 当您在unity编辑器中运行multiplay服务器并播放场景时,控制台将显示以下内容。 查询参数:argkey\ argvalue 请求体:datakey\ datavalue 请求头:header key\ header value