2017-05-04 108 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

不,我指的是客戶端使用服務器的信息,即連接到網絡服務器的一系列計算機。 –