简体   繁体   English

Wpf 服务器/客户端登录。 事件问题

[英]Wpf Server/client logon. Problems with events

I'm pretty new to programming, so bear with me if my question isn't specific enough.我是编程新手,所以如果我的问题不够具体,请耐心等待。 Right now I'm trying to make a simple Client Logon to my server.现在我正在尝试对我的服务器进行简单的客户端登录。 So the server App knows which users are connected.所以服务器 App 知道连接了哪些用户。 When a client connects I want an event to fire on the server that update the userlist.当客户端连接时,我希望在更新用户列表的服务器上触发一个事件。 But it doesn't and I can't figure out why.但事实并非如此,我也不知道为什么。 Hope you can help.希望你能帮忙。

In the codes I have removed how the users should be displayed in the serverApp.在代码中,我删除了用户在 serverApp 中的显示方式。 Right now I just need the event to work.现在我只需要活动正常进行。

In my Service Library:在我的服务库中:

INetworkService contract: 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();
    }
}

NetworkService Class:网络服务 Class:

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

UserInfo Class:用户信息 Class:

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

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

In my ClientApp (WPF): (Have made a Service Reference to the Server)在我的 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);

        }
    }
}

You subscribe to event of other NetworkService instance than ServiceHost instantiates.您订阅了 ServiceHost 实例化之外的其他 NetworkService 实例的事件。 In your case every time you make request to server, new NetworkService instance is created.在您的情况下,每次您向服务器发出请求时,都会创建新的 NetworkService 实例。 Place the following attribute above NetworkService class:将以下属性置于 NetworkService class 之上:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

Then subscribe to event:然后订阅事件:

var serviceInstance = (NetworkService)host.SingletonInstance;
serviceInstance.UserListChanged += networkService_UserListChanged;

When creating your ServiceHost, you should provide NetworkService instance instead of typeof(NetworkService)创建 ServiceHost 时,您应该提供 NetworkService 实例而不是typeof(NetworkService)

ServiceHost host = new ServiceHost(networkService);

You need to initialize it first, of course.当然,您需要先对其进行初始化。

I didnt look in great detail but overall your code looks ok.我没有看得很详细,但总的来说你的代码看起来没问题。 It is sometimes useful in this situation to run 2 instances of VisualStudio - one for server in debug and one for client in debug.有时在这种情况下运行 2 个 VisualStudio 实例很有用 - 一个用于调试中的服务器,一个用于调试中的客户端。 If you put a break point in client button1_Click code in VS thats debugging client, and a break point in NetworkServices.Logout in VS thats debugging server you will be able to step from client to server code and see easily whats going wrong where.如果你在客户端 button1_Click 代码中放置一个断点,那是调试客户端,并且在 NetworkServices.Logout 中放置一个断点,那是调试服务器,你将能够从客户端到服务器代码,并轻松查看哪里出了问题。

Why do you need an event model here?为什么这里需要一个事件 model? Why not just handle your "event" directly in NetworkService.Logout().为什么不直接在 NetworkService.Logout() 中处理您的“事件”。 Does pushing this off to an event and then having to wire that event (which as ilya.dofofeev correctly points out is not on the same object) provide any real benefit?将它推到一个事件然后必须连接该事件(正如 ilya.dofofeev 正确指出的那样不在同一个对象上)是否提供任何真正的好处?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM