Unity 服务器交互开发指南

发布于:2025-06-12 ⋅ 阅读:(14) ⋅ 点赞:(0)

在 Unity 中实现客户端与服务器的交互是网络游戏和应用开发的核心部分。以下是全面的 Unity 服务器交互解决方案。

1. 常见通信协议

1.1 HTTP/HTTPS 协议

  • 适用场景:账号系统、商城、排行榜等非实时交互

  • 实现方式

using UnityEngine.Networking;

IEnumerator GetRequest(string uri) {
    using (UnityWebRequest webRequest = UnityWebRequest.Get(uri)) {
        yield return webRequest.SendWebRequest();
        
        if (webRequest.result == UnityWebRequest.Result.Success) {
            Debug.Log("Received: " + webRequest.downloadHandler.text);
        } else {
            Debug.LogError("Error: " + webRequest.error);
        }
    }
}

1.2 WebSocket 协议

  • 适用场景:实时聊天、多人游戏同步

  • 实现方式

using WebSocketSharp;

WebSocket ws = new WebSocket("ws://yourserver:port");

ws.OnMessage += (sender, e) => {
    Debug.Log("Message received: " + e.Data);
};

ws.Connect();
ws.Send("Hello Server");

1.3 TCP/UDP 自定义协议

  • 适用场景:MMORPG、FPS等需要高性能实时交互的游戏

  • 推荐库:LiteNetLib, ENET

2. 数据格式处理

2.1 JSON

// 序列化
string json = JsonUtility.ToJson(playerData);

// 反序列化
PlayerData data = JsonUtility.FromJson<PlayerData>(json);

2.2 Protocol Buffers

// 定义 .proto 文件
message Player {
    required string name = 1;
    optional int32 level = 2;
}

// C# 中使用
Player player = new Player { Name = "John", Level = 10 };
using (MemoryStream stream = new MemoryStream()) {
    Serializer.Serialize(stream, player);
    byte[] data = stream.ToArray();
    // 发送数据...
}

3. 通信架构设计

3.1 请求-响应模式

public class NetworkManager : MonoBehaviour {
    private static NetworkManager _instance;
    public static NetworkManager Instance { get { return _instance; } }
    
    void Awake() {
        if (_instance != null && _instance != this) {
            Destroy(this.gameObject);
        } else {
            _instance = this;
            DontDestroyOnLoad(gameObject);
        }
    }
    
    public void SendRequest(RequestType type, Action<Response> callback) {
        // 实现请求发送和回调处理
    }
}

3.2 消息推送模式

public class MessageDispatcher : MonoBehaviour {
    private Queue<NetworkMessage> _messageQueue = new Queue<NetworkMessage>();
    
    void Update() {
        lock (_messageQueue) {
            while (_messageQueue.Count > 0) {
                ProcessMessage(_messageQueue.Dequeue());
            }
        }
    }
    
    public void EnqueueMessage(NetworkMessage msg) {
        lock (_messageQueue) {
            _messageQueue.Enqueue(msg);
        }
    }
}

4. 安全考虑

4.1 数据加密

// AES加密示例
public static string Encrypt(string plainText, string key) {
    byte[] iv = new byte[16];
    byte[] array;
    
    using (Aes aes = Aes.Create()) {
        aes.Key = Encoding.UTF8.GetBytes(key);
        aes.IV = iv;
        
        ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
        
        using (MemoryStream memoryStream = new MemoryStream()) {
            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) {
                using (StreamWriter streamWriter = new StreamWriter(cryptoStream)) {
                    streamWriter.Write(plainText);
                }
                array = memoryStream.ToArray();
            }
        }
    }
    
    return Convert.ToBase64String(array);
}

4.2 防作弊措施

  • 服务器端数据验证

  • 关键逻辑放在服务器端

  • 使用时间戳和随机数防止重放攻击

5. 断线重连处理

public class ReconnectManager : MonoBehaviour {
    private int _retryCount = 0;
    private const int MAX_RETRY = 3;
    
    public void HandleDisconnect() {
        if (_retryCount < MAX_RETRY) {
            _retryCount++;
            StartCoroutine(ReconnectAfterDelay(5f));
        } else {
            ShowReconnectFailed();
        }
    }
    
    IEnumerator ReconnectAfterDelay(float delay) {
        yield return new WaitForSeconds(delay);
        ConnectToServer();
    }
}

6. 性能优化

6.1 数据压缩

using Ionic.Zlib;

// 压缩
byte[] compressed = ZlibStream.CompressBuffer(data);

// 解压
byte[] decompressed = ZlibStream.UncompressBuffer(compressed);

6.2 带宽优化

  • 使用Delta压缩(只发送变化的数据)

  • 优化协议字段(使用更小的数据类型)

  • 合并小数据包

7. 测试与调试

7.1 本地测试服务器

# 简单Python HTTP测试服务器
from http.server import BaseHTTPRequestHandler, HTTPServer

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        self.wfile.write(b'{"status": "ok"}')

HTTPServer(('localhost', 8000), Handler).serve_forever()

8. 实际应用示例:玩家登录系统

public class LoginSystem : MonoBehaviour {
    private const string LOGIN_URL = "https://yourserver.com/api/login";
    
    public void Login(string username, string password) {
        StartCoroutine(LoginCoroutine(username, password));
    }
    
    private IEnumerator LoginCoroutine(string username, string password) {
        WWWForm form = new WWWForm();
        form.AddField("username", username);
        form.AddField("password", password);
        
        using (UnityWebRequest www = UnityWebRequest.Post(LOGIN_URL, form)) {
            yield return www.SendWebRequest();
            
            if (www.result != UnityWebRequest.Result.Success) {
                Debug.LogError("Login failed: " + www.error);
                yield break;
            }
            
            LoginResponse response = JsonUtility.FromJson<LoginResponse>(www.downloadHandler.text);
            if (response.success) {
                // 登录成功处理
            } else {
                // 登录失败处理
            }
        }
    }
}

[System.Serializable]
public class LoginResponse {
    public bool success;
    public string token;
    public PlayerData player;
}


网站公告

今日签到

点亮在社区的每一天
去签到