国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

unity 聯(lián)網(wǎng)的游戲后端服務(wù)器框架和語言

這篇具有很好參考價值的文章主要介紹了unity 聯(lián)網(wǎng)的游戲后端服務(wù)器框架和語言。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

作者:蟑螂惡霸
鏈接:https://www.zhihu.com/question/381711152/answer/3083699647
來源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
?

本文將從以下幾個方面來講解Unity客戶端網(wǎng)絡(luò)架構(gòu)的設(shè)計與實現(xiàn):

1.網(wǎng)絡(luò)通信協(xié)議的選擇

2.客戶端網(wǎng)絡(luò)框架的設(shè)計

3.網(wǎng)絡(luò)通信的實現(xiàn)

4.代碼實現(xiàn)

對啦!這里有個游戲開發(fā)交流小組里面聚集了一幫熱愛學(xué)習(xí)游戲的零基礎(chǔ)小白,也有一些正在從事游戲開發(fā)的技術(shù)大佬,歡迎你來交流學(xué)習(xí)。

一、網(wǎng)絡(luò)通信協(xié)議的選擇

網(wǎng)絡(luò)通信協(xié)議是實現(xiàn)客戶端與服務(wù)器之間通信的基礎(chǔ),目前常用的網(wǎng)絡(luò)通信協(xié)議有TCP和UDP兩種。

TCP協(xié)議是面向連接的協(xié)議,具有可靠性高、穩(wěn)定性好的特點,但是在傳輸大量數(shù)據(jù)時,效率較低。

UDP協(xié)議是無連接的協(xié)議,傳輸效率高,但是可靠性不如TCP。

在Unity客戶端網(wǎng)絡(luò)架構(gòu)的設(shè)計中,需要根據(jù)實際情況選擇合適的網(wǎng)絡(luò)通信協(xié)議。如果是對網(wǎng)絡(luò)傳輸?shù)姆€(wěn)定性和可靠性有要求的游戲,如MOBA游戲,就需要選擇TCP協(xié)議。如果是對網(wǎng)絡(luò)傳輸?shù)男视幸蟮挠螒?,如射擊游戲,就需要選擇UDP協(xié)議。

二、客戶端網(wǎng)絡(luò)框架的設(shè)計

在Unity客戶端網(wǎng)絡(luò)架構(gòu)的設(shè)計中,需要考慮以下幾個方面:

1.網(wǎng)絡(luò)連接的建立與斷開

2.消息的發(fā)送與接收

3.消息的封裝與解析

4.消息的處理與回調(diào)

網(wǎng)絡(luò)連接的建立與斷開

在客戶端網(wǎng)絡(luò)框架的設(shè)計中,需要實現(xiàn)網(wǎng)絡(luò)連接的建立與斷開。網(wǎng)絡(luò)連接的建立需要指定服務(wù)器的IP地址和端口號,通過Socket類建立TCP或UDP連接。網(wǎng)絡(luò)連接的斷開需要釋放Socket資源,關(guān)閉網(wǎng)絡(luò)連接。

消息的發(fā)送與接收

在客戶端網(wǎng)絡(luò)框架的設(shè)計中,需要實現(xiàn)消息的發(fā)送與接收。消息的發(fā)送需要將消息封裝成字節(jié)流,通過Socket類發(fā)送到服務(wù)器;消息的接收需要通過Socket類接收服務(wù)器發(fā)送的消息字節(jié)流,并將其解析成消息對象。

消息的封裝與解析

在客戶端網(wǎng)絡(luò)框架的設(shè)計中,需要實現(xiàn)消息的封裝與解析。消息的封裝需要將消息對象轉(zhuǎn)換成字節(jié)流,以便發(fā)送到服務(wù)器;消息的解析需要將服務(wù)器發(fā)送的字節(jié)流轉(zhuǎn)換成消息對象,以便在客戶端中進行處理。

消息的處理與回調(diào)

在客戶端網(wǎng)絡(luò)框架的設(shè)計中,需要實現(xiàn)消息的處理與回調(diào)。消息的處理需要根據(jù)消息類型進行相應(yīng)的處理,例如登錄消息需要進行賬號驗證;消息的回調(diào)需要在處理完消息后將處理結(jié)果返回給游戲邏輯層,以便進行相應(yīng)的處理。

三、網(wǎng)絡(luò)通信的實現(xiàn)

在Unity客戶端網(wǎng)絡(luò)架構(gòu)的實現(xiàn)中,需要使用Socket類進行網(wǎng)絡(luò)通信。Socket類是.NET Framework提供的用于網(wǎng)絡(luò)通信的基礎(chǔ)類,支持TCP和UDP兩種協(xié)議。

在使用Socket類進行網(wǎng)絡(luò)通信時,需要考慮以下幾個方面:

1.網(wǎng)絡(luò)連接的建立與斷開

2.消息的發(fā)送與接收

3.消息的封裝與解析

4.消息的處理與回調(diào)

網(wǎng)絡(luò)連接的建立與斷開

使用Socket類建立網(wǎng)絡(luò)連接的方法如下:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

socket.Connect(ip, port);

使用Socket類斷開網(wǎng)絡(luò)連接的方法如下:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

socket.Connect(ip, port);

消息的發(fā)送與接收

使用Socket類發(fā)送消息的方法如下:

byte[] bytes = message.ToBytes();
socket.Send(bytes);

使用Socket類接收消息的方法如下:

byte[] bytes = new byte[1024];
int length = socket.Receive(bytes);
Message message = Message.Parse(bytes, length);

消息的封裝與解析

消息的封裝需要將消息對象轉(zhuǎn)換成字節(jié)流,以便發(fā)送到服務(wù)器。消息的解析需要將服務(wù)器發(fā)送的字節(jié)流轉(zhuǎn)換成消息對象,以便在客戶端中進行處理。消息的封裝與解析可以通過序列化和反序列化來實現(xiàn)。

消息的處理與回調(diào)

消息的處理需要根據(jù)消息類型進行相應(yīng)的處理,例如登錄消息需要進行賬號驗證。消息的回調(diào)需要在處理完消息后將處理結(jié)果返回給游戲邏輯層,以便進行相應(yīng)的處理。

四、代碼實現(xiàn)

以下是一個簡單的Unity客戶端網(wǎng)絡(luò)框架的實現(xiàn),使用TCP協(xié)議進行網(wǎng)絡(luò)通信。該框架實現(xiàn)了網(wǎng)絡(luò)連接的建立與斷開、消息的發(fā)送與接收、消息的封裝與解析、消息的處理與回調(diào)等功能。

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;

public class Client
{
    private Socket socket;
    private byte[] buffer;

    public bool Connect(string ip, int port)
    {
        try
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(ip, port);
            buffer = new byte[1024];
            socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, null);
            return true;
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
            return false;
        }
    }

    public void Disconnect()
    {
        if (socket != null && socket.Connected)
        {
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
        }
    }

    public void Send(Message message)
    {
        byte[] bytes = message.ToBytes();
        socket.Send(bytes);
    }

    private void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            int length = socket.EndReceive(ar);
            if (length > 0)
            {
                Message message = Message.Parse(buffer, length);
                OnMessageReceived(message);
                socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, null);
            }
            else
            {
                Disconnect();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
            Disconnect();
        }
    }

    private void OnMessageReceived(Message message)
    {
        switch (message.Type)
        {
            case MessageType.Login:
                LoginMessage loginMessage = (LoginMessage)message;
                bool success = Login(loginMessage.Username, loginMessage.Password);
                ResponseMessage responseMessage = new ResponseMessage(success);
                Send(responseMessage);
                break;
            case MessageType.Move:
                MoveMessage moveMessage = (MoveMessage)message;
                Move(moveMessage.Direction);
                break;
        }
    }

    private bool Login(string username, string password)
    {
        // TODO: login logic
        return true;
    }

    private void Move(int direction)
    {
        // TODO: move logic
    }
}

public enum MessageType
{
    Login,
    Move
}

public abstract class Message
{
    public MessageType Type { get; protected set; }

    public abstract byte[] ToBytes();

    public static Message Parse(byte[] bytes, int length)
    {
        MessageType type = (MessageType)BitConverter.ToInt32(bytes, 0);
        switch (type)
        {
            case MessageType.Login:
                return LoginMessage.Parse(bytes, length);
            case MessageType.Move:
                return MoveMessage.Parse(bytes, length);
            default:
                throw new ArgumentException("Invalid message type");
        }
    }
}

public class LoginMessage : Message
{
    public string Username { get; private set; }
    public string Password { get; private set; }

    public LoginMessage(string username, string password)
    {
        Type = MessageType.Login;
        Username = username;
        Password = password;
    }

    public override byte[] ToBytes()
    {
        List<byte> bytes = new List<byte>();
        bytes.AddRange(BitConverter.GetBytes((int)Type));
        bytes.AddRange(BitConverter.GetBytes(Username.Length));
        bytes.AddRange(System.Text.Encoding.UTF8.GetBytes(Username));
        bytes.AddRange(BitConverter.GetBytes(Password.Length));
        bytes.AddRange(System.Text.Encoding.UTF8.GetBytes(Password));
        return bytes.ToArray();
    }

    public static LoginMessage Parse(byte[] bytes, int length)
    {
        int offset = 4;
        int usernameLength = BitConverter.ToInt32(bytes, offset);
        offset += 4;
        string username = System.Text.Encoding.UTF8.GetString(bytes, offset, usernameLength);
        offset += usernameLength;
        int passwordLength = BitConverter.ToInt32(bytes, offset);
        offset += 4;
        string password = System.Text.Encoding.UTF8.GetString(bytes, offset, passwordLength);
        return new LoginMessage(username, password);
    }
}

public class MoveMessage : Message
{
    public int Direction { get; private set; }

    public MoveMessage(int direction)
    {
        Type = MessageType.Move;
        Direction = direction;
    }

    public override byte[] ToBytes()
    {
        List<byte> bytes = new List<byte>();
        bytes.AddRange(BitConverter.GetBytes((int)Type));
        bytes.AddRange(BitConverter.GetBytes(Direction));
        return bytes.ToArray();
    }

    public static MoveMessage Parse(byte[] bytes, int length)
    {
        int offset = 4;
        int direction = BitConverter.ToInt32(bytes, offset);
        return new MoveMessage(direction);
    }
}

public class ResponseMessage : Message
{
    public bool Success { get; private set; }

    public ResponseMessage(bool success)
    {
        Type = MessageType.Response;
        Success = success;
    }

    public override byte[] ToBytes()
    {
        List<byte> bytes = new List<byte>();
        bytes.AddRange(BitConverter.GetBytes((int)Type));
        bytes.AddRange(BitConverter.GetBytes(Success));
        return bytes.ToArray();
    }

    public static ResponseMessage Parse(byte[] bytes, int length)
    {
        int offset = 4;
        bool success = BitConverter.ToBoolean(bytes, offset);
        return new ResponseMessage(success);
    }
}

以上代碼實現(xiàn)了一個簡單的Unity客戶端網(wǎng)絡(luò)框架,使用TCP協(xié)議進行網(wǎng)絡(luò)通信。在該框架中,客戶端可以建立和斷開網(wǎng)絡(luò)連接,發(fā)送和接收消息,并對不同類型的消息進行相應(yīng)的處理和回調(diào)。

作者:阿博的game圈
鏈接:https://www.zhihu.com/question/381711152/answer/2548719506
來源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
?

目前能做大型MMORPG ARPG的主流游戲服務(wù)器框架編程語言有:

C++:網(wǎng)絡(luò)庫: libevent, libuv, iocp/epoll, 可靠的UDP網(wǎng)絡(luò)傳送kcp;

序列化與反序列化:protobuf;

協(xié)議加密解密: crypto;

http解析庫: curl;

數(shù)據(jù)庫: mysql, redis, mongodb;

多線程: pthread庫;

服務(wù)短尋路與導(dǎo)航: recastnavigation

行為決策樹: 具體的庫可以github搜索一下;

業(yè)務(wù)邏輯腳本開發(fā): Lua等輕量級嵌入式腳本語言

Java:

網(wǎng)絡(luò)庫: Netty, Mina;

序列化與反序列化:protobuf;

協(xié)議加密解密: crypto;

http解析庫: Java有很多這樣的jar包,可以自行找下;

數(shù)據(jù)庫: mysql, redis, mongodb;

多線程 Java Thread庫;

服務(wù)短尋路與導(dǎo)航: recastnavigation Java版本

行為決策樹: 也有Java版本;

C#和Go不太熟悉,大家可以根據(jù)上面的清單自行去找一下。游戲服務(wù)端的框架還是建議自己寫,自己粘合。服務(wù)器對穩(wěn)定性要求很好, 所以還是自己寫比較好。:文章來源地址http://www.zghlxwxcb.cn/news/detail-717882.html

到了這里,關(guān)于unity 聯(lián)網(wǎng)的游戲后端服務(wù)器框架和語言的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Microdot是一個可以在micropython中搭建物聯(lián)網(wǎng)web服務(wù)器的框架

    micordot英文官網(wǎng) 只要是支持micropython的設(shè)備都可以使用它 什么是Microdot?Microdot是一個受Flask啟發(fā)的簡約Python Web框架,旨在運行在 資源有限的系統(tǒng),例如微控制器(esp32,esp8266)。它在標(biāo)準(zhǔn)上運行 Python和MicroPython。 [項目需要的所需的Microdot源文件代碼](miguelgrinberg/microdot: The impos

    2024年02月03日
    瀏覽(30)
  • Flask框架小程序后端分離開發(fā)學(xué)習(xí)筆記《3》客戶端向服務(wù)器端發(fā)送請求

    Flask框架小程序后端分離開發(fā)學(xué)習(xí)筆記《3》客戶端向服務(wù)器端發(fā)送請求

    Flask是使用python的后端,由于小程序需要后端開發(fā),遂學(xué)習(xí)一下后端開發(fā)。 可以看到上述代碼構(gòu)建了一個HTTP請求,在發(fā)送之前需要將發(fā)送之前,使用http_request.encode(‘utf-8’)。 這是因為我們在這構(gòu)建的請求是字符串文本,而電腦只認(rèn)識二進制0和1,所以需要將其數(shù)據(jù)類型轉(zhuǎn)換

    2024年01月22日
    瀏覽(39)
  • Unity進階--通過PhotonServer實現(xiàn)聯(lián)網(wǎng)登錄注冊功能(服務(wù)器端)--PhotonServer(二)

    Unity進階--通過PhotonServer實現(xiàn)聯(lián)網(wǎng)登錄注冊功能(服務(wù)器端)--PhotonServer(二)

    如何配置PhotonServer服務(wù)器:https://blog.csdn.net/abaidaye/article/details/132096415 大體結(jié)構(gòu)圖 結(jié)構(gòu)圖示意 BLL層(控制層) 總管理類 控制層接口 登錄注冊控制類 DAL層(數(shù)據(jù)控制層) 總數(shù)據(jù)管理層 登錄注冊數(shù)據(jù)管理層 模型層 登錄注冊層 DLC 服務(wù)器配置類 發(fā)送消息類 以及消息類 服務(wù)器

    2024年02月14日
    瀏覽(30)
  • Unity3D 游戲服務(wù)器怎么實現(xiàn)熱更新詳解

    Unity3D是一款強大的游戲開發(fā)引擎,它不僅可以用于游戲客戶端的開發(fā),還可以用于游戲服務(wù)器的搭建。在游戲開發(fā)過程中,熱更新是一項非常重要的功能,它可以使游戲在不重新啟動的情況下,更新游戲內(nèi)容,修復(fù)bug,提高游戲體驗。本文將詳細(xì)介紹Unity3D游戲服務(wù)器如何實

    2024年01月16日
    瀏覽(22)
  • ioGame21發(fā)布,史詩級增強,Java Netty 輕量級網(wǎng)絡(luò)游戲服務(wù)器框架

    ioGame21發(fā)布,史詩級增強,Java Netty 輕量級網(wǎng)絡(luò)游戲服務(wù)器框架

    標(biāo)題:ioGame21 發(fā)布:史詩級增強,Java Netty 輕量級網(wǎng)絡(luò)游戲服務(wù)器框架 引言 近日,一款名為?ioGame21 的輕量級網(wǎng)絡(luò)游戲服務(wù)器框架在 GitHub 上正式發(fā)布。這款框架基于 Java Netty 構(gòu)建,具有高性能、高可擴展性和易于使用的特點。ioGame21 的發(fā)布將為游戲開發(fā)者提供一個強大的工

    2024年02月19日
    瀏覽(24)
  • C/C++輕量級并發(fā)TCP服務(wù)器框架Zinx-游戲服務(wù)器開發(fā)002:框架學(xué)習(xí)-按照三層結(jié)構(gòu)模式重構(gòu)測試代碼+Tcp數(shù)據(jù)適配+時間輪定時器

    C/C++輕量級并發(fā)TCP服務(wù)器框架Zinx-游戲服務(wù)器開發(fā)002:框架學(xué)習(xí)-按照三層結(jié)構(gòu)模式重構(gòu)測試代碼+Tcp數(shù)據(jù)適配+時間輪定時器

    三層結(jié)構(gòu)重構(gòu)原有功能 自定義消息類,繼承UserData,添加一個成員變量szUserData 定義多個Role類繼承Irole,重寫ProcMsg函數(shù),進行不同處理 定義protocol類,繼承Iprotocol,重寫四個函數(shù),兩個函數(shù)時原始 數(shù)據(jù)和用戶數(shù)據(jù)之間的轉(zhuǎn)換;另兩個用來找消息處理對象和消息發(fā) 送對象。 定

    2024年02月21日
    瀏覽(24)
  • Zinx框架-游戲服務(wù)器開發(fā)002:框架學(xué)習(xí)-按照三層結(jié)構(gòu)模式重構(gòu)測試代碼+Tcp數(shù)據(jù)適配+時間輪定時器

    Zinx框架-游戲服務(wù)器開發(fā)002:框架學(xué)習(xí)-按照三層結(jié)構(gòu)模式重構(gòu)測試代碼+Tcp數(shù)據(jù)適配+時間輪定時器

    三層結(jié)構(gòu)重構(gòu)原有功能 自定義消息類,繼承UserData,添加一個成員變量szUserData 定義多個Role類繼承Irole,重寫ProcMsg函數(shù),進行不同處理 定義protocol類,繼承Iprotocol,重寫四個函數(shù),兩個函數(shù)時原始 數(shù)據(jù)和用戶數(shù)據(jù)之間的轉(zhuǎn)換;另兩個用來找消息處理對象和消息發(fā) 送對象。 定

    2024年02月05日
    瀏覽(23)
  • unity的學(xué)習(xí),準(zhǔn)備搞一款mmo小游戲,服務(wù)器和客戶端從零學(xué)

    unity的學(xué)習(xí),準(zhǔn)備搞一款mmo小游戲,服務(wù)器和客戶端從零學(xué)

    先學(xué)一下unity,mmo服務(wù)器框架到時候在學(xué)習(xí)一下,暫時服務(wù)器簡單做一下 如代碼所示,簡單了解一下。 我個人感覺不要一個放在Awake函數(shù)中,一個放在Start中。因為這只適合兩個腳本使用,如果多個腳本還是沒有辦法解決腳本執(zhí)行的順序。在這里設(shè)置腳本的執(zhí)行順序,添加進

    2023年04月21日
    瀏覽(26)
  • 騰訊云服務(wù)器+寶塔+后端+前端發(fā)布

    騰訊云服務(wù)器+寶塔+后端+前端發(fā)布

    1、申請云服務(wù)器。登陸。 https://cloud.tencent.com/ ? 創(chuàng)建實例 最好重置密碼,并記住。 ?配置安全組,當(dāng)我們是學(xué)習(xí)的時候,全部開放好了。 ? 有些版本是去“防火墻”那里配置。?輕量應(yīng)用服務(wù)器(試用的) ? ? 2、安裝Docker。在安裝云服務(wù)時,我選了Centos7.8+Docker。這里就不

    2024年02月13日
    瀏覽(40)
  • 【Linux后端服務(wù)器開發(fā)】管道設(shè)計

    【Linux后端服務(wù)器開發(fā)】管道設(shè)計

    目錄 一、管道通信 二、匿名管道 1. 匿名管道通信 2. 匿名管道設(shè)計 三、命名管道 comm.hpp client.cc serve.cc 進程通信 數(shù)據(jù)傳輸:一個進程需要將它的數(shù)據(jù)發(fā)送給另一個進程 資源共享:多個進程之間共享同樣的資源 通知事件:一個進程向另一個(一組)進程發(fā)送信息,通知它們發(fā)

    2024年02月13日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包