ÒµÓà×öµÄСÓÎÏ·£¬ÅÅÐаñ±¾À´ÊÇÓÃPlayerPrefs´æ´¢ÔÚ±¾µØ£¬ÏÖÔÚÏ뽫Êý¾Ý·ÅÔÚ·þÎñÆ÷ÉÏ¡£ÒòΪ¹¦Äܼܺòµ¥£¬¾ÍÑ¡ÔñÁËСÇÉÁáççµÄFlaskÀ´ÊµÏÖ¡£
Ïл°ÉÙÐð¡£Ê×ÏÈ¿¼ÂÇURLµÄÉè¼Æ¡£ÅÅÐаñÎÞ·ÇÊÇÒ»¶Ñ·ÖÊýscoreµÄ¼¯ºÏ£¬°´ÕÕRESTµÄ˼Ï룬²»·Á½«URLÉèΪ/scores¡£ÓÃGET»ñµÃÅÅÐаñÊý¾Ý£¬ÓÃPOSTÌí¼ÓÒ»Ìõмͼµ½ÅÅÐаñ¡£´ËÍ⣬°´ÕÕ¹ßÀý£¬ÅÅÐаñµÄÊý¾Ý²»ÐèÒª¸üкÍɾ³ý¡£
Flask×ÔÉí²»Ö§³ÖREST£¬µ«ÎÒÃÇ¿ÉÒÔͨ¹ýrouteºÍmethod×Ô¼ºÊµÏÖ¡£ÏÂÃæ´´½¨Ò»¸öÔÐͰ汾µÄrank_server.py¡£ÃüÃûÑØÏ®ÁËRailsµÄϰ¹ß£º
from flask import Flask ¡¡¡¡app = Flask(__name__) ¡¡¡¡@app.route('/scores', methods=['GET']) ¡¡¡¡def index(): ¡¡¡¡return 'index' ¡¡¡¡@app.route('/scores', methods=['POST']) ¡¡¡¡def create(): ¡¡¡¡return 'create' ¡¡¡¡if __name__ == '__main__': ¡¡¡¡app.run(debug=True) |
Ö´ÐÐpython rank_server.pyÀ´Æô¶¯×Ô´øµÄ·þÎñÆ÷¡£ÏÂÃæÎÒÃǰ²×°cURLÀ´²âÊÔÓ¦Óá£
²âÊÔGET£º
`curl -i -X GET 127.0.0.1:5000/scores` |
²âÊÔPOST£º
`curl -i -X POST 127.0.0.1:5000/scores` |
¡¡-i²ÎÊý¿ÉÒÔչʾÏìÓ¦µÄÍ·²¿ÐÅÏ¢£¬±ãÓÚdebug¡£-X²ÎÊýÖ¸¶¨ÇëÇóµÄ·½·¨method¡£
¿ÉÒÔ¿´µ½²âÊԳɹ¦¡£
ÏÂÃæÎÒÃǽ¨Á¢´æ´¢Êý¾ÝµÄ±í¡£±¾µØ²âÊÔÎÒÃÇʹÓÃsqlite£¬Ö®ºó²¿ÊðʹÓÃmysql¡£
½¨±íÎļþcreate_rank.sqlÄÚÈÝÈçÏ£º
DROP TABLE IF EXISTS rank; ¡¡¡¡CREATE TABLE rank( ¡¡¡¡id INTEGER PRIMARY KEY AUTOINCREMENT, ¡¡¡¡name VARCHAR(255) NOT NULL, ¡¡¡¡score INTEGER NOT NULL ¡¡¡¡); |
¡¡Mac×Ô´øsqlite¡£Ö´ÐÐÏÂÃæÓï¾äµ¼ÈësqlÎļþ£º
sqlite3 rank.db < create_rank.sql |
È»ºóËæ±ã²åÈ뼸Ìõ²âÊÔÊý¾Ý¡£È磺
INSERT INTO rank (name, score) VALUES ('A', 100); ¡¡¡¡INSERT INTO rank (name, score) VALUES ('B', 200); ¡¡¡¡INSERT INTO rank (name, score) VALUES ('C', 300); |
Õë¶ÔÊý¾Ý¿â£¬ÎÒÃÇÔÚrank_server.pyÖмÓÈëÏÂÃæÒ»¶Î´úÂ룬ÓÃÓÚÔÚÇëÇóǰºó´¦ÀíÊý¾Ý¿âÁ¬½Ó¡£
import sqlite3 ¡¡¡¡DATABASE = 'rank.db' ¡¡¡¡@app.before_request ¡¡¡¡def before_request(): ¡¡¡¡g.db = sqlite3.connect(DATABASE) ¡¡¡¡@app.teardown_request ¡¡¡¡def teardown_request(exception): ¡¡¡¡if hasattr(g, 'db'): ¡¡¡¡g.db.close() |
ÎÒÃǹ涨·þÎñÆ÷ºÍ¿Í»§¶ËʹÓÃJSON´«ÊäÊý¾Ý¡£
GETÇëÇ󷵻صÄJSON¸ñʽÈçÏ£º
{ "data": [ { "id": 0, "name": "A", "score": 100 }, { "id": 1, "name": "B", "score": 200 } ] } |
ÕâÀïµÄidÆäʵÊÇ×ÔÔöÖ÷¼ü£¬¿ÉÒÔ²»±Ø±£Áô£¬µ«ÎªÁ˺óÃæ´¦Àí·½±ã¾ÍÒ»Æð±£ÁôÁË¡£
POSTÌá½»µÄJSON¸ñʽÈçÏ£º
{ ¡¡¡¡"id": 0, ¡¡¡¡"name": "C", ¡¡¡¡"score": 300 ¡¡¡¡} |
ÏÖÔÚÎÒÃÇ¿ÉÒÔ×ÅÊÖʵÏÖindex·½·¨ÁË£º
def index(): ¡¡¡¡cur = g.db.execute('select id, name, score from rank order by score desc;') ¡¡¡¡result = cur.fetchmany(100) ¡¡¡¡data = [] ¡¡¡¡for row in result: ¡¡¡¡data.append({'id': row[0], 'name': row[1], 'score': row[2]}) ¡¡¡¡return jsonify({'data': data}) |
£¨ÆäÖÐjsonifyºÍgÔÚflaskÄ£¿éÄÚ¡£ºóÃæ²»ÔÙ¶Ôµ¼Èë½øÐÐ˵Ã÷£¬Ä¬È϶¼ÊÇ´Óflaskµ¼Èë¡££©
ÔÚ²éѯʱ¶ÔÊý¾Ý×öÁËÅÅÐò£¬²¢ÇÒÖ»·µ»ØÁËǰ100Ìõ¼Ç¼¡£¿ÉÒÔÓÃcurlÔÙ²âÊÔһϡ£²âÊÔÎÞÎóÔÙʵÏÖcreate·½·¨£º
def create(): ¡¡¡¡status = {'status': 'OK'} ¡¡¡¡if not request.json or not 'name' in request.json or not 'score' in request.json: ¡¡¡¡status['status'] = 'bad request' ¡¡¡¡try: ¡¡¡¡g.db.execute('insert into rank (name, score) values (?, ?)', [request.json['name'], request.json['score']]) ¡¡¡¡g.db.commit() ¡¡¡¡except: ¡¡¡¡status['status'] = 'database error' ¡¡¡¡return jsonify(status) |
ÎÒÃǵÄPOSTÇëÇó¶¼ÊÇJSONÀàÐ͵ģ¬ËùÒÔÒª´Órequest.json»ñµÃ£¬¶ø²»ÊÇargs»òÕßform¡£´ËÍ⣬·µ»ØÁËÒ»¸östatus±äÁ¿£¬±ãÓڲ鿴³ö´íÔÒò¡£
ÔÙÓÃcurl²âÊÔÒ»ÏÂPOST¡£Õâ´Î£¬ÎÒÃÇÒªÏòPOSTÇëÇóÖмÓÈëÊý¾Ý£º
curl -i -X POST -H "Content-Type: application/json" -d '{"id": 0, "name": "xyz", "score": "800"}' 127.0.0.1:5000/scores |
-H²ÎÊýÓÃÓÚÖ¸¶¨Í·²¿ÐÅÏ¢£¬-d²ÎÊý¿ÉÒÔЯ´øÊý¾Ý£¬ÕâÀï¾ÍÊÇÒ»Ìõ·ûºÏÎÒÃÇÌá½»¸ñʽµÄJSONÊý¾Ý¡£
ÏÖÔÚ·þÎñÆ÷¶Ë¾Í£¨ÔÝʱ£©ÊµÏÖÍêÁË¡£ÏÂÃæ¸ÃдC#´úÂëÀ²¡£
ÎÒÃÇÐèÒªÉè¼ÆÒ»¸öºÍ·þÎñÆ÷½»»¥¡¢²¢·µ»ØÊý¾Ý¸øUI²ãµÄÀà¡£
Ê×ÏÈ£¬Õâ¸öÀàÓ¦¸ÃÊǵ¥ÀýµÄ£¬Òª¼Ì³ÐMonoBehaviour£¨ÒòΪºÍ·þÎñÆ÷½»»¥ÒªÀûÓÃCoroutine£©£»¶øÇÒ×îºÃ¶ÀÁ¢ÓÚ³¡¾°Ö®Íâ¡£¹ØÓÚUnityÖÐʵÏÖµ¥ÀýÀàµÄ¼¯Öз½Ê½£¬Çë¿´ÎÒµÄÁíһƪÎÄÕ¡£µ¥ÀýµÄ´úÂëÈçÏ£º
private static SaveLoad _instance = null; public static SaveLoad Instance { get { if (_instance == null) { GameObject go = new GameObject("SaveLoadGameObject"); DontDestroyOnLoad(go); _instance = go.AddComponent<SaveLoad>(); } return _instance; } } |
»¹ÐèÒª¶¨ÒåһЩ³£Á¿£º
const int recordsPerPage = 5; ¡¡¡¡const string URL = "127.0.0.1:5000/scores"; |
¶¨ÒåÒ»¸öÊý¾Ý½á¹¹£º
public struct Data { ¡¡¡¡public int id; ¡¡¡¡public string name; ¡¡¡¡public int score; ¡¡¡¡} |
ÔÚ¶¯ÊÖ֮ǰ£¬»¹ÒªÁ˽âÁ½¸ö¶«Î÷£ºWWWÀàºÍLitJson¿â¡£WWWÀàÊÇUnity×Ô´øµÄ´¦ÀíHTTPÇëÇóµÄÀࣻLitJsonÊÇÒ»¸öC#´¦ÀíJSONµÄ¿ªÔ´¿â¡£ÒªÊ¹ÓÃLitJson£¬ÏÈ´Ó¹ÙÍøÏÂÔØdllÎļþ£¬È»ºóµ¼ÈëAsset¡£
SaveLoadÀàµÄ¹¦ÄܾÍÏñÃû×ÖÒ»Ñù£¬°üÀ¨±£´æSaveºÍÔØÈëLoad¡£
public void Save(Data data) { var jsonString = JsonMapper.ToJson(data); var headers = new Dictionary<string, string> (); headers.Add ("Content-Type", "application/json"); var scores = new WWW (URL, new System.Text.UTF8Encoding ().GetBytes (jsonString), headers); StartCoroutine (WaitForPost (scores)); } IEnumerator WaitForPost(WWW www){ yield return www; Debug.Log (www.text); } |
ÕâÀï´´½¨WWWʵÀý£¬Ö¸¶¨ÁËURL¡¢headerºÍÌá½»Êý¾Ý¡£µÚÒ»ÐеÄJsonMapper¿ÉÒÔÔÚ¶ÔÏóºÍJSONÖ®¼ä½øÐÐת»»£¬Ç°ÌáÊǶÔÏóÖеÄÊôÐÔºÍJSONÖеļüÒª±£³ÖÒ»Ö¡£
public void Load() { var scores = new WWW (URL); StartCoroutine(WaitForGet(scores)); } IEnumerator WaitForGet(WWW www){ yield return www; if (www.error == null && www.isDone) { var dataList = JsonMapper.ToObject<DataList>(www.text); data = dataList.data; }else{ Debug.Log ("Failed to connect to server!"); Debug.Log (www.error); } } |
Load·½·¨ÖÐÊǽ«Ç°Ãæindex·½·¨·µ»ØµÄJSONÎı¾×ª»»³É¶ÔÏó£¬ÕâÀïΪÁËʵÏÖת»»£¬Ð½¨Ò»¸öDataListÀ࣬ÆäÖеÄÊôÐÔÊÇList<Data>¡£
µ½ÕâÀ¿Í»§¶ËµÄ¶ÁÈ¡ºÍ±£´æÊý¾Ý¾ÍʵÏÖÁË¡£ÆäÓàµÄÂß¼£¬±ÈÈçºÍUIµÄ½»»¥£¬ÔÚÕâÀï¾Í²»Ð´ÁË¡£¸ÐÐËȤµÄ¿ÉÒÔ¿´ÎÒµÄСÓÎÏ·µÄÍêÕû´úÂë
GitHub´«ËÍÃÅ
×îºó̸̸²¿ÊðµÄÊÂÇé¡£Èç¹ûÒª²¿Êðµ½SAEÓм¸µãҪעÒ⣺
´úÂëÒª½øÐÐÒ»¶¨µÄÐÞ¸ÄÒÔÊÊÓ¦MySQLdb¡£
ҪעÒâÖÐÎĵıàÂë¡£ÈçÓÃunicode·½·¨×ª»»Ãû×ÖÊôÐÔ£¬ÒÔ¼°ÎļþÍ·²¿µÄ£º
# -*- coding:utf8 -*- ¡¡¡¡#encoding = utf-8 |
×îºó˵˵±È½Ï¿ÓµÄUnity¿çÓò·ÃÎʵÄÏÞÖÆ¡£ÔÚÎҳɹ¦²¿Êðºó£¬curl²âÊÔûÓÐÎÊÌâÁË¡£½á¹ûUnity±¨ÁË´í£º
SecurityException: No valid crossdomain policy available to allow access |
¾¹ýÒ»·¬ËÑË÷£¬ÔÀ´ÒªÔÚ·þÎñÆ÷µÄ¸ùĿ¼Ôö¼ÓÒ»¸öcrossdomain.xmlÎļþ¡£ÎļþÄÚÈÝ´óÖÂÈçÏ£º
<?xml version="1.0"?> ¡¡¡¡<!DOCTYPE cross-domain-policy SYSTEM ¡¡¡¡"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> ¡¡¡¡<cross-domain-policy> ¡¡¡¡<site-control permitted-cross-domain-policies="master-only"/> ¡¡¡¡<allow-access-from domain="*"/> ¡¡¡¡<allow-http-request-headers-from domain="*" headers="*"/> ¡¡¡¡</cross-domain-policy> |
µ«ÊÇSAEºÃÏñ²»Ö§³ÖÉÏ´«Îļþµ½¸ùĿ¼¡£Ö»ÄÜÓÃFlask·ÂðһÏÂÁË£º
@app.route('/crossdomain.xml') ¡¡¡¡def fake(): ¡¡¡¡xml = """ÉÏÃæµÄÄǶÑÄÚÈÝ""" ¡¡¡¡return xml, 200, {'Content-Type': 'text/xml; charset=ascii'} |
|