0

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

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

4

1 回答 1

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是具有监控功能的方法。

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

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

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

于 2017-05-04T12:08:11.947 回答