0

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

在代码中,我删除了用户在 serverApp 中的显示方式。现在我只需要这个活动来工作。

在我的服务库中:

INetworkService 合同:

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

在我的 ServerApp (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!");
        }
    }
}

在我的 ClientApp (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);

        }
    }
}
4

4 回答 4

3

您订阅了其他 NetworkService 实例的事件,而不是 ServiceHost 实例化的事件。在您的情况下,每次向服务器发出请求时,都会创建新的 NetworkService 实例。将以下属性置于 NetworkService 类之上:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

然后订阅事件:

var serviceInstance = (NetworkService)host.SingletonInstance;
serviceInstance.UserListChanged += networkService_UserListChanged;
于 2012-04-10T07:37:59.670 回答
2

创建 ServiceHost 时,您应该提供 NetworkService 实例而不是typeof(NetworkService)

ServiceHost host = new ServiceHost(networkService);

当然,您需要先初始化它。

于 2012-04-10T07:35:48.860 回答
0

我没有看得很详细,但总的来说你的代码看起来还不错。在这种情况下,有时运行 2 个 VisualStudio 实例很有用——一个用于调试中的服务器,一个用于调试中的客户端。如果您在调试客户端的 VS 中的客户端 button1_Click 代码中放置一个断点,在调试服务器的 VS 中的 NetworkServices.Logout 中放置一个断点,您将能够从客户端跳转到服务器代码并轻松查看哪里出了问题。

于 2012-04-10T07:32:49.290 回答
0

为什么在这里需要一个事件模型?为什么不直接在 NetworkService.Logout() 中处理您的“事件”。将其推迟到一个事件然后必须连接该事件(正如 ilya.dofofeev 正确指出的那样不在同一个对象上)提供任何真正的好处吗?

于 2012-04-10T07:46:16.143 回答