在C#上实现异步游戏服务器的有效方法

时间:2016-04-06 20:01:16

标签: c# asynchronous networking server

我一直在为MMO服务器开发宠物项目框架。只是为了提高技能。有很多教程,但通常它不包含细节。

使用async / await。

async void StartReceive()
{
    while (mTcpClient.Connected)
    {
        var stream = mTcpClient.GetStream();
        try
        {

            //read header
            byte[] headerBuffer = new byte[sizeof(int)];
            int read = 0;
            while (read < sizeof(int))
            {
                read += await stream.ReadAsync(headerBuffer, 0, sizeof(int) - read).ConfigureAwait(false);
            }

            //read body
            read = 0;
            int messageSize = BitConverter.ToInt32(headerBuffer, 0);
            byte[] messageBuffer = new byte[messageSize];

            while (read < messageSize)
            {
                read += await stream.ReadAsync(messageBuffer, read, messageSize - read).ConfigureAwait(false);
            }

            //parse and proccess message
            ProcessMessage(messageBuffer);
        }
        catch (Exception ex)
        {
            ...
        }
    }
}

async void ProcessMessage(byte[] buffer)
{
    var message = await ParseMessageAsync(buffer).ConfigureAwait(false);
    if (OnReceived != null)
        OnReceived(this, message);
}

Task<IMessage> ParseMessageAsync(byte[] buffer)
{
    return Task<IMessage>.Factory.StartNew(() =>
    {
        var header = MessageHeader.Parser.ParseFrom(buffer);
        return MessagingReflection.Descriptor.MessageTypes[header.Type].Parser.ParseFrom(header.Data);
    });
}

如果我的理解正确,将生成两个方法并在池中的未知线程中调用。第一种方法包括&#34;读取身体&#34;和&#34;解析和处理&#34;零件,第二个 - &#34;解析和过程&#34;。 这意味着当sizeof(int)的读取结束时,某些线程将被释放,并且将运行一些其他线程以继续读取。

  • 最好是同步继续阅读邮件正文 阅读标题结果完成的线程? (我的意思是使用 在异步读取头之后,为body进行同步读取)。在我的 案例信息应该非常简单和紧凑。但是它 对任何案件都很有意思。
  • ProcessMessage运行等待Google.Protobuf解析的任务。然后将调用OnReceived委托。如果处理程序正在做一些繁重的工作,客户端可以断开与主机的连接。如果客户端断开连接,有什么方法可以正确停止任务?
  • 我有两个代表 - OnReceived和OnDisconnected。第一个在收到完整的消息缓冲区时调用,第二个在StartReceived()中抛出异常时调用。此委托同时受到限制,但在catch块中,OnDisconnected始终等于null!我无法理解为什么(在这种情况下OnReceived仍然不为null,但OnDisconnect已经消失了!)。有人可以解释它为什么会发生吗?

(分配代表示例)

public class ServerTest
{
    List<Client> mClients = new List<Client>();
    ConectionService mConnectionService = new ConectionService(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555));

    public ServerTest()
    {
        mConnectionService.OnClientConnected += OnClientConnected;
        mConnectionService.Start();
    }

    public void OnClientConnected(Client client)
    {
        client.OnDisconnected += OnDisconnected;
        client.OnReceived += OnDataReceived;
        mClients.Add(client);
    }

    public void OnDisconnected(Client client)
    {
        Console.WriteLine("Server: client disconnected");
    }

    public void OnDataReceived(Client client, IMessage message)
    {
        var res = new LoginResponce() { Status = true };
        client.SendMessage(LoginResponce.Descriptor, res);
    }
}

0 个答案:

没有答案