日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转】利用WCF的双工通信

發布時間:2025/7/25 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】利用WCF的双工通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Silverlight與WCF之間的通信(2)利用WCF的雙工通信“推送”給SL數據

作者:Leon Weng??來源:博客園??發布時間:2010-06-19 23:43??閱讀:2215 次??原文鏈接?? [收藏]??

一,Duplex簡介

上一個隨筆記錄了SL利用Timer定時去WCF上取數據再綁定到界面上的問題,今天嘗試用了WCF的Duplex雙工通信來做這個事情,也以這個例子來說明WCF中Duplex的使用。

雙工通信的原理很簡單,我們平時用的是客戶端調用服務端的方法來獲取數據,而Duplex是將客戶端也當作了服務器,客戶端上的方法也可以被調用,以聊天功能為例子,用戶A連接到服務器后,之前的做法是客戶端定時取數據,而Duplex是在服務端定時檢測數據變化,如果發現了發送給A的信息,那么立即會調用客戶端的方法來推送信息到A。

二,建立Duplex模式的WCF服務

這里以一個簡單的聊天功能來說明,WCF提供了三個方法,連接到服務器方法,發送信息方法和接收信息方法。從服務契約上來說分為兩個接口,分別是為客戶端提供發送信息和開始聊天方法的IChatService接口和服務器調用客戶端方法的IChatServiceCallBack接口

IChatService.cs文件

代碼 namespaceChatWCF?
{?
???? [ServiceContract(CallbackContract=typeof(IChatServiceCallBack))]//這里需要定義IChatService接口的回調接口IChatServiceCallBack
publicinterfaceIChatService?
??? {?
??????? [OperationContract]?
??????? boolSendMessage(MessageInfo msg); //發送信息

??????? [OperationContract]?
??????? boolLoginChat(stringUser,stringPartner);//開始聊天模式??
}?

??? [ServiceContract]?
??? publicinterfaceIChatServiceCallBack //供服務端回調的接口
{?
??????? [OperationContract(IsOneWay=true)]?
??????? voidReceiveMessages(List<MessageInfo>listMessages);//客戶端被服務端回調后接收信息
}?
}

接下來需要實現這接口,IChatService.svc.cs

代碼 namespaceChatWCF?
{?
???? publicclassChatService : IChatService?
???? {?
??????? IChatServiceCallBack chatserviceCallBack;?
??????? string_user;?
??????? string_partner;?
     Timer timer;
//開始聊天
publicboolLoginChat(stringUser, stringPartner)

??????? {?
??????????? try
??????????? {?
??????????????? chatserviceCallBack =OperationContext.Current.GetCallbackChannel<IChatServiceCallBack>();?
??????????????? _user =User;?
??????????????? _partner =Partner;??

??????????????? timer =newTimer(newTimerCallback(CheckMessages), this, 100, 100);?

??????????????? returntrue;?
??????????? }?
??????????? catch(Exception ex)?
??????????? {?
??????????????? returnfalse;?
??????????? }?
??????? }?
//檢查消息并回調客戶端接收此消息,此處是回調的重點
??????? privatevoidCheckMessages(objecto) {?
??????????? chatserviceCallBack.ReceiveMessages(GetMessages(_user,_partner));?
??????? }?

//發送信息
publicboolSendMessage(MessageInfo msg)?
{
??????????????? [將MessageInfo寫入數據庫...]
}?

//檢測數據庫
privateList<MessageInfo>GetMessages(stringUser, stringPartner)?
{?
??????????? List<MessageInfo>listMsg =newList<MessageInfo>();
?? [檢測數據庫并返回檢測到的MessageInfo...]?????? returnlistMsg;?
}?

//執行簡單的SQL語句
privateDataSet ExcuteSQL(stringstrSql)?
?????? {?
??????????? stringstrServer ="server=LEON-PC\\sql2005;database=jplan;uid=sa;pwd=sa;";?
??????????? SqlConnection con =newSqlConnection(strServer);?
??????????? con.Open();?
??????????? SqlDataAdapter dataAdapter =newSqlDataAdapter(strSql, con);?
??????????? DataSet ds =newDataSet();?
??????????? dataAdapter.Fill(ds);?
??????????? con.Close();?

??????????? returnds;?
??????? }?
??? }?
}

這里需要注意一點的是這個WCF是建立在Duplex基礎上的,所以在wcf的項目中需要添加一個程序集:

Assembly System.ServiceModel.PollingDuplex
??? C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Libraries\Server\System.ServiceModel.PollingDuplex.dll

接下來需要對Web.config進行配置,主要是ServiceModel節點:

代碼 <system.serviceModel>
??? <behaviors>
????? <serviceBehaviors>
??????? <behavior name="ChatWCF.ChatBehavior">
????????? <serviceMetadata httpGetEnabled="true"/>
????????? <serviceDebug includeExceptionDetailInFaults="false"/>
??????? </behavior>
????? </serviceBehaviors>
??? </behaviors>
??? <services>
????? <service behaviorConfiguration="ChatWCF.ChatBehavior"name="ChatWCF.ChatService">
??????? <endpoint?
?????????? address=""
?????????? binding="pollingDuplexHttpBinding"
?????????? bindingConfiguration="multipleMessagesPerPollPollingDuplexHttpBinding"
?????????? contract="ChatWCF.IChatService">
??????? </endpoint>
??????? <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>

??? <bindings>
????? <pollingDuplexHttpBinding>
??????? <binding name="multipleMessagesPerPollPollingDuplexHttpBinding"
???????????????? duplexMode="MultipleMessagesPerPoll"
???????????????? maxOutputDelay="00:00:07"/>
????? </pollingDuplexHttpBinding>
??? </bindings>
??? <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
? </system.serviceModel>

如果您的WCF服務是一個單獨的站點,而客戶端是SL的話,鑒于SL的安全性考慮不支持跨域訪問,那么就需要在WCF的根目錄下放置一個XML策略文件,文件名為

clientaccesspolicy.xml:

代碼 <?xml version="1.0" encoding="utf-8"?>
<access-policy>
? <cross-domain-access>
??? <policy>
????? <allow-from http-request-headers="SOAPAction">
??????? <domain uri="*"/>
????? </allow-from>
????? <grant-to>
??????? <resource path="/"include-subpaths="true"/>
????? </grant-to>
??? </policy>
? </cross-domain-access>
</access-policy>

如果您的配置和代碼書寫正確,瀏覽一下WCF服務會發現下圖,說明服務已經正確host到VS的輕量級IIS上了

三,Silverlight跨域訪問WCF的Duplex服務

先建立一個單獨的project,silverlight app,當然還是需要先引用WCF服務的:

新建一個SL文件,Chat.xaml代碼,包括了一個發送消息窗口和一個顯示聊天信息的窗口,這個聊天的窗口從普通HTML街面上接收兩個參數,即user和partner互為聊天對象。

代碼 <UserControl x:Class="ChatSL.Chat"
??? xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation%22?
??? xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml%22?
??? xmlns:d="http://schemas.microsoft.com/expression/blend/2008%22?
??? xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006%22?
??? mc:Ignorable="d"
??? d:DesignHeight="510"d:DesignWidth="514">

??? <Grid x:Name="LayoutRoot"Background="White"Height="479"Width="485">
??????? <TextBox Height="87"HorizontalAlignment="Left"Margin="12,347,0,0"Name="txtMessage"VerticalAlignment="Top"Width="335"/>
??????? <Button Content="發送"Height="29"HorizontalAlignment="Right"Margin="0,440,138,0"Name="btnSend"VerticalAlignment="Top"Width="61"/>
??????? <ListBox Height="317"HorizontalAlignment="Left"ItemsSource="{Binding MessageInfo,Mode=OneWay}"Name="listMsgs"VerticalAlignment="Top"Width="335"Margin="12,12,0,0">
??????????? <ListBox.ItemTemplate>
??????????????? <DataTemplate>
??????????????????? <StackPanel Orientation="Horizontal">
??????????????????????? <TextBlock Text="{Binding SendTime,StringFormat='HH:mm:ss'}"></TextBlock>
??????????????????????? <TextBlock Text="??? "></TextBlock>
??????????????????????? <TextBlock Text="{Binding Sender}"Width="60"></TextBlock>
??????????????????????? <TextBlock Text="? :? "></TextBlock>
??????????????????????? <TextBlock Text="{Binding Message}"FontSize="12"FontFamily="Verdana"Foreground="Chocolate"></TextBlock>
??????????????????? </StackPanel>
??????????????? </DataTemplate>
??????????? </ListBox.ItemTemplate>
??????? </ListBox>
??????? <Image Height="31"HorizontalAlignment="Left"Source="Images/online.jpg"Margin="351,12,0,0"Name="image1"Stretch="Fill"VerticalAlignment="Top"Width="32"/>
??????? <Button Content="關閉"Height="29"HorizontalAlignment="Left"Margin="219,440,0,0"Name="btnClose"VerticalAlignment="Top"Width="61"/>
??????? <TextBox Height="23"HorizontalAlignment="Left"Margin="389,17,0,0"Name="txtPartner"VerticalAlignment="Top"Width="83"/>
??????? <Image Height="28"HorizontalAlignment="Left"Margin="352,347,0,0"Name="image2"Source="Images/online.jpg"Stretch="Fill"VerticalAlignment="Top"Width="31"/>
??????? <TextBox Height="23"HorizontalAlignment="Left"Margin="389,349,0,0"Name="txtMe"VerticalAlignment="Top"Width="83"/>
??? </Grid>
</UserControl>

后臺代碼中需要從HTML中接收聊天對象:

代碼 namespaceChatSL?
{?
??? publicpartialclassChat : UserControl?
??? {??
??????? stringuser;?
??????? stringpartner;?

??????? EndpointAddress address ;?
??????? PollingDuplexHttpBinding binding;?
??????? ChatService.ChatServiceClient proxy;?

??????? publicChat()?
??????? {?
??????????? InitializeComponent();

??????????? this.Loaded+=newRoutedEventHandler(Chat_Loaded);?
??????????? this.txtMessage.KeyDown +=newKeyEventHandler(KeyDownProcess);?
??????????? this.btnSend.Click +=newRoutedEventHandler(btnSend_Click);?
??????????? this.btnClose.Click +=newRoutedEventHandler(btnClose_Click);?
??????? }?

??????? voidChat_Loaded(objectsender,RoutedEventArgs e)?
??????? {?
??????????? HtmlElement element;?
??????????? element =HtmlPage.Document.GetElementById("lbluser");?
??????????? this.txtMe.Text =element.GetAttribute("innerText");?
??????????? element =HtmlPage.Document.GetElementById("lblpartner");?
??????????? this.txtPartner.Text =element.GetAttribute("innerText");?

??????????? user =this.txtMe.Text;?
??????????? partner =this.txtPartner.Text;?

??????????? LogIn();?
??????? }?
//向服務器示意上線
??????? privatevoidLogIn()?
??????? {?
??????????? address =newEndpointAddress("http://localhost:32662/ChatService.svc%22);
binding =newPollingDuplexHttpBinding(PollingDuplexMode.MultipleMessagesPerPoll);?
??????????? proxy =newChatService.ChatServiceClient(binding,address);?
??????????? proxy.ReceiveMessagesReceived+=newEventHandler<ChatService.ReceiveMessagesReceivedEventArgs>(proxy_ReceiveMessagesReceived);?
??????????? proxy.LoginChatAsync(user, partner);?
??????? }?

??????? #region綁定數據
??????? voidproxy_ReceiveMessagesReceived(objectsender,ChatService.ReceiveMessagesReceivedEventArgs e)?
??????? {?
??????????? this.listMsgs.ItemsSource =e.listMessages;?
??????? }?

??????? privatevoidSetDataSource()?
??????? {?
????????????
??????? }?
??????? #endregion

??????? #region鍵盤事件
??????? protectedvoidKeyDownProcess(objectsender, KeyEventArgs e)?
??????? {?
??????????? if(e.Key ==Key.Enter)?
??????????? {?
??????????????? SendMessage();?
??????????? }?
??????? }?
??????? #endregion
??????? #region發送信息
??????? privatevoidbtnSend_Click(objectsender, RoutedEventArgs e)?
??????? {?
??????????? SendMessage();?
??????? }?
??????? privatevoidSendMessage()?
??????? {?
??????????? if(this.txtMessage.Text =="")?
??????????? {?
??????????????? MessageBox.Show("請輸入信息!");?
??????????????? return;?
??????????? }?

??????????? ChatService.MessageInfo message =newChatService.MessageInfo();?
??????????? message.ID =Guid.NewGuid().ToString();?
??????????? message.Receipt =0;?
??????????? message.ReceiveMode ="user";?
??????????? message.ReceiveOrgan ="";?
??????????? message.ReceiveUser =this.txtPartner.Text;?
??????????? message.Message =this.txtMessage.Text;?
??????????? message.Sender =this.txtMe.Text;?
??????????? message.SendTime =DateTime.Now;?
??????????? message.Source ="web";?
??????????? message.State =0;?
??????????? message.Title =this.txtMessage.Text;?

??????????? proxy =newChatService.ChatServiceClient(binding, address);?
??????????? proxy.SendMessageCompleted? +=newEventHandler<ChatService.SendMessageCompletedEventArgs>(SendMessageComleted);?
??????????? proxy.SendMessageAsync(message);?

??????????? this.txtMessage.Text ="";?
??????? }?
??????? voidSendMessageComleted(objectsender, ChatService.SendMessageCompletedEventArgs e)?
??????? {?
??????????? if(e.Error ==null)?
??????????? {?
??????????????? //MessageBox.Show(e.Result.ToString());
}?
??????? }?
??????? #endregion

??????? #region關閉窗口
??????? privatevoidbtnClose_Click(objectsender, EventArgs e)?
??????? {?

??????? }?
??????? #endregion
??? }?
}

效果圖:

源代碼(包含視頻部分):http://files.cnblogs.com/wengyuli/Chat_%e5%8f%8c%e5%b7%a5http.7z

轉載于:https://www.cnblogs.com/niuxiaohao/archive/2011/06/08/2075577.html

總結

以上是生活随笔為你收集整理的【转】利用WCF的双工通信的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。