NetSimplifyServer.cs 8.04 KB
using HslCommunication.Core.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace HslCommunication.Enthernet
{

    /// <summary>
    /// 异步消息处理服务器,主要用来实现接收客户端信息并进行消息反馈的操作,适用于客户端进行远程的调用,要求服务器反馈数据。
    /// </summary>
    /// <remarks>
    /// 详细的使用说明,请参照博客<a href="http://www.cnblogs.com/dathlin/p/7697782.html">http://www.cnblogs.com/dathlin/p/7697782.html</a>
    /// </remarks>
    /// <example>
    /// 此处贴上了Demo项目的服务器配置的示例代码
    /// <code lang="cs" source="TestProject\SimplifyNetTest\FormServer.cs" region="Simplify Net" title="NetSimplifyServer示例" />
    /// </example>
    public class NetSimplifyServer : NetworkAuthenticationServerBase
    {
        #region Constructor

        /// <summary>
        /// 实例化一个服务器消息请求的信息
        /// </summary>
        public NetSimplifyServer()
        {

        }

        #endregion

        #region Event Handle

        /// <summary>
        /// 接收字符串信息的事件
        /// </summary>
        public event Action<AppSession, NetHandle, string> ReceiveStringEvent;

        /// <summary>
        /// 接收字符串数组信息的事件
        /// </summary>
        public event Action<AppSession, NetHandle, string[]> ReceiveStringArrayEvent;

        /// <summary>
        /// 接收字节信息的事件
        /// </summary>
        public event Action<AppSession, NetHandle, byte[]> ReceivedBytesEvent;


        private void OnReceiveStringEvent( AppSession session, int customer, string str )
        {
            ReceiveStringEvent?.Invoke( session, customer, str );
        }

        private void OnReceivedBytesEvent( AppSession session, int customer, byte[] temp )
        {
            ReceivedBytesEvent?.Invoke( session, customer, temp );
        }

        private void OnReceiveStringArrayEvent( AppSession session, int customer, string[] str )
        {
            ReceiveStringArrayEvent?.Invoke( session, customer, str );
        }

        #endregion

        #region Public Method

        /// <summary>
        /// 向指定的通信对象发送字符串数据
        /// </summary>
        /// <param name="session">通信对象</param>
        /// <param name="customer">用户的指令头</param>
        /// <param name="str">实际发送的字符串数据</param>
        public void SendMessage( AppSession session, int customer, string str )
        {
            SendBytesAsync( session, HslProtocol.CommandBytes( customer, Token, str ) );
        }

        /// <summary>
        /// 向指定的通信对象发送字符串数组
        /// </summary>
        /// <param name="session">通信对象</param>
        /// <param name="customer">用户的指令头</param>
        /// <param name="str">实际发送的字符串数组</param>
        public void SendMessage( AppSession session, int customer, string[] str )
        {
            SendBytesAsync( session, HslProtocol.CommandBytes( customer, Token, str ) );
        }

        /// <summary>
        /// 向指定的通信对象发送字节数据
        /// </summary>
        /// <param name="session">连接对象</param>
        /// <param name="customer">用户的指令头</param>
        /// <param name="bytes">实际的数据</param>
        public void SendMessage( AppSession session, int customer, byte[] bytes )
        {
            SendBytesAsync( session, HslProtocol.CommandBytes( customer, Token, bytes ) );
        }

        #endregion

        #region Start Close

        /// <summary>
        /// 关闭网络的操作
        /// </summary>
        protected override void CloseAction()
        {
            ReceivedBytesEvent = null;
            ReceiveStringEvent = null;
            base.CloseAction( );
        }


        /// <summary>
        /// 当接收到了新的请求的时候执行的操作
        /// </summary>
        /// <param name="socket">异步对象</param>
        /// <param name="endPoint">终结点</param>
        protected override void ThreadPoolLogin( Socket socket, IPEndPoint endPoint )
        {
            AppSession session = new AppSession( );

            session.WorkSocket = socket;
            try
            {
                session.IpEndPoint = endPoint;
                session.IpAddress = session.IpEndPoint.Address.ToString( );
            }
            catch (Exception ex)
            {
                LogNet?.WriteException( ToString( ), StringResources.Language.GetClientIpaddressFailed, ex );
            }

            LogNet?.WriteDebug( ToString( ), string.Format( StringResources.Language.ClientOnlineInfo, session.IpEndPoint ) );
            System.Threading.Interlocked.Increment( ref clientCount );
            ReBeginReceiveHead( session, false );
        }

        /// <summary>
        /// 处理异常的方法
        /// </summary>
        /// <param name="session">会话</param>
        /// <param name="ex">异常信息</param>
        internal override void SocketReceiveException( AppSession session, Exception ex )
        {
            session.WorkSocket?.Close( );
            System.Threading.Interlocked.Decrement( ref clientCount );
            LogNet?.WriteDebug( ToString( ), string.Format( StringResources.Language.ClientOfflineInfo, session.IpEndPoint ) );
        }

        /// <summary>
        /// 正常下线
        /// </summary>
        /// <param name="session">会话</param>
        internal override void AppSessionRemoteClose( AppSession session )
        {
            session.WorkSocket?.Close( );
            System.Threading.Interlocked.Decrement( ref clientCount );
            LogNet?.WriteDebug( ToString( ), string.Format( StringResources.Language.ClientOfflineInfo, session.IpEndPoint ) );
        }

        /// <summary>
        /// 数据处理中心
        /// </summary>
        /// <param name="session">当前的会话</param>
        /// <param name="protocol">协议指令头</param>
        /// <param name="customer">客户端信号</param>
        /// <param name="content">触发的消息内容</param>
        internal override void DataProcessingCenter( AppSession session, int protocol, int customer, byte[] content )
        {
            //接收数据完成,进行事件通知,优先进行解密操作
            if (protocol == HslProtocol.ProtocolCheckSecends)
            {
                // 初始化时候的测试消息
                session.HeartTime = DateTime.Now;
                SendMessage( session, customer, content );
            }
            else if (protocol == HslProtocol.ProtocolUserBytes)
            {
                // 字节数据
                OnReceivedBytesEvent( session, customer, content );
            }
            else if (protocol == HslProtocol.ProtocolUserString)
            {
                // 字符串数据
                OnReceiveStringEvent( session, customer, Encoding.Unicode.GetString( content ) );
            }
            else if (protocol == HslProtocol.ProtocolUserStringArray)
            {
                // 字符串数组
                OnReceiveStringArrayEvent( session, customer, HslProtocol.UnPackStringArrayFromByte( content ) );
            }
            else
            {
                // 数据异常
                AppSessionRemoteClose( session );
            }
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// 当前在线的客户端数量
        /// </summary>
        public int ClientCount => clientCount;

        #endregion

        #region Private Member

        private int clientCount = 0;                                    // 在线客户端的数量

        #endregion

        #region Object Override


        /// <summary>
        /// 返回表示当前对象的字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString( )
        {
            return "NetSimplifyServer";
        }


        #endregion
    }
}