Unity使用Socket與後臺連線,包含Json的讀寫
阿新 • • 發佈:2019-01-27
在做遊戲開發,最近正在將前端與後臺連線,就寫一下筆記記錄一下吧!
我用的是Socket與後臺進行連線,資料的傳輸用的是Json格式。也是從零做起的,以前沒有與伺服器連線的經驗,所以也是結合了網上一些資料。首先說一下總體思路吧,這裡沒有用非同步,採用的是新建了執行緒,來接收資料,並存到佇列進行呼叫解析。
Socket的建立和連結:
using UnityEngine; using System.Collections.Generic; using System.Collections;using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; public class TcpClientHandler:MonoBehaviour { Socket serverSocket; //伺服器端socket private string ClientIP = "192.168.1.139";//IP地址,改成自己的 IPAddress ip; //主機ip IPEndPoint ipEnd; string recvStr; //接收的字串 string sendStr; //傳送的字串 byte[] recvData=new byte[1024]; //接收的資料,必須為位元組 byte[] sendData=new byte[1024]; //傳送的資料,必須為位元組 int recvLen = 0; //接收的資料長度 Thread connectThread; //連線執行緒 private Queue<string> queue = new Queue<string> ();//新建一個佇列,用來儲存伺服器發來的資料 //伺服器初始化 public void InitSocket() { ip=IPAddress.Parse(ClientIP); ipEnd=new IPEndPoint(ip,8009); //伺服器埠號,自己改 //開啟一個執行緒連線 connectThread=new Thread(new ThreadStart(SocketReceive)); connectThread.Start(); } //接收伺服器訊息 void SocketConnet() { if(serverSocket!=null) serverSocket.Close(); //定義套接字型別,必須在子執行緒中定義 serverSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); //連線 serverSocket.Connect(ipEnd); recvLen=serverSocket.Receive(recvData); recvStr=Encoding.UTF8.GetString(recvData,0,recvLen); print(recvStr); queue.Enqueue (recvStr); } public void SocketSend(string sendStr) { //清空傳送快取 sendData=new byte[1024]; //資料型別轉換 sendData=Encoding.UTF8.GetBytes(sendStr); //傳送 serverSocket.Send(sendData,sendData.Length,SocketFlags.None); } void SocketReceive() { SocketConnet(); //不斷接收伺服器發來的資料 while(true) { recvData=new byte[1024]; recvLen=serverSocket.Receive(recvData); if(recvLen==0) { SocketConnet(); continue; } recvStr=Encoding.UTF8.GetString(recvData,0,recvLen); queue.Enqueue (recvStr); print(recvStr); } } //返回接收到的字串 public string GetRecvStr() { string returnStr; //加鎖防止字串被改 lock(this) { if (queue.Count > 0) {//佇列內有資料時,取出 returnStr = queue.Dequeue (); return returnStr; } } return null; } public void SocketQuit() { //關閉執行緒 if(connectThread!=null) { connectThread.Interrupt(); connectThread.Abort(); } //最後關閉伺服器 if(serverSocket!=null) serverSocket.Close(); } }
然後在另一個指令碼啟動伺服器:
using UnityEngine; using System.Collections; using LitJson; using UnityEngine.SceneManagement; public class TcpTest:MonoBehaviour { public static TcpTest _instance; TcpClientHandler tcpClient; JsonData returnDataJson; void Awake(){ DontDestroyOnLoad (this.gameObject); } // Use this for initialization void Start() { //初始化網路連線 //tcpClient=new TcpClientHandler(); tcpClient=gameObject.AddComponent<TcpClientHandler>(); tcpClient.InitSocket(); } // Update is called once per frame void Update() { returnDataHandle (); } //伺服器返回訊息的處理 void returnDataHandle(){ returnData = tcpClient.GetRecvStr (); //print (returnData); if (returnData != null){ returnDataJson = JsonMapper.ToObject (returnData); switch(returnDataJson["cmd"].ToString()){ //在此處解析Json,如有專案需要,最好在其他指令碼編寫,此處只為方便 } } } void OnApplicationQuit() { //退出時關閉連線 tcpClient.SocketQuit(); print ("Quit"); } public void closeC(){//此處比較關鍵,因為在我們除錯時,關閉程式Unity並不一定認為你是退出,所以上面程式碼也許不會執行,導致與伺服器一直連線,Unity崩潰 tcpClient.SocketQuit(); print ("closeC"); } }
最後說一下Json的處理,首先要匯入LitJson庫,然後在指令碼中using LitJson。
傳送資料舉例:
//註冊 public void RegisterEvent(string username, string password){ JsonData registerJson = new JsonData (); registerJson ["cmd"] = "Login|register"; registerJson ["name"] = "wyq"; registerJson ["tel"] = username; registerJson ["psd"] = password; string registrStr = registerJson.ToJson(); tcpClient.SocketSend (registrStr); }
接收的處理上面程式碼中已有部分介紹,在獲取json資料後,進行解析呼叫即可。