上接稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service)

简介:



客户端:
DuplexService.xaml
<UserControl x:Class="Silverlight20.Communication.DuplexService" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
        <StackPanel HorizontalAlignment="Left" Margin="5"> 
         
                <TextBox x:Name="txtStockCode" Text="请输入股票代码" Margin="5" /> 
                <Button x:Name="btnSubmit" Content="获取股票信息" Click="btnSubmit_Click" Margin="5" /> 
                <Button x:Name="btnStop" Content="停止获取" Click="btnStop_Click"    Margin="5" /> 
                <TextBlock x:Name="lblStockMessage" Margin="5" /> 
         
        </StackPanel> 
</UserControl>
 
DuplexService.xaml.cs
InBlock.gif using System; 
InBlock.gif using System.Collections.Generic; 
InBlock.gif using System.Linq; 
InBlock.gif using System.Net; 
InBlock.gif using System.Windows; 
InBlock.gif using System.Windows.Controls; 
InBlock.gif using System.Windows.Documents; 
InBlock.gif using System.Windows.Input; 
InBlock.gif using System.Windows.Media; 
InBlock.gif using System.Windows.Media.Animation; 
InBlock.gif using System.Windows.Shapes; 
InBlock.gif 
InBlock.gif using System.ServiceModel; 
InBlock.gif using System.ServiceModel.Channels; 
InBlock.gif using System.Threading; 
InBlock.gif using System.IO; 
InBlock.gif 
InBlock.gif namespace Silverlight20.Communication 
InBlock.gif
InBlock.gif         public partial  class DuplexService : UserControl 
InBlock.gif        { 
InBlock.gif                SynchronizationContext _syncContext; 
InBlock.gif 
InBlock.gif                 // 是否接收服务端发送过来的消息 
InBlock.gif                 bool _status =  true
InBlock.gif 
InBlock.gif                 public DuplexService() 
InBlock.gif                { 
InBlock.gif                        InitializeComponent(); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 private  void btnSubmit_Click( object sender, RoutedEventArgs e) 
InBlock.gif                { 
InBlock.gif                        _status =  true
InBlock.gif 
InBlock.gif                         // UI 线程 
InBlock.gif                        _syncContext = SynchronizationContext.Current; 
InBlock.gif 
InBlock.gif                        PollingDuplexHttpBinding binding =  new PollingDuplexHttpBinding() 
InBlock.gif                        { 
InBlock.gif                                 // InactivityTimeout - 服务端与客户端在此超时时间内无任何消息交换的情况下,服务会关闭其会话 
InBlock.gif                                InactivityTimeout = TimeSpan.FromMinutes(1) 
InBlock.gif                        }; 
InBlock.gif 
InBlock.gif                         // 构造 IDuplexSessionChannel 的信道工厂 
InBlock.gif                        IChannelFactory<IDuplexSessionChannel> factory = 
InBlock.gif                                binding.BuildChannelFactory<IDuplexSessionChannel>( new BindingParameterCollection()); 
InBlock.gif 
InBlock.gif                         // 打开信道工厂 
InBlock.gif                        IAsyncResult factoryOpenResult = 
InBlock.gif                                factory.BeginOpen( new AsyncCallback(OnOpenCompleteFactory), factory); 
InBlock.gif 
InBlock.gif                         if (factoryOpenResult.CompletedSynchronously) 
InBlock.gif                        { 
InBlock.gif                                 // 如果信道工厂被打开的这个 异步操作 已经被 同步完成 则执行下一步 
InBlock.gif                                CompleteOpenFactory(factoryOpenResult); 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 private  void btnStop_Click( object sender, RoutedEventArgs e) 
InBlock.gif                { 
InBlock.gif                        _status =  false
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 void OnOpenCompleteFactory(IAsyncResult result) 
InBlock.gif                { 
InBlock.gif                         // 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步 
InBlock.gif                         if (result.CompletedSynchronously) 
InBlock.gif                                 return
InBlock.gif                         else 
InBlock.gif                                CompleteOpenFactory(result); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 void CompleteOpenFactory(IAsyncResult result) 
InBlock.gif                { 
InBlock.gif                        IChannelFactory<IDuplexSessionChannel> factory = result.AsyncState  as IChannelFactory<IDuplexSessionChannel>; 
InBlock.gif 
InBlock.gif                         // 完成异步操作,以打开信道工厂 
InBlock.gif                        factory.EndOpen(result); 
InBlock.gif 
InBlock.gif                         // 在信道工厂上根据指定的地址创建信道 
InBlock.gif                        IDuplexSessionChannel channel = 
InBlock.gif                                factory.CreateChannel( new EndpointAddress( "http://localhost:3036/DuplexService.svc")); 
InBlock.gif 
InBlock.gif                        // 打开信道 
InBlock.gif                        IAsyncResult channelOpenResult = 
InBlock.gif                                channel.BeginOpen(new AsyncCallback(OnOpenCompleteChannel), channel); 
InBlock.gif 
InBlock.gif                        if (channelOpenResult.CompletedSynchronously) 
InBlock.gif                        { 
InBlock.gif                                // 如果信道被打开的这个 异步操作 已经被 同步完成 则执行下一步 
InBlock.gif                                CompleteOpenChannel(channelOpenResult); 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void OnOpenCompleteChannel(IAsyncResult result) 
InBlock.gif                { 
InBlock.gif                        // 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步 
InBlock.gif                        if (result.CompletedSynchronously) 
InBlock.gif                                return
InBlock.gif                        else 
InBlock.gif                                CompleteOpenChannel(result); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void CompleteOpenChannel(IAsyncResult result) 
InBlock.gif                { 
InBlock.gif                        IDuplexSessionChannel channel = result.AsyncState as IDuplexSessionChannel; 
InBlock.gif 
InBlock.gif                        // 完成异步操作,以打开信道 
InBlock.gif                        channel.EndOpen(result); 
InBlock.gif 
InBlock.gif                        // 构造需要发送到服务端的 System.ServiceModel.Channels.Message (客户端终结点与服务端终结点之间的通信单元) 
InBlock.gif                        Message message = Message.CreateMessage( 
InBlock.gif                                channel.GetProperty<MessageVersion>(), // MessageVersion.Soap11 (Duplex 服务仅支持 Soap11) 
InBlock.gif                                "Silverlight20/IDuplexService/SendStockCode"// Action 为请求的目的地(需要执行的某行为的路径) 
InBlock.gif                                txtStockCode.Text); 
InBlock.gif 
InBlock.gif                        // 向目的地发送消息 
InBlock.gif                        IAsyncResult resultChannel = 
InBlock.gif                                channel.BeginSend(message, new AsyncCallback(OnSend), channel); 
InBlock.gif 
InBlock.gif                        if (resultChannel.CompletedSynchronously) 
InBlock.gif                        { 
InBlock.gif                                // 如果向目的地发送消息的这个 异步操作 已经被 同步完成 则执行下一步 
InBlock.gif                                CompleteOnSend(resultChannel); 
InBlock.gif                        } 
InBlock.gif 
InBlock.gif                        // 监听指定的信道,用于接收返回的消息 
InBlock.gif                        ReceiveLoop(channel); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void OnSend(IAsyncResult result) 
InBlock.gif                { 
InBlock.gif                        // 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步 
InBlock.gif                        if (result.CompletedSynchronously) 
InBlock.gif                                return
InBlock.gif                        else 
InBlock.gif                                CompleteOnSend(result); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void CompleteOnSend(IAsyncResult result) 
InBlock.gif                { 
InBlock.gif                        try 
InBlock.gif                        { 
InBlock.gif                                IDuplexSessionChannel channel = (IDuplexSessionChannel)result.AsyncState; 
InBlock.gif 
InBlock.gif                                // 完成异步操作,以完成向目的地发送消息的操作 
InBlock.gif                                channel.EndSend(result); 
InBlock.gif                        } 
InBlock.gif                        catch (Exception ex) 
InBlock.gif                        { 
InBlock.gif                                _syncContext.Post(WriteText, ex.ToString() + Environment.NewLine); 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void ReceiveLoop(IDuplexSessionChannel channel) 
InBlock.gif                { 
InBlock.gif                        // 监听指定的信道,用于接收返回的消息 
InBlock.gif                        IAsyncResult result =    
InBlock.gif                                channel.BeginReceive(new AsyncCallback(OnReceiveComplete), channel); 
InBlock.gif 
InBlock.gif                        if (result.CompletedSynchronously) 
InBlock.gif                        { 
InBlock.gif                                CompleteReceive(result); 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void OnReceiveComplete(IAsyncResult result) 
InBlock.gif                { 
InBlock.gif                        if (result.CompletedSynchronously) 
InBlock.gif                                return
InBlock.gif                        else 
InBlock.gif                                CompleteReceive(result); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void CompleteReceive(IAsyncResult result) 
InBlock.gif                { 
InBlock.gif                        IDuplexSessionChannel channel = (IDuplexSessionChannel)result.AsyncState; 
InBlock.gif 
InBlock.gif                        try 
InBlock.gif                        { 
InBlock.gif                                // 完成异步操作,以接收到服务端发过来的消息 
InBlock.gif                                Message receivedMessage = channel.EndReceive(result); 
InBlock.gif 
InBlock.gif                                if (receivedMessage == null
InBlock.gif                                { 
InBlock.gif                                        // 服务端会话已被关闭 
InBlock.gif                                        // 此时应该关闭客户端会话,或向服务端发送消息以启动一个新的会话 
InBlock.gif                                } 
InBlock.gif                                else 
InBlock.gif                                { 
InBlock.gif                                        // 将接收到的信息输出到界面上 
InBlock.gif                                        string text = receivedMessage.GetBody<string>(); 
InBlock.gif                                        _syncContext.Post(WriteText, text + Environment.NewLine); 
InBlock.gif 
InBlock.gif                                        if (!_status) 
InBlock.gif                                        { 
InBlock.gif                                                // 关闭信道 
InBlock.gif                                                IAsyncResult resultFactory = 
InBlock.gif                                                        channel.BeginClose(new AsyncCallback(OnCloseChannel), channel); 
InBlock.gif 
InBlock.gif                                                if (resultFactory.CompletedSynchronously) 
InBlock.gif                                                { 
InBlock.gif                                                        CompleteCloseChannel(result); 
InBlock.gif                                                } 
InBlock.gif 
InBlock.gif                                        } 
InBlock.gif                                        else 
InBlock.gif                                        { 
InBlock.gif                                                // 继续监听指定的信道,用于接收返回的消息 
InBlock.gif                                                ReceiveLoop(channel); 
InBlock.gif                                        } 
InBlock.gif                                } 
InBlock.gif                        } 
InBlock.gif                        catch (Exception ex) 
InBlock.gif                        { 
InBlock.gif                                // 出错则记日志 
InBlock.gif                                using (StreamWriter sw = new StreamWriter(@"C:\Silverlight_Duplex_Log.txt"true)) 
InBlock.gif                                { 
InBlock.gif                                        sw.Write(ex.ToString()); 
InBlock.gif                                        sw.WriteLine(); 
InBlock.gif                                } 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void OnCloseChannel(IAsyncResult result) 
InBlock.gif                { 
InBlock.gif                        if (result.CompletedSynchronously) 
InBlock.gif                                return
InBlock.gif                        else 
InBlock.gif                                CompleteCloseChannel(result); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void CompleteCloseChannel(IAsyncResult result) 
InBlock.gif                { 
InBlock.gif                        IDuplexSessionChannel channel = (IDuplexSessionChannel)result.AsyncState; 
InBlock.gif 
InBlock.gif                        // 完成异步操作,以关闭信道 
InBlock.gif                        channel.EndClose(result); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void WriteText(object text) 
InBlock.gif                { 
InBlock.gif                        // 将信息打到界面上 
InBlock.gif                        lblStockMessage.Text += (string)text; 
InBlock.gif                } 
InBlock.gif        } 
InBlock.gif}
 
 



     本文转自webabcd 51CTO博客,原文链接: http://blog.51cto.com/webabcd/343810 ,如需转载请自行联系原作者

相关文章
|
XML 网络协议 IDE
WCF基础教程(三)——WCF通信过程及配置文件解析
WCF基础教程(三)——WCF通信过程及配置文件解析
294 0
WCF基础教程(三)——WCF通信过程及配置文件解析
|
JavaScript
|
Web App开发 JavaScript 前端开发