2017-05-04 64 views
0

我们有一个现有系统,其中启用了网络服务的Windows服务托管在服务器上的网络服务帐户上。每个客户端上都安装了Windows服务,当用户通过每个客户端登录后,这些服务会自动启动,客户端上的这些服务会触发服务器上的服务,告诉客户端A已登录。如何在客户端登录时在服务器上的网络服务帐户中触发服务?

我想做什么是创建一个网络服务并将其托管在服务器上,并直接触发它,而无需在每个客户端上安装单独的Windows服务。可能吗?我希望每个客户端都使用现有的网络服务,并在登录时通知它在线。随着时间的推移,在服务器上维护用户登录日志的种类。

回答

0

我已经使用Simple Impersonation Library。这是我在我的WPF客户端上使用的片段。

public static async Task ToggleServiceStatus(this EdiServiceInfo serviceInfo) 
     { 
      await Task.Factory.StartNew(() => 
      { 
       using (
        Impersonation.LogonUser(serviceInfo.Domain, serviceInfo.User, serviceInfo.Pswd, 
         Environment.MachineName.Equals(serviceInfo.ComputerName, 
          StringComparison.InvariantCultureIgnoreCase) 
          ? LogonType.Network 
          : LogonType.Interactive)) 
       { 
        var service = new ServiceController(serviceInfo.ServiceName, serviceInfo.ComputerName); 
        if (service.Status == ServiceControllerStatus.Stopped) 
        { 
         service.Start(); 
         service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(60)); 
        } 
        else 
        { 
         service.Stop(); 
         service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(60)); 
        } 
       } 
      }); 
     } 

如果要从客户端触发服务,这非常有用。但是,如果服务已经正常工作并且只想响应登录,那么您可以使用标记DidLoggedIn维护一个客户端表,并且您的Windows服务应该有一个监视此标志的长时间运行的任务。这里的想法是,每当客户端登录时,您将标志设置为true,并且在您的服务器端,Windows服务的长时间运行任务将检测到这一点,并做好您想做的任何事情。

希望它可以帮助

编辑>>>我有这样做的应用程序。让我分享一些片段。

public virtual async Task InitAsync() 
     { 
      EdiDataAccess.ResetServiceFlags(); 
      EdiDataAccess.SetServiceAsWorking(); 
      var startMonitorTask = new Func<Task>(StartAllWorkersAsync) 
       .CyclicalTask(TimeSpan.FromSeconds(MonitorSeconds), MonitorCancellationToken); 
      var stopMonitorTask = new Func<Task>(StopRequestsMonitor) 
       .CyclicalTask(TimeSpan.FromSeconds(MonitorSeconds), MonitorCancellationToken); 
      await TaskEx.WhenAll(startMonitorTask, stopMonitorTask); 
     } 

startMonitorTask是长期运行的任务监视标志。 CyclicalTask​​只是一个我自己的扩展方法:

public static Task CyclicalTask(this Func<Task> task, TimeSpan waitTimeSpan, 
      CancellationToken token = default(CancellationToken)) 
     { 
      return TaskEx.Run(async() => 
      { 
       while (true) 
       { 
        token.ThrowIfCancellationRequested(); 
        await task(); 
        token.WaitHandle.WaitOne(waitTimeSpan); 
       } 
      }, token); 
     } 

StartAllWorkersAsync比有监控的funcionality的方法。

protected virtual async Task StartAllWorkersAsync() 
     { 
      var ediCustomersToStart = EdiDataAccess.GetEdiCostumersToStart(); 
      var ediTasks = ediCustomersToStart 
       .Select(StartWorkerAsync) 
       .ToList(); 
      await TaskEx.WhenAll(ediTasks); 
     } 

EdiDataAccess.GetEdiCostumersToStart();检索所有请求登录的客户

这是我的窗口服务可以检测客户何时请求开始会话。

+0

好吧,我抓住你在那里做了什么。所以基本上我不得不在每个客户端添加片段或可能的程序,以使其成为可能?我真正想要的是通过客户端上的服务/程序来消除触发网络服务的开销。服务器上的网络服务应能够检测特定客户端的登录并将其信息保存在服务器上的日志文件中。我不想配置每个客户端,否则我会在所有客户端上安装服务,并不会为此而烦恼。 –

+0

当你说客户端时,你是指WPF或WindowsForms等客户端应用程序? – taquion

+0

不,我指的是客户端使用服务器的信息,即连接到网络服务器的一系列计算机。 –

相关问题