以下是一个基于Mirror的多人连接管理及房间系统的服务端实现方案,包含部署说明:
一、服务端架构设计
-
网络管理扩展
using Mirror;
using UnityEngine;public class RoomNetworkManager : NetworkManager
{
// 房间字典(房间ID -> 房间对象)
public static Dictionary<string, Room> rooms = new Dictionary<string, Room>();public override void OnServerConnect(NetworkConnection conn) { base.OnServerConnect(conn); Debug.Log($"客户端 {conn.connectionId} 已连接"); } public override void OnServerDisconnect(NetworkConnection conn) { // 处理玩家断开逻辑 var player = conn.identity.GetComponent<NetworkPlayer>(); if (player != null && player.CurrentRoom != null) { player.CurrentRoom.RemovePlayer(player); } base.OnServerDisconnect(conn); Debug.Log($"客户端 {conn.connectionId} 已断开"); }
}
-
房间类实现
public class Room
{
public string RoomID { get; } = Guid.NewGuid().ToString().Substring(0, 8);
public string RoomName { get; set; }
public int MaxPlayers { get; } = 4;
public bool IsPlaying { get; set; }public List<NetworkPlayer> Players { get; } = new List<NetworkPlayer>(); public NetworkPlayer Host => Players.FirstOrDefault(); public bool AddPlayer(NetworkPlayer player) { if (Players.Count >= MaxPlayers || IsPlaying) return false; Players.Add(player); player.CurrentRoom = this; player.RpcJoinRoomSuccess(RoomID); UpdateAllPlayers(); return true; } public void RemovePlayer(NetworkPlayer player) { Players.Remove(player); player.CurrentRoom = null; UpdateAllPlayers(); if (Players.Count == 0) { RoomNetworkManager.rooms.Remove(RoomID); } } private void UpdateAllPlayers() { foreach (var p in Players) { p.RpcUpdateRoomInfo(GetRoomInfo()); } } public RoomInfo GetRoomInfo() => new RoomInfo { roomId = RoomID, playerCount = Players.Count, hostName = Host?.PlayerName };
}
-
玩家网络对象
public class NetworkPlayer : NetworkBehaviour
{
[SyncVar] public string PlayerName;
[SyncVar] public bool IsReady;
public Room CurrentRoom;[Command] public void CmdCreateRoom(string roomName) { Room newRoom = new Room { RoomName = roomName }; RoomNetworkManager.rooms.Add(newRoom.RoomID, newRoom); newRoom.AddPlayer(this); } [Command] public void CmdJoinRoom(string roomId) { if (RoomNetworkManager.rooms.TryGetValue(roomId, out Room room)) { if (!room.AddPlayer(this)) { TargetJoinRoomFailed("房间已满或游戏已开始"); } } else { TargetJoinRoomFailed("房间不存在"); } } [TargetRpc] public void TargetJoinRoomFailed(string reason) { /* 客户端处理 */ } [Command] public void CmdStartGame() { if (CurrentRoom.Host != this) return; CurrentRoom.IsPlaying = true; ServerChangeScene("GameScene"); }
}
二、部署流程
-
服务器构建
使用Headless模式构建Linux服务器
Unity.exe -batchmode -nographics -buildTarget Linux64 -buildPath ServerBuild -quit
-
服务器配置
// NetworkManager配置
public class ServerConfig : MonoBehaviour
{
void Start()
{
// 设置服务器参数
Transport.activeTransport = GetComponent<TelepathyTransport>();
GetComponent<RoomNetworkManager>().networkAddress = "0.0.0.0";
GetComponent<RoomNetworkManager>().StartServer();
}
}
- **网络要求
-
开放端口:7777(默认TCP/UDP)
-
建议使用固定公网IP或DDNS
-
推荐服务器配置:
-
最低:2核CPU / 4GB RAM(支持50人同时在线)
-
推荐:4核CPU / 8GB RAM(支持200人同时在线)
-
三、客户端交互示例
-
创建房间
public void CreateRoom(string roomName)
{
NetworkClient.localPlayer.GetComponent<NetworkPlayer>().CmdCreateRoom(roomName);
}
-
加入房间
public void JoinRoom(string roomId)
{
NetworkClient.localPlayer.GetComponent<NetworkPlayer>().CmdJoinRoom(roomId);
}
四、优化建议
-
心跳检测
// 添加心跳机制防止假连接
[System.Serializable]
public class HeartbeatConfig
{
public float Interval = 5f;
public float Timeout = 15f;
}
-
房间清理
void CleanEmptyRooms()
{
var emptyRooms = rooms.Values.Where(r => r.Players.Count == 0).ToList();
foreach (var room in emptyRooms)
{
rooms.Remove(room.RoomID);
}
}
五、安全措施
-
数据验证
[Command]
public void CmdSendChat(string message)
{
// 防止注入攻击
if (message.Length > 100) return;
if (message.Contains("<script>")) return;RpcReceiveChat(PlayerName, message);
}
-
频率限制
Dictionary<NetworkConnection, float> lastCommandTimes = new Dictionary<NetworkConnection, float>();
bool CheckRateLimit(NetworkConnection conn)
{
if (lastCommandTimes.TryGetValue(conn, out float lastTime))
{
if (Time.time - lastTime < 0.5f) return false;
}
lastCommandTimes[conn] = Time.time;
return true;
}
该方案实现了完整的房间管理功能,支持:创建房间、自动房间ID生成、玩家数量限制、游戏状态管理、断线处理等核心功能。部署时需根据实际并发量调整服务器配置,建议配合数据库实现持久化存储。