
みなさんこんにちは! Unity3DでWWWを操作するために自転車を共有することにしました。
WWWとは何ですか?
WWWは、指定されたURLにWeb要求を送信し、テキスト、テクスチャ、ロードバンドルの形式で応答を受信できるようにするクラスです。 詳細については、証明書をご覧ください(
クリック )。
テキストデータ形式に焦点を当てます。
背景
ゲームをPhpで記述されたサーバーに接続するタスクが発生する場合があります(ただし、他の言語を使用してバックエンドパーツを展開できます)。 常に新しいWWWの形式でリクエストを送信します(アドレス+ "?Api =ログイン&ユーザー名= ..."); 便利ではないので、データの送受信をもっと便利にしたいです。
別の問題があります。リクエストは同期的に送信され、メインスレッドをブロックします。 これを回避するためにコルーチンを使用するオプションがあります。
その結果、このアイデアは、WWW.textを操作するための生活を簡素化できるものを書くために熟成しました。
実装
通常、結果を返すサーバー上のメソッドをプルする必要があります。 リストを列挙メソッドに入れて、必要に応じて展開できます。
public enum PacketTypes { nil, auth, updateinfo }
以下は、それぞれ
NetRequestクラスと
NetResponseクラスによって表される要求/応答オブジェクトです。 データ交換形式を非表示にして、辞書に保存します(普遍的に同じ)。 NetRequestでは、
GetParamsString()を介してサーバーに送信するクエリ文字列を取得できます。 NetResponseにはすぐに使用できるデータが含まれており、IsErrorを使用してエラー応答を確認することもできます。
使用される別のクラスはHttpUtility(System.Web、Patrik Torstenssonの作者ではない)で、文字(スペース、引用符など)をエンコードできます。 その理由は、System.Web for Unity3dにはこのクラスがないためです。 ソースのみを提供しますが、考慮しません。
NetRequest.cs
using System.Collections.Generic; using System.Linq; public class NetRequest : Dictionary<string, string> { private const string METHOD_KEY = "method"; public NetRequest(PacketTypes header) { AddParam(METHOD_KEY, header.ToString()); } public void AddParam(string key, string value) { var val = HttpUtility.HtmlEncode(value); if (ContainsKey(key)) base[key] = val; else Add(key, val); } public void AddParam(string key, long value) { AddParam(key, value.ToString()); } public void AddParam(string key, bool value) { AddParam(key, value ? 1 : 0); } public void RemoveParam(string key) { if (ContainsKey(key)) Remove(key); } public string GetParamsString() { return string.Join("&", this.Select(n => n.Key + "=" + n.Value).ToArray()); } }
NetResponse.cs
using System.Collections.Generic; public class NetResponse : Dictionary<string, string> { private const string ERROR_KEY = "error"; public string GetError { get { if (IsError) return base[ERROR_KEY]; return string.Empty; } } public bool IsError { get { return ContainsKey(ERROR_KEY); } } public NetResponse(string data) { var mas = data.Split(new[] { '&' }); foreach (var s in mas) { var keyVal = s.Split(new[] { '=' }); Add(keyVal[0], HttpUtility.UrlDecode(keyVal[1])); } } }
次に、その使用方法について説明します。 ネットワーククラス(シングルトン)があり、リクエストを送信するためのメソッドと、クライアント側でのAPIメソッドの実装(リクエストに特定のデータを入力するため)が含まれています。
Network.cs
using System.Collections; using UnityEngine; public class Network { private static Network _instance; public static Network Instance { get { if (_instance == null) _instance = new Network(); return _instance; } } private const string SERVER_PATH = "http://localhost:8080/server/engine.php"; private IEnumerator SendRequest(NetRequest request) { var www = new WWW(string.Concat(SERVER_PATH, "?", request.GetParamsString())); while (!www.isDone) yield return www; if (!string.IsNullOrEmpty(www.error)) {
おそらく、2つの重要なポイントがあります。
まず、
SendRequestメソッドはIEnumeratorを返します。 リクエストを非同期に実行したいです。 要求が実行されるまで待機してから、データとともにNetResponseオブジェクトを返します。
次に、WWWでエラーが発生した場合、またはサーバーからエラーが発生した場合、NetResponseに正常に配置し、優れたロジックで処理します。
必要に応じて、リクエストを送信する前に、不足しているデータ(フィル全体、ユーザーIDなどからのハッシュ)を直接SendRequestに添付できます。
IEnumerator SendUpdateInfo(intポイント)について詳しく見てみましょう。 なぜIEnumeratorなのか? これは、兄弟、StartCoroutineに必要です。 これがメソッドを呼び出す方法です。 しかし、利益はどこにありますか?
彼は低いです
return SendRequest(request).ContinueWith(response => { if (response.IsError) {
なぜなら SendRequestからNetResponseを返すと、すでにデータにアクセスできます。解析する必要はありません。
.ContinueWithが何であるかを理解する
だけです 。
public static class NetApiExt { public static IEnumerator ContinueWith(this IEnumerator request, Action<NetResponse> resp) { var link = request; while (link.MoveNext()) { yield return link; } var obj = link.Current as NetResponse; resp(obj); yield return obj; } }
ここにハックがあります:)
送信メソッドの内部と外部の両方で答えをキャッチできます。
StartCoroutine(Network.Instance.SendUpdateInfo(userPoints).ContinueWith(reponse => { if (!reponse.IsError) {
サーバー部分の一部のみを提供します。 $ _GET ["some key"]を取得した後、何かをして、必要なものをNetResponseクラスのオブジェクトに追加します。
class NetResponse { private $mas = array(); public function AddParam($key, $val){ $this->mas[$key] = urlencode($val); } public function AddError($val){ $this->AddParam("error", $val); } public function SendResponse(){ $res = ""; foreach ($this->mas as $key => $val) { $res = $res.strtolower($key)."=".$val."&"; } if(strlen($res) > 0) echo substr($res,0,-1); } }
電話をかけ続ける
$resp = new NetResponse; $resp->AddParam("points","123456");
合計
もちろん、このオプションは理想的ではありませんが、実用的なアプリケーションであり、プロジェクト間での移植性に優れています。
親愛なる%ユーザー名%s、あなたはWWWでどのように仕事をしていますか、どのような面白いことを思いついていますか?