我们有一个现有系统,其中启用了网络服务的 Windows 服务托管在服务器上的网络服务帐户上。每个客户端上都安装了 Windows 服务,一旦用户通过每个客户端登录,这些服务就会自动启动,客户端上的这些服务会触发服务器上的服务,告诉它例如客户端 A 已经登录。
我想要做的是创建一个网络服务并将其托管在服务器上,并直接触发它,而无需在每个客户端上安装单独的 Windows 服务。可能吗?我希望每个客户端都使用现有的网络服务,并在登录时通知它它在线。随着时间的推移在服务器上维护用户登录日志。
我们有一个现有系统,其中启用了网络服务的 Windows 服务托管在服务器上的网络服务帐户上。每个客户端上都安装了 Windows 服务,一旦用户通过每个客户端登录,这些服务就会自动启动,客户端上的这些服务会触发服务器上的服务,告诉它例如客户端 A 已经登录。
我想要做的是创建一个网络服务并将其托管在服务器上,并直接触发它,而无需在每个客户端上安装单独的 Windows 服务。可能吗?我希望每个客户端都使用现有的网络服务,并在登录时通知它它在线。随着时间的推移在服务器上维护用户登录日志。
我使用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 (); 检索所有已请求登录的客户
我的窗口服务可以检测客户何时请求开始会话。