Unity网络通信方式之Network

本文介绍了一个基于Unity的游戏网络通信实现方案,包括自定义消息类CustomMessage的定义与使用,客户端和服务端的消息处理流程,以及连接、断开连接和错误处理等关键环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【消息管理】
	public class CustomMessage : MessageBase {
		public const short RecMsg = 1001;
		public string msg = string.Empty;

		public override void Serialize(NetworkWriter writer) {
			writer.Write(msg);
		}
		public override void Deserialize(NetworkReader reader) {
			msg = reader.ReadString();
		}
	}
【客户端】
		public bool connected = false;
		private NetworkClient client;
		private string ipAddress = string.Empty;
		private int port = 0;
		private NetworkConnection netConn = null;
		
		public void OpenClient() {
			client.RegisterHandler(MsgType.Connect, OnConnectedServer);
			client.RegisterHandler(MsgType.Disconnect, OnDisconnectedServer);
			client.RegisterHandler(MsgType.Error, OnError);

			client.RegisterHandler(CustomMessage.RecMsg, OnRecieveMessage);

			client.Connect(ipAddress, port);
			connected = true;
			Debug.Log("Client opened.");
		}

		public void CloseClient() {
			client.Disconnect();
			connected = false;
			Debug.Log("Client closed.");
		}

		public void OnSendMessage(string msg) {
			CustomMessage customMessage = new CustomMessage();
			customMessage.msg = msg;
			netConn.Send(CustomMessage.RecMsg, customMessage);
		}

		private void OnRecieveMessage(NetworkMessage netMsg) {
			CustomMessage customMessage = new CustomMessage();
			customMessage.Deserialize(netMsg.reader);

			if (customMessage.msg != null && customMessage.msg != string.Empty && customMessage.msg != message) {
				message = customMessage.msg;
				string prefix = message.Split(':')[0];
				switch (prefix) {
					case "AllowClientOnline": {
							int.TryParse(message.Split(':')[1], out videoIndex);
							BufferVideo();

							long time = 0;
							long.TryParse(message.Split(':')[3], out time);
							videoPlayer.frame = time;
							videoTimeSlider.value = time / videoPlayer.frameRate;

							if (message.Split(':')[2] == "True") {
								videoPlayer.Play();
							}else if (message.Split(':')[2] == "False") {
								videoPlayer.Pause();
							}
						}
						break;
					case "VideoChanged": {
							int.TryParse(message.Split(':')[1], out videoIndex);
							BufferVideo();
							videoTimeSlider.value = 0;
						}
						break;
					case "VideoStateChanged": {
							if (message.Split(':')[1] == "True") {
								videoPlayer.Play();
							}else if (message.Split(':')[1] == "False") {
								videoPlayer.Pause();
							}
						}
						break;
				}
			}
		}

		private void OnConnectedServer(NetworkMessage netMsg) {
			netConn = netMsg.conn;
			connected = true;
			Debug.Log("I am client , I connect server.");
		}

		private void OnDisconnectedServer(NetworkMessage netMsg) {
			netConn = null;
			connected = false;
			Debug.Log("I am client , I disconnect server.");
		}

		private void OnError(NetworkMessage netMsg) {
			connected = false;
			Debug.Log("I am client , there is an error.");
		}
【服务端】
		private bool opened = false;
		private string ipAddress = string.Empty;
		private int port = 0;
		private int maxConnectCount = 10;
		private int connIndex = 1;
		private Dictionary<int, NetworkConnection> netConns = new Dictionary<int, NetworkConnection>();
		private int curConnectCount = 0;

		private void OpenServer() {
			opened = NetworkServer.Listen(ipAddress, port);

			NetworkServer.RegisterHandler(MsgType.Error, OnError);
			NetworkServer.RegisterHandler(MsgType.Disconnect, OnDisconnect);
			NetworkServer.RegisterHandler(MsgType.Connect, OnConnect);

			NetworkServer.RegisterHandler(CustomMessage.RecMsg, OnRecieveMessage);
		}

		private void CloseServer() {
			NetworkServer.dontListen = true;
			opened = false;
		}

		private void OnSendMessage(string msg) {
			CustomMessage customMessage = new CustomMessage();
			customMessage.msg = msg;

			for (int i = 0; i < netConns.Count; i++) {
				netConns[i].Send(CustomMessage.RecMsg, customMessage);
			}
		}

		private void OnSendMessage(string msg, int id) {
			CustomMessage customMessage = new CustomMessage();
			customMessage.msg = msg;
			NetworkServer.SendToClient(id, CustomMessage.RecMsg, customMessage);
		}

		private void OnRecieveMessage(NetworkMessage netMsg) {
			if (!opened) {
				return;
			}
			CustomMessage customMessage = new CustomMessage();
			customMessage.Deserialize(netMsg.reader);

			string prefix = customMessage.msg.Split(':')[0];
			switch (prefix) {
				//

				//
			}
		}

		private void OnConnect(NetworkMessage netMsg) {
			if(connIndex == maxConnectCount) {
				connIndex = 1;
			}

			NetworkConnection conn = netMsg.conn;
			if (!netConns.ContainsKey(connIndex)) {
				netConns.Add(connIndex, conn);
				connIndex++;
				Debug.Log("I am server , a client connected.");
			}
		}

		private void OnDisconnect(NetworkMessage netMsg) {
			NetworkConnection conn = netMsg.conn;
			foreach(KeyValuePair<int,NetworkConnection>pair in netConns) {
				if(pair.Value == conn) {
					conn = null;
					netConns.Remove(pair.Key);
					Debug.Log("I am server , a client disconnected.");
				}
			}
		}

		private void OnError(NetworkMessage netMsg) {
			opened = false;
			Debug.Log("I am server , there is an error.");
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值