本文將建立一個silverlight與wcf雙向通訊的簡單例項,以下是詳細步驟:
新建Silverlight應用程式,名稱WCFtest。解決方案中新增WCF服務應用程式,名稱WcfServiceTest,WCF服務將不再寄宿在Web中。
刪除VS自動生成的IService1.cs和Service1.svc檔案,修改WCF服務固定埠12345。
在WCF服務應用程式WcfServiceTest上,新增應用,選擇瀏覽定位到 C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Libraries\Server \System.ServiceModel.PollingDuplex.dll,PollingDuplex是一種擴充套件的雙工輪詢通訊方法,在安裝的 Silverlight SDK中可以找到。
新增一個WCF服務,名稱ServiceTest。
修改WCF服務應用程式WcfServiceTest的Web.config檔案。

<?xml version="1.0" encoding="utf-8"?>
<configuration> <system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 為避免洩漏元資料資訊,請在部署前將以下值設定為 false 並刪除上面的元資料終結點 -->
<serviceMetadata httpGetEnabled="true"/>
<!-- 要接收故障異常詳細資訊以進行除錯,請將以下值設定為 true。在部署前設定為 false 以避免洩漏異常資訊 -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--這裡是新增的開始-->
<services>
<service name="WcfServiceTest.ServiceTest" >
<endpoint address="" binding="pollingDuplexHttpBinding" contract="WcfServiceTest.IServiceTest" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<extensions>
<bindingExtensions>
<add name="pollingDuplexHttpBinding" type="System.ServiceModel.Configuration.PollingDuplexHttpBindingCollectionElement,System.ServiceModel.PollingDuplex, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
</extensions>
<!--這裡是新增的結束-->
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer> </configuration>

此處的修改,添加了兩個終結點,使用服務配置編輯器開啟可以看到它們
服務配置編輯器,可以在開始選單中找到
右鍵點選其屬性,複製其目標地址
右鍵Wcf服務應用程式中的Web.config檔案,選擇開啟方式,點選新增,程式名輸入"服務配置編輯器的路徑",友好名稱"服務配置編輯器"
選擇Web.config檔案的開啟方式,就可以選擇服務配置編輯器打開了;
修改IServiceTest.cs檔案。

[ServiceContract(CallbackContract = typeof(ICallBack))]//指定回撥介面ICallBack
public interface IServiceTest
{
[OperationContract(IsOneWay = true)]//單向呼叫,不需要返回值
void SayHellow(string name);
} public interface ICallBack
{
[OperationContract(IsOneWay = true)]//單向呼叫,不需要返回值
void ShowHello(string hello);
}

CallbackContract=typeof(ICallBack),指定了回撥介面;
(IsOneWay = true),單向呼叫,不需要返回值。
修改ServiceTest.svc.cs檔案,實現IService介面的SayHello方法,傳進name引數,處理為My name is [name],作為引數再呼叫指定的回撥介面ICallBack中的ShowHello方法,ICallBack中的所有方法則留給客戶端實現,這裡不需 要實現它。

public class ServiceTest : IServiceTest
{
#region IServiceTest 成員 public void SayHellow(string name)
{
name = string.Format("My name is {0}.", name);
ICallBack callBack = OperationContext.Current.GetCallbackChannel<ICallBack>();
callBack.ShowHello(name);
} #endregion
}

當客戶端呼叫服務端的SayHellow方法時,服務端收到呼叫,獲取客戶端例項的通道。
按照約定好的回撥介面,呼叫ShowHello方法,同時把引數傳遞過去,ICallBack中的方法留給客戶端實現,服務端這裡只管呼叫。
你可能會遇到跨域問題,解決方法是為WCF應用程式WcfServiceTest新增跨域檔案clientaccesspolicy.xml。
clientaccesspolicy.xml內容如下:
重新生成解決方案,否則可能會遇到發現wcf服務有誤的情況,為Silverlight專案新增服務引用,點擊發現可以查詢到剛剛新增的ServiceTest服務,修改名稱空間ServiceReferenceTest。
在Silverlight專案的MainPage.xaml上,為了便於演示,新增一個TextBox,一個Button,一個TextBlock。

<Grid x:Name="LayoutRoot" Background="White">
<TextBox Height="" HorizontalAlignment="Left" Margin="12,12,0,0" Name="textBox1" VerticalAlignment="Top" Width="" />
<Button Content="Button" Height="" HorizontalAlignment="Left" Margin="12,41,0,0" Name="button1" VerticalAlignment="Top" Width="" />
<TextBlock Height="" HorizontalAlignment="Left" Margin="12,70,0,0" Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" Width="" />
</Grid>

新增button1的點選Click事件。

private void button1_Click(object sender, RoutedEventArgs e)
{
//擴充套件的輪詢機制的雙向通訊
PollingDuplexHttpBinding binding = new PollingDuplexHttpBinding()
{
//每次輪詢建立的有效時間為20分鐘
InactivityTimeout = TimeSpan.FromMinutes()
};
//基礎的http請求方式
//Binding binding =new BasicHttpBinding();
//svc服務地址
EndpointAddress endPoint = new EndpointAddress("http://localhost:12345/ServiceTest.svc");
ServiceReferenceTest.ServiceTestClient client = new ServiceReferenceTest.ServiceTestClient(binding, endPoint);
//非同步呼叫SayHellow方法
client.SayHellowAsync(this.textBox1.Text);
//呼叫完成後ShowHello回撥事件
client.ShowHelloReceived += new EventHandler<ServiceReferenceTest.ShowHelloReceivedEventArgs>(client_ShowHelloReceived);
}

new PollingDuplexHttpBinding();例項化一個PollingDuplex通道,PollingDuplex為雙向工作輪詢通訊機制;
InactivityTimeout = TimeSpan.FromMinutes(20);每次輪詢建立的有效時間為20分鐘;
new EndpointAddress("http://localhost:12345/ServiceTest.svc");指定svc服務的終結點地址;
client.SayHellowAsync(this.textBox1.Text);將textBox1的text內容作為引數,非同步呼叫服務端的SayHellow方法;
client.ShowHelloReceived += new EventHandler<ServiceReferenceTest.ShowHelloReceivedEventArgs> (client_ShowHelloReceived);呼叫服務端的SayHellow方法,方法將呼叫回撥介面ICallBack中的 ShowHello方法,這裡指定ShowHello呼叫完成的事件;
void client_ShowHelloReceived(object sender, ServiceReferenceTest.ShowHelloReceivedEventArgs e)
{
//實現void ShowHello(string hello)方法,引數e.hello
this.textBlock1.Text = string.Format("Hello! {0}", e.hello);
}
這裡就是對ICallBack介面中ShowHello方法的實現,可使用引數e.hello,當客戶端呼叫服務端的SayHello方法 時,SayHello方法中呼叫指定的回撥介面ICallBack中的ShowHello方法,客戶端完善呼叫到ShowHello方法完成後的事件,顯 示結果Hello![e.hello],在textBlock1上;
F5執行,在textbox1中輸入名字name,點選button1,呼叫服務端的SayHello方法帶引數name,SayHello方 法處理為Mynameis[name],作為引數再呼叫指定的回撥介面ICallBack中的ShowHello方法,客戶端實現呼叫ShowHello 方法完成後的事件, 處理為Hello![e.hello],後輸出結果到textBlock1中。