WPF 服务器/客户端登录.事件问题

本文关键字:事件 问题 登录 客户端 服务器 WPF | 更新日期: 2023-09-27 18:30:29

我对编程很陌生,如果我的问题不够具体,请耐心等待。现在我正在尝试对我的服务器进行简单的客户端登录。 因此,服务器应用程序知道哪些用户已连接。当客户端连接时,我希望在更新用户列表的服务器上触发一个事件。但它没有,我也想不通为什么。希望你能帮到忙。

代码中,我删除了用户在服务器应用程序中的显示方式。现在我只需要事件起作用。

在我的服务库中:

工作服务合同:

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

WPF 服务器/客户端登录.事件问题

您订阅了除 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正确指出的那样,它不在同一对象上)是否提供了任何真正的好处?