我对编程很陌生,如果我的问题不够具体,请耐心等待。现在我正在尝试对我的服务器进行简单的客户端登录。 因此,服务器应用程序知道哪些用户已连接。当客户端连接时,我希望在更新用户列表的服务器上触发一个事件。但它没有,我也想不通为什么。希望你能帮到忙。
在代码中,我删除了用户在服务器应用程序中的显示方式。现在我只需要事件起作用。
在我的服务库中:
工作服务合同:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace NetworkLib
{
[ServiceContract]
public interface INetworkService
{
[OperationContract]
void Logon(UserInfo userInfo);
[OperationContract]
void Logout();
}
}
网络服务类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace NetworkLib
{
public class NetworkService : INetworkService
{
public event EventHandler UserListChanged;
public void Logon(UserInfo userInfo)
{
OnUserListChanged();
}
public void Logout()
{
OnUserListChanged();
}
private void OnUserListChanged()
{
var handler = UserListChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
}
用户信息类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace NetworkLib
{
[DataContract]
public class UserInfo
{
[DataMember]
public string Name;
}
}
在我的服务器应用程序 (WPF) 中:
using System.ServiceModel;
using NetworkLib;
namespace ServerApp
{
public partial class MainWindow : Window
{
NetworkService networkService;
public MainWindow()
{
InitializeComponent();
ServiceHost host = new ServiceHost(typeof(NetworkService));
host.Open();
networkService = new NetworkService();
networkService.UserListChanged += networkService_UserListChanged;
}
private void networkService_UserListChanged(object sender, EventArgs e)
{
MessageBox.Show("It Works!");
}
}
}
在我的客户端应用程序 (WPF) 中:(已对服务器进行了服务引用)
namespace ClientApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
ServiceReference.NetworkServiceClient proxy = new ServiceReference.NetworkServiceClient();
ServiceReference.UserInfo userInfo = new ServiceReference.UserInfo();
userInfo.Name = "Test";
proxy.Logon(userInfo);
}
}
}
您订阅了除 ServiceHost 实例化之外的其他 NetworkService 实例的事件。在您的情况下,每次向服务器发出请求时,都会创建新的网络服务实例。将以下属性放在网络服务类上方:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
然后订阅活动:
var serviceInstance = (NetworkService)host.SingletonInstance;
serviceInstance.UserListChanged += networkService_UserListChanged;
创建服务主机时,应提供 NetworkService 实例,而不是typeof(NetworkService)
ServiceHost host = new ServiceHost(networkService);
当然,您需要先初始化它。
我没有看得很详细,但总的来说你的代码看起来不错。 在这种情况下,运行 2 个 VisualStudio 实例有时很有用 - 一个用于调试中的服务器,另一个用于调试中的客户端。 如果在调试客户端的 VS 中的客户端button1_Click代码中放置断点,在调试服务器的 VS 中的 NetworkServices.Logout 中放置断点,您将能够从客户端单步执行到服务器代码,并轻松查看哪里出了什么问题。
为什么这里需要一个事件模型? 为什么不直接在NetworkService.Logout()中处理您的"事件"。 将其推送到一个事件,然后必须连接该事件(正如ilya.dofofeev正确指出的那样,它不在同一对象上)是否提供了任何真正的好处?