Sync Invoke Remoting IOCP Async Invoke


/*
csc /t:library Share.cs
*/
namespace Microshaoft
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Runtime.Remoting;
    using System.Runtime.Remoting.Channels;
    using System.Runtime.Remoting.Channels.Tcp;
    using System.Runtime.Serialization.Formatters;
    public static class RemotingHelper
    {
        public static void StartRemoting
                                (
                                    Type RemotingType
                                    , string Url
                                    , int Port
                                    , WellKnownObjectMode ServiceMode
                                )
        {
            BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
            provider.TypeFilterLevel = TypeFilterLevel.Full;
            IDictionary ht = new Hashtable();
            ht["port"] = Port;
            TcpChannel tc = new TcpChannel(ht, null, provider);
            ChannelServices.RegisterChannel(tc, false);
            RemotingConfiguration.RegisterWellKnownServiceType(RemotingType, Url, ServiceMode);
            Console.WriteLine("Remoting Object Started ...");
        }
        public static void StartRemoting<T>
                                (
                                    string Url
                                    , int Port
                                    , WellKnownObjectMode Mode
                                )
        {
            StartRemoting(typeof(T), Url, Port, Mode);
        }
        public static T GetRemotingLocalClientProxyObject<T>
            (
                string Url
            )
        {
            return (T) Activator.GetObject
                                    (
                                        typeof(T)
                                        , Url
                                    );
        }
    }
}
namespace Microshaoft.RemotingObjects.Share
{
    using System;
    public interface IRemotingIoCP
    {
        void BeginSyncWaitFor(string command);
        void SendCommand(string command);
    }
}
/*
csc /r:Share.dll Server.cs
*/
namespace Microshaoft
{
    using System;
    using System.Threading;
    using System.Runtime.InteropServices;
    using Microsoft.Win32.SafeHandles;
    using Microshaoft.Win32;
    public class IocpHandler<TSessionData, TIocpData>
    {
        public delegate void DataReceivedEventHandler
                                                (
                                                    IocpHandler<TSessionData, TIocpData> sender
                                                    , TIocpData iocp
                                                );
        public event DataReceivedEventHandler DataReceived;
        private bool _running = false;
        private SafeFileHandle _completionPort;
        public void CompleteHandle()
        {
            _running = false;
            _completionPort.Dispose();
        }
        public void SendData(TIocpData data)
        {
            GCHandle gch = GCHandle.Alloc(data);
            unsafe
            {
                NativeMethods.PostQueuedCompletionStatus
                                                    (
                                                        _completionPort
                                                        , (uint) sizeof(IntPtr)
                                                        , IntPtr.Zero
                                                        , (IntPtr) gch
                                                    );
            }
        }
        private TSessionData _sessionData;
        public TSessionData SessionData
        {
            get
            {
                return _sessionData;
            }
        }
        public void BeginSyncWait(TSessionData session)
        {
            _sessionData = session;
            _completionPort = NativeMethods.CreateIoCompletionPort
                                                    (
                                                        new IntPtr(-1)
                                                        , IntPtr.Zero
                                                        , IntPtr.Zero
                                                        , 1
                                                    );
            if(!_completionPort.IsInvalid)
            {
                _running = true;
///                Thread thread = new Thread(Run);
///                thread.Start();
                Run();
            }
        }
        private void Run()
        {
            while (_running)
            {
                uint r = 0;
                IntPtr PerHandleData;
                IntPtr lpOverlapped;
                NativeMethods.GetQueuedCompletionStatus
                                        (
                                            _completionPort
                                            , out r
                                            , out PerHandleData
                                            , out lpOverlapped
                                            , 0xffffffff
                                        );
                Console.WriteLine("GetQueuedCompletionStatus ... ");
                if(r > 0)
                {
                    GCHandle gch = GCHandle.FromIntPtr(lpOverlapped);
                    TIocpData data = (TIocpData) gch.Target;
                    gch.Free();
                    if (DataReceived != null)
                    {
                        DataReceived(this, data);
                    }
                }
            }
        }
    }
}
namespace Microshaoft.RemotingObjects.Server
{
    using System;
    using System.Runtime.InteropServices;
    using Microshaoft;
    public class IocpProcessor
    {
        private IocpHandler<UserSessionData, IocpData> _iocpHandler;
        public IocpProcessor()
        {
            _iocpHandler = new IocpHandler<UserSessionData, IocpData>();
            _iocpHandler.DataReceived += new IocpHandler<UserSessionData, IocpData>.DataReceivedEventHandler(_iocpHandler_DataReceived);
        }
        public void BeginSyncWaitFor(string command)
        {
            UserSessionData session = new UserSessionData();
            session.CompleteCommand = command;
            _iocpHandler.BeginSyncWait(session);
        }
        public void SendData(IocpData data)
        {
            _iocpHandler.SendData(data);
        }
        void _iocpHandler_DataReceived(IocpHandler<UserSessionData , IocpData> sender, IocpData data)
        {
            if (sender.SessionData.CompleteCommand == data.Text)
            {
                sender.CompleteHandle();
            }
        }
    }
    public class UserSessionData
    {
        public string UserName;
        public string CompleteCommand;
    }
    //[StructLayout(LayoutKind.Sequential)]
    public class IocpData
    {
        public string Text;
    }
}
namespace Microshaoft.RemotingObjects.Server
{
    using System;
    using System.Threading;
    using System.Collections;
    using System.ServiceProcess;
    using System.ComponentModel;
    using System.Security.Principal;
    using System.Configuration.Install;
    using System.Runtime.Remoting;
    using System.Runtime.Remoting.Channels;
    using System.Runtime.Remoting.Channels.Tcp;
    using Microshaoft;
    using Microshaoft.Win32;
    using Microshaoft.RemotingObjects;
    public class ServiceHost : ServiceBase
    {
        public static readonly string serviceName = "RemotingSyncIocpAsycInvokeService";
        private static IocpProcessor _IocpProcessor;
        public static IocpProcessor IocpProcessor
        {
            get
            {
                return _IocpProcessor;
            }
        }
        static void Main(string[] args)
        {
            ServiceHost service = new ServiceHost();
            int l = 0;
            bool needFreeConsole = false;
            if (args != null)
            {
                l = args.Length;
            }
            if (l > 0)
            {
                if (args[0].ToLower() == "/console")
                {
                    needFreeConsole = true;
                    NativeMethods.AllocConsole();
                    Console.Title = "Server ...";
                    Console.WriteLine("Alloc Console ...");
                    Console.WriteLine("Current User Identity: {0}", WindowsIdentity.GetCurrent().Name);
                    Console.WriteLine(".Net Framework version: {0}", Environment.Version.ToString());
                }
                Console.Title = "Server"; //不能以服务运行
                Console.WriteLine("Console");
                service.OnStart(null);
                Console.ReadLine();
                return;
            }
            Console.WriteLine("Service");
            ServiceBase.Run(service);
            if (needFreeConsole)
            {
                Console.WriteLine("Free Console ...");
                NativeMethods.FreeConsole();
            }
        }
        public ServiceHost()
        {
            CanPauseAndContinue = true;
            ServiceName = ServiceHost.serviceName;
        }
        protected override void OnStart(string[] args)
        {
            Console.WriteLine(Environment.Version.ToString());
            _IocpProcessor = new IocpProcessor();
            RemotingHelper.StartRemoting<RemotingIoCP>
                                            (
                                                "iocp"
                                                , 8080
                                                , WellKnownObjectMode.SingleCall
                                            );
            Console.WriteLine("Server . , Press Enter key to exit.");
        }
    }
    [RunInstallerAttribute(true)]
    public class ProjectInstaller : Installer
    {
        private ServiceInstaller serviceInstaller;
        private ServiceProcessInstaller processInstaller;
        public ProjectInstaller()
        {
            processInstaller = new ServiceProcessInstaller();
            serviceInstaller = new ServiceInstaller();
            // Service will run under system account
            processInstaller.Account = ServiceAccount.LocalSystem;
            // Service will have Start Type of Manual
            serviceInstaller.StartType = ServiceStartMode.Manual;
            serviceInstaller.ServiceName = ServiceHost.serviceName;
            Installers.Add(serviceInstaller);
            Installers.Add(processInstaller);
        }
    }
}
namespace Microshaoft.Win32
{
    using System;
    using Microsoft.Win32.SafeHandles;
    using System.Runtime.InteropServices;
    public static class NativeMethods
    {
        [
            DllImport
                (
                    "kernel32.dll"
                )
        ]
        public static extern bool AllocConsole();
        [
            DllImport
                (
                    "kernel32.dll"
                )
        ]
        public static extern bool FreeConsole();
        [
            DllImport
                (
                    "kernel32.dll"
                    , CharSet = CharSet.Auto
                    , SetLastError = true
                )
        ]
        public static extern SafeFileHandle CreateIoCompletionPort
                                                    (
                                                        IntPtr FileHandle
                                                        , IntPtr ExistingCompletionPort
                                                        , IntPtr CompletionKey
                                                        , uint NumberOfConcurrentThreads
                                                    );
        [
            DllImport
                (
                    "kernel32.dll"
                    , CharSet = CharSet.Auto
                    , SetLastError = true
                )
        ]
        public static extern bool GetQueuedCompletionStatus
                                                    (
                                                        SafeFileHandle CompletionPort
                                                        , out uint lpNumberOfBytesTransferred
                                                        , out IntPtr lpCompletionKey
                                                        , out IntPtr lpOverlapped
                                                        , uint dwMilliseconds
                                                    );
        [
            DllImport
                (
                    "Kernel32"
                    , CharSet = CharSet.Auto
                )
        ]
        public static extern bool PostQueuedCompletionStatus
                                                    (
                                                        SafeFileHandle CompletionPort
                                                        , uint dwNumberOfBytesTransferred
                                                        , IntPtr dwCompletionKey
                                                        , IntPtr lpOverlapped
                                                    );
    }
}
namespace Microshaoft.RemotingObjects
{
    using System;
    using Microshaoft;
    using Microshaoft.RemotingObjects.Share;
    using Microshaoft.RemotingObjects.Server;
    public class RemotingIoCP : MarshalByRefObject, IRemotingIoCP
    {
        public void BeginSyncWaitFor(string command)
        {
            ServiceHost.IocpProcessor.BeginSyncWaitFor(command);
        }
        public void SendCommand(string command)
        {
            IocpData data = new IocpData();
            data.Text= command;
            ServiceHost.IocpProcessor.SendData(data);
        }
    }
}
/*
csc /r:Share.dll Client.cs
*/
namespace ConsoleApplication
{
    using System;
    using System.Threading;
    using Microshaoft;
    using Microshaoft.RemotingObjects.Share;
    public class Class1
    {
        static void Main(string[] args)
        {
            Console.Title = "Client";
            Class1 a = new Class1();
            a.Run();
            Console.WriteLine(Environment.Version.ToString());
            Console.ReadLine();
        }
        public void Run()
        {
            IRemotingIoCP _proxy = RemotingHelper.GetRemotingLocalClientProxyObject<IRemotingIoCP>("tcp://127.0.0.1:8080/iocp");
            string s;
            while ((s = Console.ReadLine()) != "q")
            {
                Console.WriteLine("BeginSyncWaitFor: {0} at {1} blocking ...", s, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff"));
                _proxy.BeginSyncWaitFor(s);
                Console.WriteLine("EndSyncWaitFor: {0} at {1}", s, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff"));
            }
        }
    }
}
/*
csc /r:Share.dll ControlerClient.cs
*/
namespace ConsoleApplication
{
    using System;
    using System.Threading;
    using Microshaoft;
    using Microshaoft.RemotingObjects.Share;
    public class Class1
    {
        static void Main(string[] args)
        {
            Console.Title = "Controler Client";
            Class1 a = new Class1();
            a.Run();
            Console.WriteLine(Environment.Version.ToString());
            Console.ReadLine();
        }
        public void Run()
        {
            IRemotingIoCP _proxy = RemotingHelper.GetRemotingLocalClientProxyObject<IRemotingIoCP>("tcp://127.0.0.1:8080/iocp");
            string s;
            while ((s = Console.ReadLine()) != "q")
            {
                _proxy.SendCommand(s);
                Console.WriteLine("SendCommand end: [{0}] at {1}", s, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff"));
            }
        }
    }
}

原文地址:https://www.cnblogs.com/Microshaoft/p/1629227.html