2012-04-10 89 views
0

我很新的編程,所以如果我的問題不夠具體,請耐心等待。現在我正在嘗試將一個簡單的客戶端登錄到我的服務器。所以服務器應用程序知道哪些用戶連接。當客戶端連接時,我想要在更新用戶列表的服務器上觸發一個事件。但它不,我不明白爲什麼。希望你能幫助。Wpf服務器/客戶端登錄。問題與事件

在代碼中,我已經刪除了用戶應該如何顯示在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); 
      } 
     } 
    } 
} 

的UserInfo類:

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

     } 
    } 
} 

回答

2

在創建ServiceHost的,你應該提供網絡服務實例,而不是typeof(NetworkService)

ServiceHost host = new ServiceHost(networkService); 

你需要先初始化它,當然。

+0

通過使用什麼ilya.dorofeev說關於使NetworkService [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]的一個實例,並提供主機與您所描述的那個實例,它的工作原理..謝謝:) – user1077186 2012-04-10 09:34:50

0

我沒有看的很詳細但總的來說你的代碼看起來不錯在這種情況下運行VisualStudio的兩個實例有時很有用 - 一個用於調試服務器,一個用於調試客戶端。如果你在客戶端的button1_Click代碼中加入了一個斷點,那就是調試客戶端,並且在VS中的NetworkServices.Logout中有一個斷點,它們是調試服務器,你將能夠從客戶端到服務器端的代碼輕鬆地看到哪裏出錯。

3

您訂閱了除ServiceHost實例化之外的其他NetworkService實例的事件。在你每次向服務器發出請求時,都會創建一個新的NetworkService實例。將下面的屬性上述網絡服務類:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 

然後訂閱事件:

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

非常感謝。使用:[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]使它只有一個實例。但是當我嘗試訂閱事件時,它拋出了一個TargetInvocationException異常(InnerException:System。NullReferenceException Message =未將對象引用設置爲對象的實例。) – user1077186 2012-04-10 09:31:12

0

你爲什麼在這裏需要一個事件模型?爲什麼不直接在NetworkService.Logout()中處理你的「事件」。如果將此事件推遲到一個事件,然後必須連線該事件(正如ilya.dofofeev正確指出的那樣,它不在同一個對象上),那麼是否能提供任何真正的好處?