2012-08-12 50 views
0

我有幾個關於WCF的問題: - 程序既可以作爲客戶端又可以作爲服務器? - 什麼是錯我的代碼:作爲客戶端和服務器的程序

服務:

[ServiceContract] 
public interface IShout 
{ 
    [OperationContract] 
    String Broadcast(String message); 
} 

實施:

public class eveShout : IShout 
{ 
    public String Broadcast(String message) 
    { 
     return message + " reply"; 
    } 
} 

我在表單構造器的服務:

ServiceHost s = new ServiceHost(typeof(IShout)); 
s.AddServiceEndpoint(typeof(IShout), new BasicHttpBinding(), "http://localhost:9189"); 
s.Open(); 

的,當我點擊另一個表單上的按鈕時,我想發送一條消息並獲得回覆。 我使用下面的代碼:

ChannelFactory<IShout> channel = new ChannelFactory<IShout>(new BasicHttpBinding(), "http://localhost:9189"); 
IShout shout = channel.CreateChannel(); 

String reply = shout.Broadcast("Test"); 

注:所有的代碼是在同一個命名空間。 注:我第一次啓動「服務器」(打開),然後應用程序繼續。

當我運行代碼時,服務器被創建。我使用netstat -a來查看端口是否打開。當我運行命令時,我得到了9189處於監聽狀態。但代碼停止在命令reply = shout(「test」)。我得到anexception,說

請求信道超時而00:00:59之後等待答覆...

+0

你用svcutil創建代理類嗎? – 2012-08-12 09:19:36

+1

這段代碼:1)不會編譯('eveShout.Broadcast'沒有明確實現); 2)如果你修復1,它會填充到運行時錯誤('Broadcast'方法未被標記爲'OperationContract');所以,請給我們提供真正的運行代碼示例。 – Dennis 2012-08-12 09:21:07

+0

burning_LEGION - 我不使用svcutil。這是必須的嗎?丹尼斯:我解決了這個問題,你現在可以檢查一下嗎? – 2012-08-12 09:25:50

回答

0

是的,你可以有一個應用程序同時作爲客戶端和服務器。

我看到一些可能需要糾正的事情。首先,嘗試添加OperationContract。

[ServiceContract] 
public interface IShout 
{ 
    [OperationContract] 
    String Broadcast(String message); 
} 

然後,採取類的類型,而不是接口。

ServiceHost s = new ServiceHost(typeof(eveShout)); 
s.AddServiceEndpoint(typeof(IShout), new BasicHttpBinding(), "http://localhost:9189"); 
s.Open(); 

確保您您有權訪問該命名空間(s.Open(),如果它不應該拋出一個異常)。

net http add urlacl url=http://+:9189/ user=... 

看看這些建議是否有所幫助。

(哦葉,並在你的類廣播的公共)

一個簡單的例子WindowsFormsApplication看起來像這樣...

// form1.cs 
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.ServiceModel; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      ChannelFactory<IShout> channel = new ChannelFactory<IShout>(new BasicHttpBinding(), "http://localhost:9189"); 
      IShout shout = channel.CreateChannel(); 

      String reply = shout.Broadcast("Test"); 

     } 
    } 
} 

// and Program.cs 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Windows.Forms; 
using System.ServiceModel; 

namespace WindowsFormsApplication1 
{ 
    static class Program 
    { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
      ServiceHost s = new ServiceHost(typeof(eveShout)); 
      s.AddServiceEndpoint(typeof(IShout), new BasicHttpBinding(), "http://localhost:9189"); 
      s.Open(); 

      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
     } 
    } 

    public class eveShout : IShout 
    { 
     public String Broadcast(String message) 
     { 
      return message + " reply"; 
     } 
    } 

    [ServiceContract] 
    public interface IShout 
    { 
     [OperationContract] 
     String Broadcast(String message); 
    } 
} 

看看你是否能得到,因爲這工作簡單的事。這至少會證明你可以做到,而且問題在別的地方。

+0

謝謝。但這並沒有幫助。如果我使用typeof(eveShout),我會在運行時遇到一個錯誤:合同類型不會被賦予ServiceContractAttribute。 – 2012-08-12 11:00:26

+0

你使用了什麼運行時,我已經在4.0上成功運行了這個函數。 – Les 2012-08-12 21:12:46

+0

注意:s.AddServiceEndpoint(typeof(IShout)...),new ServiceHost(typeof(eveShout)) – Les 2012-08-12 21:14:39

0

啓用WCF調試。

最簡單的方法是使用WCF服務配置編輯器。打開該實用程序,然後瀏覽以打開您的應用程序的配置文件。從診斷部分,只需點擊'啓用跟蹤'。默認跟蹤將會很好。

運行應用程序後,框架會將日誌文件轉儲到配置文件中指定的位置。雙擊打開並閱讀紅色事件(這些是有例外或意想不到的結果)。這非常有幫助,應該幫助您確定問題發生的位置。