2017-05-04 5 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 서비스의 장기 실행 태스크가이를 감지하고 원하는대로 수행한다는 것입니다.

내가 그렇게하는 응용 프로그램이 >>>이

편집을 도움이되기를 바랍니다. 몇 가지 발췌 문장을 공유하겠습니다. startMonitorTask

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); 
     } 

는 플래그를 모니터링하는 장기 실행 작업입니다.

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을 가지고보다 방법 : CyclicalTask ​​ 내 자신의 단지 확장 방법이다.

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

경우 EdiDataAccess.GetEdiCostumersToStart();은 로그인을 요청한 모든 고객을 검색합니다.

고객이 세션 시작을 요청한 시간을 감지 할 수 있습니다.

+0

좋아, 내가 네가 한 짓을 잡아. 따라서 기본적으로 각 클라이언트에 미리보기 나 프로그램을 추가해야이 작업이 가능해집니다. 정말 원하는 것은 클라이언트의 서비스/프로그램을 통해 네트워크 서비스를 트리거하는 오버 헤드를 제거하는 것입니다. 서버의 네트워크 서비스는 특정 클라이언트의 로그인을 감지하고 서버의 로그 파일을 말하면 정보를 저장할 수 있어야합니다. 나는이 모든 경우에 모든 클라이언트를 구성하고 싶지 않다. 나는 모든 클라이언트에 서비스를 설치하고 이것에 대해 걱정하지 않을 것이다. –

+0

client라고하면 WPF 나 WindowsForms와 같은 클라이언트 응용 프로그램을 참조할까요? – taquion

+0

아니요. 서버에서 정보를 사용하는 클라이언트, 즉 네트워크 서버에 연결된 일련의 컴퓨터를 말합니다. –