• 稳扎稳打Silverlight(53) 4.0通信之对WCF NetTcpBinding的支持, 在Socket通信中通过HTTP检索策略文件, HTTP请求中的ClientHttp和BrowserHttp


    [索引页]
    [源码下载]


    稳扎稳打Silverlight(53) - 4.0通信之对WCF NetTcpBinding的支持, 在Socket通信中通过HTTP检索策略文件, HTTP请求中的ClientHttp和BrowserHttp



    作者:webabcd


    介绍
    Silverlight 4.0 通信方面的增强:

    • NetTcpBinding - 通过  NetTcpBinding 与 WCF 服务进行通信
    • 支持在 Socket 通信中通过 HTTP 的方式检索策略文件 
    • HTTP 请求中的 ClientHttp 方式和 BrowserHttp 方式的应用



    在线DEMO
    http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html


    示例
    1、演示如何通过 NetTcpBinding 与 WCF 进行双向通信
    服务端:
    IDuplex.cs

    代码
    /*
     * 双向通信的 Contract
     
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using System.ServiceModel;

    namespace SocketServer
    {
        [ServiceContract(CallbackContract 
    = typeof(IDuplexCallback))]
        
    public interface IDuplex
        {
            [OperationContract(IsOneWay 
    = true)]
            
    void HelloDuplex(string msg);
        }

        
    public interface IDuplexCallback
        {
            [OperationContract(IsOneWay 
    = true)]
            
    void HelloDuplexCallback(string msg);
        }
    }


    Duplex.cs

    代码
    /*
     * 实现 IDuplex 契约
     
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using System.ServiceModel;

    namespace SocketServer
    {
        
    public class Duplex : IDuplex
        {
            
    private IDuplexCallback _callback;

            
    // 服务端方法,其用于被客户端调用
            public void HelloDuplex(string msg)
            {
                Program.Form1.ShowMessage(msg);

                
    if (_callback == null)
                {
                    
    // 实例化回调接口
                    _callback = OperationContext.Current.GetCallbackChannel<IDuplexCallback>();

                    
    // 每一秒调用一次回调接口(即调用客户端的方法)
                    System.Timers.Timer timer = new System.Timers.Timer();
                    timer.Interval 
    = 3000d;
                    timer.Elapsed 
    += delegate { _callback.HelloDuplexCallback("服务端发给客户端的信息:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); };
                    timer.Start();
                }
            }
        }
    }


    App.config

    代码
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        
    <system.serviceModel>
            
    <services>
                
    <!--
                    元数据地址:http://localhost:12345/SocketServer/Duplex/mex
                    TCP 地址:net.tcp://localhost:4502/SocketServer/Duplex
                    TCP 端口限制在 4502 - 4534 之间
                
    -->
                
    <service name="SocketServer.Duplex">
                    
    <endpoint address="SocketServer/Duplex" binding="customBinding" contract="SocketServer.IDuplex" />
                    
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                    
    <host>
                        
    <baseAddresses>
                            
    <add baseAddress="http://localhost:12345/SocketServer/Duplex" />
                            
    <add baseAddress="net.tcp://localhost:4502/" />
                        
    </baseAddresses>
                    
    </host>
                
    </service>
            
    </services>
            
            
    <!--
                Silverlight 4.0 对 NetTcpBinding 的支持是通过自定义绑定的方式来实现的。服务端和客户端都需要使用自定义绑定
            
    -->
            
    <bindings>
                
    <customBinding>
                    
    <binding>
                        
    <binaryMessageEncoding></binaryMessageEncoding>
                        
    <tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                    
    </binding>
                
    </customBinding>
            
    </bindings>
            
            
    <behaviors>
                
    <serviceBehaviors>
                    
    <behavior>
                        
    <serviceMetadata httpGetEnabled="true" />
                        
    <serviceDebug includeExceptionDetailInFaults="true"/>
                    
    </behavior>
                
    </serviceBehaviors>
            
    </behaviors>
        
    </system.serviceModel>
    </configuration>


    Form1.cs

    代码
    // 启动 WCF 服务,用于演示 Silverlight 4.0 与 WCF 的交互(基于 NetTcpBinding 绑定)
    private void LaunchNetTcpBinding()
    {
        ServiceHost host 
    = new ServiceHost(typeof(SocketServer.Duplex));
        host.Open();

        ShowMessage(
    "演示 NetTcpBinding 的 WCF 服务已启动");
    }


    客户端(需要引用服务的元数据):
    NetTcpBinding.xaml

    代码
    <navigation:Page x:Class="Silverlight40.Communication.NetTcpBinding" 
               xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
               xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml" 
               xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008"
               xmlns:mc
    ="http://schemas.openxmlformats.org/markup-compatibility/2006"
               xmlns:navigation
    ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
               Title
    ="NetTcpBinding Page">
        
    <Grid x:Name="LayoutRoot">
            
    <StackPanel HorizontalAlignment="Left">

                
    <Button Name="btnSend" Content="发送信息到服务端" Click="btnSend_Click" />
                
                
    <TextBlock Name="lblMsg" />
                
            
    </StackPanel>
        
    </Grid>
    </navigation:Page>


    NetTcpBinding.xaml.cs

    代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Navigation;

    using System.ServiceModel;
    using System.Net.Sockets;
    using System.ServiceModel.Channels;

    namespace Silverlight40.Communication
    {
        
    public partial class NetTcpBinding : Page, DuplexServiceReference.IDuplexCallback
        {
            
    private DuplexServiceReference.DuplexClient _client;

            
    public NetTcpBinding()
            {
                InitializeComponent();
            }

            
    protected override void OnNavigatedTo(NavigationEventArgs e)
            {
               
            }


            
    private void btnSend_Click(object sender, RoutedEventArgs e)
            {
                
    // 客户端与服务端之间如果没有信道的话,则产生这个信道
                if (_client == null)
                {
                    var ctx 
    = new InstanceContext(this);
                    
                    
    // 通过配置文件的方式建立信道
                    _client = new DuplexServiceReference.DuplexClient(ctx);

                    
    // 通过编写代码的方式建立信道
                    /*
                    EndpointAddress ea = new EndpointAddress("net.tcp://localhost:4502/SocketServer/Duplex");
                    BindingElement be = new TcpTransportBindingElement();
                    CustomBinding cb = new CustomBinding(be);
                    _client = new DuplexServiceReference.DuplexClient(ctx, cb, ea);
                    
    */
                }

                
    // 调用服务端的方法
                _client.HelloDuplexAsync("客户端发给服务端的信息:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                
    // _client.HelloDuplexCompleted - 在此 Handler 中获取服务端方法的返回值,因为本例是 IsOneWay 方式,所以没有返回值
            }

            
    // 客户端方法,其用于被服务端调用
            public void HelloDuplexCallback(string msg)
            {
                lblMsg.Text 
    += msg + "\n";
            }
        }
    }


    ServiceReferences.ClientConfig

    代码
    <configuration>
        
    <system.serviceModel>
            
    <!--
                使用 NetTcpBinding 绑定需要先引用 System.ServiceModel.NetTcp.dll 程序集
            
    -->
            
    <client>
                
    <endpoint address="net.tcp://localhost:4502/SocketServer/Duplex" binding="customBinding" contract="DuplexServiceReference.IDuplex"
                          bindingConfiguration
    ="netTcpBinding" />
            
    </client>

            
    <!--
                Silverlight 4.0 对 NetTcpBinding 的支持是通过自定义绑定的方式来实现的。服务端和客户端都需要使用自定义绑定
            
    -->
            
    <bindings>
                
    <customBinding>
                    
    <binding name="netTcpBinding">
                        
    <binaryMessageEncoding />
                        
    <tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                    
    </binding>
                
    </customBinding>
            
    </bindings>
        
    </system.serviceModel>
    </configuration>



    2、通过 HTTP 的方式检索 Socket 通信的安全策略
    SocketClientRetrievePolicyFileViaHttp.xaml

    代码
    <navigation:Page x:Class="Silverlight40.Communication.SocketClientRetrievePolicyFileViaHttp" 
               xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
               xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml" 
               xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008"
               xmlns:mc
    ="http://schemas.openxmlformats.org/markup-compatibility/2006"
               xmlns:navigation
    ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
               Title
    ="SocketCommunicationRetrievePolicyFileViaHttp Page">
        
    <Grid x:Name="LayoutRoot">

            
    <TextBlock>
                
    <Run>以前的 Socket 通信,在连接之前先要以 943 端口的 TCP 方式在服务端检索策略文件</Run>
                
    <LineBreak />
                
    <Run>Silverlight 4.0 中的 Socket 通信可以通过 80 端口的 HTTP 方式检索策略文件,获取到的策略文件作用于此 HTTP 地址所解析出的 IP</Run>
                
    <LineBreak />
                
    <Run>System.Net.Sockets.SocketAsyncEventArgs.SocketClientAccessPolicyProtocol - 指定 Socket 通信检索策略文件的方式 [System.Net.Sockets.SocketClientAccessPolicyProtocol 枚举]</Run>
                
    <LineBreak />
                
    <Run>可能的值有:System.Net.Sockets.SocketClientAccessPolicyProtocol.Http 和 System.Net.Sockets.SocketClientAccessPolicyProtocol.Tcp</Run>
            
    </TextBlock>
            
        
    </Grid>
    </navigation:Page>



    3、两种 HTTP 请求方式,即 ClientHttp 和 BrowserHttp 的区别
    服务端:
    HttpResult.aspx.cs

    代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    namespace Silverlight40.Web
    {
        
    public partial class HttpResult : System.Web.UI.Page
        {
            
    protected void Page_Load(object sender, EventArgs e)
            {
                
    // 返回当前 HTTP 请求的 HTTP 方法及 Cookie
                Response.Write(string.Format("HttpMethod: {0}, Cookie - name: {1}", Request.HttpMethod, Request.Cookies["name"].Value));
                Response.End();
            }
        }
    }


    客户端:
    ClientHttpAndBrowserHttp.xaml.cs

    代码
    /*
     * BrowserHttp - 由浏览器构造 HTTP 请求。默认值
     * ClientHttp - 由 Silverlight 客户端构造 HTTP 请求
     * 
     * 指定 HTTP 请求为 BrowserHttp 类型或 ClientHttp 类型的方法如下:
     *     WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp); - 根据前缀指定 HTTP 请求的方式
     *     (HttpWebRequest)WebRequestCreator.ClientHttp.Create(); - 为单个请求指定 HTTP 请求的方式
     * 
     * 本例演示如果通过 ClientHttp,来实现 PUT 方法的 HTTP 请求以及如何手动构造 Cookie(这些在 BrowserHttp 方式下是无法实现的)
     * 详细的 BrowserHttp 和 ClientHttp 的区别参看文档
     
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Navigation;

    using System.Net.Browser;
    using System.IO;
    using System.Threading;

    namespace Silverlight40.Communication
    {
        
    public partial class ClientHttpAndBrowserHttp : Page
        {
            SynchronizationContext _syncContext;

            
    public ClientHttpAndBrowserHttp()
            {
                InitializeComponent();
            }

            
    protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                _syncContext 
    = SynchronizationContext.Current;

                
    // 创建一个 ClientHttp 方式的 HttpWebRequest 对象
                HttpWebRequest request = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(new Uri("http://localhost:9483/HttpResult.aspx"));

                
    // ClientHttp 可以使用任何 Http 方法(BrowserHttp 只能使用 GET 和 POST)
                request.Method = "PUT";

                
    // ClientHttp 可以手工构造 Cookie(如果需要 Forms 验证或 NTLM 验证则只能通过 BroswerHttp 方式)
                request.CookieContainer = new CookieContainer();
                request.CookieContainer.Add(
    new Uri("http://localhost:9483"), new Cookie("name""webabcd"));

                request.BeginGetResponse(
    new AsyncCallback(ResponseCallback), request);

            }

            
    // 获取服务返回的结果
            private void ResponseCallback(IAsyncResult result)
            {
                HttpWebRequest request 
    = result.AsyncState as HttpWebRequest;
                WebResponse response 
    = request.EndGetResponse(result) as HttpWebResponse;

                
    if (response != null)
                {
                    Stream responseStream 
    = response.GetResponseStream();
                    
    using (StreamReader sr = new StreamReader(responseStream))
                    {
                        
    string s = sr.ReadToEnd();
                        Deployment.Current.Dispatcher.BeginInvoke(
    delegate { MessageBox.Show(s); });
                    }
                }
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    团队开发5
    团队开发4
    团队开发3
    团队开发2
    团队开发1
    团队计划会议
    寒假学习进度---完结篇
    寒假学习进度十七
    寒假学习进度十六
    python后续学习
  • 原文地址:https://www.cnblogs.com/webabcd/p/1827752.html
Copyright © 2020-2023  润新知