logo
Khóa học lập trình game server - smartfox - game đa người chơi Học lập trinh game online 3dvietpro Sửa chữa và thiết kế website .net
Welcome Guest! To enable all features please Đăng nhập or Đăng ký.

Thông báo

Icon
Error

Tùy chọn
Xem
Xem bài viết cuối Go to first unread
JungJinHyuk  
#1 Đã gửi : 29/09/2014 lúc 11:39:44(UTC)
JungJinHyuk

Danh hiệu: Administration

Nhóm:
Gia nhập: 20-08-2014(UTC)
Bài viết: 60

Cảm ơn: 2 lần
Được cảm ơn: 2 lần trong 2 bài viết
bài viết được trích của bạn tiến nguyễn trong unityviet
=======================================================
Như vậy chúng ta đã cùng nhau trãi qua loạt bài viết về save game, để kết thúc series này hôm nay mình sẽ trình bày vấn đề và giải pháp đơn giản thực hiện vấn đề: Đồng bộ dữ liệu game lên server và cho phép user chơi trên nhiều máy khác nhau.

Mô hình đồng bộ dữ liệu
Mô hình đồng bộ dữ liệu

Trong quá trình đồ bộ dữ liệu ở mức đơn giản thì chúng ta có 2 thành phần đó là:

– Client: game client (Android, iOS, WP8), thành phần này phụ trách đẩy dữ liệu lên server và cập nhật mới khi có thông báo, kiểm tra tính hợp lệ của dữ liệu (có thể sử dụng thư viện từ build, hoặc SDK nếu sử dụng services của bên thứ 3 cung cấp).

– Server: thành phần kiểm tra tính hợp lệ, lưu trữ dữ liệu và cho phép truy xuất dữ liệu (có thể sử dụng các services của bên thứ 3 cung cấp). Trong phạm vi bài viết này mình sẽ sử dụng service inhouse (tự build).

Chuẩn bị:
– Server:

Hệ thống UserId (Đăng ký, đăng nhập, session).
Sử dụng PHP & MySQL để mở API cho phép client put, get thông tin dựa trên giao thức HTTP (dành cho các game đơn gian, việc truy xuất dữ liệu không liên tục).
Sử dụng Socket Server(Websocket, Socket C/C++, Socket Java.

– Client:

Module (đăng ký, đăng nhập, kiểm tra session)
HTTPRequest (sử dụng đối tượng WWW của Unity).
Socket client

Chi tiết:
– Phần server (implement sử dụng giao thức HTTP bằng PHP và MySQL):

Phương thức Put (lưu trữ dữ liệu) với URL: http://api.stgame.vn/put...on=xxxxxx&data=yyyyy
Phuong thức Get(lấy dữ liệu) với URL: http://api.stgame.vn/get...on=xxxxxx&data=yyyyy
Parameter được mã hóa đề đảm bảo tính bảo mật (mã hóa theo thuật toán giống nhau ở client và server, dùng public key và private key như facebook SDK)
Implement chi tiết sẽ được trình bài ở series cụa thể về lưu trư game data ở server.
– Phần client (implement đơn gian module sync data sử dụng HTTP) với các thành phần sử dụng:

EventDelegate
Coroutine của MonoBehaviour (Unity)
WWW (Unity)
SimpleJSON
Mã:
using System.Collections;
using System.Collections.Generic;
using SimpleJSON;
 
public class SimpleSyncData : MonoBehaviour {
 
    public delegate void CallbackFunction(string message);
    public List<EventDelegate> onConnectFail = new List<EventDelegate>();
    public List<EventDelegate> onSyncDataDone = new List<EventDelegate>();
    
    
    public void syncGameDataFromServer(string data) {
        if(UserInfoLocal.Instance.isLogin && !UserInfoLocal.Instance.isUpdated) {
            string urlGetGameData = "http://api.stgame.vn/get?session=" + UserInfoLocal.getDataSession() + "&data=" + data;
            StartCoroutine(sendHttpRequest(urlGetGameData, onSyncGameDataFromDone));
        }
    }
 
    public void syncGameDataToServer(string data) {
        if(UserInfoLocal.Instance.isLogin && UserInfoLocal.Instance.isUpdated) {
            string urlPutGameData = "http://api.stgame.vn/put?session=" + UserInfoLocal.getDataSession() + "&data=" + data;
            StartCoroutine(sendHttpRequest(urlPutGameData, onSyncGameDataToDone));
        }
    }
    
    public IEnumerator sendHttpRequest(string url, CallbackFunction callback) {
        WWW www = new WWW(url);
        float timer = 0; 
        bool failed = false;
        while(!www.isDone){
            if(timer > maxWaitingTime){
                failed = true;
                break;
            }
            timer += Time.deltaTime;
            yield return null;
        }
        
        if(failed) {
            www.Dispose();
            fireEventConnectFail();
        } else {
            if(string.IsNullOrEmpty(www.error)){
                callback(www.text);
            } else {
                fireEventConnectFail();
            }
        }
    }
 
    public JSONNode processDataFromServer(string data) {
        if(!string.IsNullOrEmpty(data)) {
            string jsonStr = StCypher.Decrypt(data);
            if(!string.IsNullOrEmpty(jsonStr)) {
                Debug.Log (jsonStr);
                JSONNode jsonNode = JSONNode.Parse(jsonStr);
                if(jsonNode != null && !string.IsNullOrEmpty(jsonNode["error"].Value)) {
                    return jsonNode;
                }
            }
        }
        fireEventConnectFail();
        return null;
    }
 
 
    public void onSyncGameDataFromDone(string data) {
        JSONNode jsonNode = processDataFromServer(data);
        if(jsonNode != null) {
            int error = jsonNode["error"].AsInt;
            if(error >= ErrorCode.Err_None) {
                if(jsonNode["data"] != null) {
                    JSONNode gameData = JSONNode.Parse(jsonNode["data"]);
                    if(gameData != null && UserInfoLocal.Instance.onReceiveGameData(gameData)) {
                        fireEventSyncDataDone();
                    } else {
                        syncGameDataToServer();
                    }
                } else {
                    syncGameDataToServer();
                }
            } else {
                switch(error) {
                case ErrorCode.Err_Not_Exists:
                {
                    //Update state data
                    //Sync data to server
                    syncGameDataToServer();
                    break;
                }
                case ErrorCode.Err_Invalid_Session:
                {
                    //Sign out
                    break;
                }
                }
            }
        } else {
            //fail
            fireEventConnectFail();
        }
    }
 
    public void onSyncGameDataToDone(string data) {
        JSONNode jsonNode = processDataFromServer(data);
        if(jsonNode != null) {
            int error = jsonNode["error"].AsInt;
            if(error >= ErrorCode.Err_None) {
                fireEventSyncDataDone();
            } else {
                switch(error) {
                case ErrorCode.Err_Write_Failed:
                case ErrorCode.Err_Invalid_Params:
                {
                    //Write fail
                    //Sign out
                    break;
                }
                default:
                {
                    fireEventConnectFail();
                    break;
                }
                }
            }
        } else {
            //fail
            fireEventConnectFail();
        }
    }
 
 
    public void fireEventSyncDataDone() {
        EventDelegate.Execute(onSyncDataDone);
    }
 
    public void fireEventConnectFail() {
        EventDelegate.Execute(onConnectFail);
    }
}

– Vậy là chúng ta đã kết thúc loạt bài viết về save game, thật sự thì vấn đề này khá rộng lớn và chứ đụng nhiều sơ sót trong quá trình thực hiện, bài viết chỉ mang tính chất tham khảo ý tưởng, khi đưa vào sản phẩm thực sự chúng ta cần cải tiến rất nhiều (có điều kiện mình sẽ nói thêm về chủ đề này).

– Nếu có bất kỳ thắc mắc nào các bạn có thể comment trực tiếp để mọi người cùng thảo luận và học hỏi lẫn nhau.

Cảm ơn các bạn đã quan tâm theo dõi và hẹn gặp lại các bạn ở những series tiếp theo.

Nếu thấy thích thì nhấn nút Like bên dưới, thấy hay thì share giúp mình. Bye bye ^^.
Bạn bình luận ngay tại đây
Ai đang xem chủ đề này?
Guest
Di chuyển  
Bạn không thể tạo chủ đề mới trong diễn đàn này.
Bạn không thể trả lời chủ đề trong diễn đàn này.
Bạn không thể xóa bài của bạn trong diễn đàn này.
Bạn không thể sửa bài của bạn trong diễn đàn này.
Bạn không thể tạo bình chọn trong diễn đàn này.
Bạn không thể bỏ phiếu bình chọn trong diễn đàn này.

Powered by YAF 2.1.0 | YAF © 2003-2024, Yet Another Forum.NET
Thời gian xử lý trang này hết 0.079 giây.