//========================================================================================================================== /* csc /r:Share.dll Server.cs */ namespace Microshaoft.RemotingObjects.Server { using System; using System.Threading; using System.Collections.Concurrent; using Microshaoft; public class SyncInvokeAsyncProcessor { private ConcurrentDictionary<string, SessionWithData<string, DateTime>> _sessions = new ConcurrentDictionary<string, SessionWithData<string, DateTime>>(); public string SyncInvokeWaitFor(string sessionID, string completeCommand) { var sessionData = _sessions.GetOrAdd ( sessionID , key => { return new SessionWithData<string, DateTime>() { SessionID = sessionID , CompleteCommandWaits = new ConcurrentDictionary<string, ConcurrentBag<WaitWithData<DateTime>>>() }; } ); var waits = sessionData.CompleteCommandWaits; var completeCommandWaits = waits.GetOrAdd ( completeCommand , key => { return new ConcurrentBag<WaitWithData<DateTime>>(); } ); var wwd = new WaitWithData<DateTime>() { Wait = new AutoResetEvent(false) }; completeCommandWaits.Add(wwd); EventWaitHandle wait = wwd.Wait; wait.WaitOne(); return wwd.Data.ToString("yyyy-MM-dd HH:mm:ss.fffff"); } public void SendCommand(string sessionID, string commandText) { SessionWithData<string, DateTime> session; if (_sessions.TryGetValue(sessionID, out session)) { ConcurrentBag<WaitWithData<DateTime>> waits; if (session.CompleteCommandWaits.TryGetValue(commandText, out waits)) { while (!waits.IsEmpty) { WaitWithData<DateTime> wwd; if (waits.TryTake(out wwd)) { wwd.Data = DateTime.Now; wwd.Wait.Set(); }; } } } } } public class SessionWithData<TSessionData, TConnectionData> { public string SessionID; public ConcurrentDictionary<string, ConcurrentBag<WaitWithData<TConnectionData>>> CompleteCommandWaits; public TSessionData Data; } public class WaitWithData<T> { public EventWaitHandle Wait; public T Data; } } 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 = "RemotingSyncAsycInvokeService"; private static SyncInvokeAsyncProcessor _processor; public static SyncInvokeAsyncProcessor Processor { get { return _processor; } } 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()); _processor = new SyncInvokeAsyncProcessor(); RemotingHelper.StartRemoting<RemotingSyncInvokerAsyncHandler> ( "SyncInvokeAsyncHandler" , 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.RemotingObjects { using System; using Microshaoft; using Microshaoft.RemotingObjects.Share; using Microshaoft.RemotingObjects.Server; public class RemotingSyncInvokerAsyncHandler : MarshalByRefObject, IRemotingSyncInvokerAsyncHandler { public string SyncInvokeWaitFor(string user, string completeCommand) { return ServiceHost.Processor.SyncInvokeWaitFor(user, completeCommand); } public void SendCommand(string user, string command) { ServiceHost.Processor.SendCommand(user, command); } } } namespace Microshaoft.Win32 { using System; using System.Runtime.InteropServices; public static class NativeMethods { [ DllImport ( "kernel32.dll" ) ] public static extern bool AllocConsole(); [ DllImport ( "kernel32.dll" ) ] public static extern bool FreeConsole(); } } //========================================================================================================================== //========================================================================================================================== /* 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() { IRemotingSyncInvokerAsyncHandler _proxy = RemotingHelper.GetRemotingLocalClientProxyObject<IRemotingSyncInvokerAsyncHandler>("tcp://127.0.0.1:8080/SyncInvokeAsyncHandler"); string s; while ((s = Console.ReadLine()) != "q") { string[] a = s.Split(' '); Console.WriteLine("BeginSyncWaitFor: {0} at {1} blocking ...", s, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")); string r = _proxy.SyncInvokeWaitFor(a[0], a[1]); Console.WriteLine(r); Console.WriteLine("EndSyncWaitFor: {0} at {1}", s, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")); } } } } //========================================================================================================================== //========================================================================================================================== /* 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 IRemotingSyncInvokerAsyncHandler { string SyncInvokeWaitFor(string user, string command); void SendCommand(string user, string command); } } //========================================================================================================================== |