2013-09-26 27 views
0

我有Winforms應用程序主機WCF服務。 這是我Button connect event通過我的表格WCF客戶端消息

private void btnConnect_Click(object sender, EventArgs e) 
{ 
     try 
     { 
      // Returns a list of ipaddress configuration 
      IPHostEntry ips = Dns.GetHostEntry(Dns.GetHostName()); 
      // Get machine ipaddress 

      IPAddress _ipAddress = IPAddress.Parse(tbServerIp.Text); 

      // Create the url that is needed to specify where the service should be started 
      urlService = "net.tcp://" + _ipAddress.ToString() + ":8000/MyService"; 

      // Instruct the ServiceHost that the type that is used is a ServiceLibrary.service1 
      host = new ServiceHost(typeof(ServiceLibrary.service1)); 
      host.Opening += new EventHandler(host_Opening); 
      host.Opened += new EventHandler(host_Opened); 
      host.Closing += new EventHandler(host_Closing); 
      host.Closed += new EventHandler(host_Closed); 

      // The binding is where we can choose what transport layer we want to use. HTTP, TCP ect. 
      NetTcpBinding tcpBinding = new NetTcpBinding(); 
      tcpBinding.TransactionFlow = false; 
      tcpBinding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign; 
      tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows; 
      tcpBinding.Security.Mode = SecurityMode.None; // <- Very crucial 

      // Add a endpoint 
      host.AddServiceEndpoint(typeof(ServiceLibrary.IService1), tcpBinding, urlService); 

      // A channel to describe the service. Used with the proxy scvutil.exe tool 
      ServiceMetadataBehavior metadataBehavior; 
      metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>(); 
      if (metadataBehavior == null) 
      { 
       // This is how I create the proxy object that is generated via the svcutil.exe tool 
       metadataBehavior = new ServiceMetadataBehavior(); 
       metadataBehavior.HttpGetUrl = new Uri("http://" + _ipAddress.ToString() + ":8001/MyService"); 
       metadataBehavior.HttpGetEnabled = true; 
       metadataBehavior.ToString(); 
       host.Description.Behaviors.Add(metadataBehavior); 
       urlMeta = metadataBehavior.HttpGetUrl.ToString(); 
       //pbIndicator.Image = Resources.indicator_green; 
       btnConnect.BackColor = Color.Red; 
       btnConnect.Text = "Stop"; 
      } 

      host.Open(); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.StackTrace); 
    } 
} 

這是我ServiceLibrary:

namespace ServiceLibrary 
{ 
    public delegate void StatusEventHandler(string srt); 

    [ServiceContract()] 
    public interface IService1 
    { 
     [OperationContract] 
     string MyOperation1(string myValue); 
     [OperationContract] 
     string MyOperation2(DataContract1 dataContractValue); 
     [OperationContract] 
     string HelloWorld(string str); 
    } 

    public class service1 : IService1 
    { 
     public event StatusEventHandler StartEvent; 

     public string MyOperation1(string myValue) 
     { 
      return "Hello: " + myValue; 
     } 
     public string MyOperation2(DataContract1 dataContractValue) 
     { 
      return "Hello: " + dataContractValue.FirstName; 
     } 
     public string HelloWorld(string str) 
     { 
      StartEvent(str); 
      //return "Helloworld from " + str; 
     } 
    } 

    [DataContract] 
    public class DataContract1 
    { 
     string firstName; 
     string lastName; 

     [DataMember] 
     public string FirstName 
     { 
      get { return firstName; } 
      set { firstName = value; } 
     } 
     [DataMember] 
     public string LastName 
     { 
      get { return lastName; } 
      set { lastName = value; } 
     } 
    } 
} 

我想要做的是從HelloWorld function傳遞客戶端消息以我的主要形式,所以我嘗試創建活動裏面class service1

public delegate void StatusEventHandler(string srt); 
public event StatusEventHandler StartEvent; 

,但它仍然是零甚至從我的主要形式登記後(我的按鈕CLI內ck事件) 實現這個最簡單的方法是什麼?

回答

0

當您創建服務主機時,您提供了一個類型,這意味着每次調用您的服務時都會創建一個該類型的新實例。

host = new ServiceHost(typeof(ServiceLibrary.service1)); 

你需要你的服務的一個實例傳遞給ServiceHost的構造函數,所以每次調用將使用該實例。

var yourServiceInstance = new ServiceLibrary.service1(); 

// attach event handlers here 

host = new ServiceHost(yourServiceInstance); 

當你這樣做,你的服務類需要配置單實例模式:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
public class service1 
{ 
    // methods here 
} 
+0

我需要用別的東西來代替yourServiceInstance?因爲通過這種方式我不能連接:(爲了使用服務實例的ServiceHost構造函數之一,服務的InstanceContextMode必須設置爲InstanceContextMode.Single,可以通過ServiceBehaviorAttribute配置,否則請考慮使用帶有Type參數的ServiceHost構造函數。) – user2813889

+0

如果您還沒有服務類的實例,則需要創建一個新實例。可能是一個班級領域。 – nvoigt

+0

那麼,該消息包含一個解決您的問題。 「服務的InstanceContextMode必須設置爲InstanceContextMode.Single」。這樣做,它會工作。 – nvoigt