新文章 网摘 文章 随笔 日记

自己写的TCP自定义二进制协议(五)

using System.Threading.Tasks;
using BinaryProtocol.Core.Tcp;

namespace BinaryProtocol.Core.Handles
{
    public interface IMessageHandle
    {
        /// <summary>
        /// 解释
        /// </summary>
        void Resolve(byte[] messageBodyBytes);

        /// <summary>
        /// 消费
        /// </summary>
        /// <param name="connectContext"></param>
        Task ConsumeAsync(ConnectContext connectContext);
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BinaryProtocol.Core.Models;
using BinaryProtocol.Core.Tcp;

namespace BinaryProtocol.Core.Handles
{
    /// <summary>
    /// 消息分发器
    /// </summary>
    public class MessageDispatcher
    {
        private static List<MessageHandleMapper> _messageHandleMappers = new List<MessageHandleMapper>();
        public static IReadOnlyCollection<MessageHandleMapper> MessageHandleMappers => _messageHandleMappers;
        /// <summary>
        /// 注册消息处理器
        /// </summary>
        /// <param name="mapper"></param>
        public static void RegisterMessageHandleMapper(MessageHandleMapper mapper)
        {
            if (_messageHandleMappers.Any(r => r.ProtocolType == mapper.ProtocolType && r.MessageType == mapper.MessageType))
            {
                return;
            }
            _messageHandleMappers.Add(mapper);
        }

        public static void Dispatch(MessageHead head, byte[] msgBodyBytes, ConnectContext connectContext)
        {
            //开启一个子任务来处理消息
            Task task = new Task(() =>
              {
                  var mapper = MessageHandleMappers.FirstOrDefault(r =>
                      r.ProtocolType == head.ProtocolType
                      && r.MessageType == head.MessageType);
                  if (mapper == null)
                  {
                      return;
                  }

                  //为了防止死锁,每个消息都new一个处理器
                  var handle = (IMessageHandle)Activator.CreateInstance(mapper.HandleType);

                  //解释消息体
                  handle.Resolve(msgBodyBytes);
                  //消费消息
                  handle.ConsumeAsync(connectContext);
              });
            task.Start();
        }
    }
}
using System.Threading.Tasks;
using BinaryProtocol.Core.Models;
using BinaryProtocol.Core.Tcp;

namespace BinaryProtocol.Core.Handles
{
    /// <summary>
    /// 消息处理器
    /// </summary>
    public abstract class MessageHandle<T> : IMessageHandle
    {
        protected MessageBody<T> MessageBody { get; private set; }

        public virtual void Resolve(byte[] messageBodyBytes)
        {
            //获取消息字段配置信息
            MessageBody = new MessageBody<T>(messageBodyBytes);
        }

        /// <summary>
        /// 消费消息,抽象方法
        /// </summary>
        /// <param name="connectContext"></param>
        public abstract Task ConsumeAsync(ConnectContext  connectContext);
    }
}
using System;

namespace BinaryProtocol.Core.Handles
{
    /// <summary>
    /// 消息处理器映射器
    /// </summary>
    public class MessageHandleMapper
    {
        /// <summary>
        /// 处理器类型
        /// </summary>
        public Type HandleType { get; }
        /// <summary>
        /// 协议类型
        /// </summary>
        public byte ProtocolType { get; }
        /// <summary>
        /// 消息类型
        /// </summary>
        public byte MessageType { get; }
        public MessageHandleMapper(
            byte protocolType, 
            byte messageType,
            Type handleType)
        {
            HandleType = handleType;
            ProtocolType = protocolType;
            MessageType = messageType;
        }
    }
}
using System;
using System.Threading.Tasks;
using BinaryProtocol.Core.Constants;
using BinaryProtocol.Core.Events;
using BinaryProtocol.Core.Models;
using BinaryProtocol.Core.Tcp;

namespace BinaryProtocol.Core.Handles
{
    public class SysMessageHandle : MessageHandle<MessageEvent>
    {
        public override async Task ConsumeAsync(ConnectContext connectContext)
        {
            switch (MessageBody.Value.Command)
            {
                //客户端连接
                case (byte)Command.Connect:
                    SignActive(connectContext);
                    connectContext.LogAction($"收到客户端{connectContext.ClientId}的连接请求");
                    connectContext.ClientId = MessageBody.Value.ClientId;
                    Message<MessageEvent> msg = SysMessageBuilder.CreateConnectResultMessage(MessageBody.Value.ClientId);
                    await connectContext.TcpServer.SendAsync(MessageBody.Value.ClientId, msg);
                    break;
                case (byte)Command.ConnectResult:
                    SignActive(connectContext);
                    connectContext.LogAction($"{connectContext.ClientId}收到服务器的连接响应");
                    break;
                case (byte)Command.HeartBeat:
                    SignActive(connectContext);
                    connectContext.LogAction($"收到{connectContext.ClientId}心跳包");
                    var heartBeatMsg = SysMessageBuilder.CreateHeartBeatResultMessage(MessageBody.Value.ClientId);
                    await connectContext.TcpServer.SendAsync(MessageBody.Value.ClientId, heartBeatMsg);
                    break;
                case (byte)Command.HeartBeatResult:
                    SignActive(connectContext);
                    connectContext.LogAction($"{connectContext.ClientId}收到心跳包响应");
                    break;
            }
        }
        /// <summary>
        /// 标记活动状态
        /// </summary>
        /// <param name="connectContext"></param>
        private void SignActive(ConnectContext connectContext)
        {
            connectContext.LastActiveTime = DateTime.Now;
            connectContext.IsClientActive = true;
        }
    }
}

 

posted @ 2020-10-27 17:06  岭南春  阅读(72)  评论(0)    收藏  举报