您的位置:首页 > 理论基础 > 计算机网络

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

2011-12-01 19:04 531 查看
[源码下载]

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

作者:webabcd

介绍

Silverlight 4.0 通信方面的增强:

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

在线DEMO

/article/4589659.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

[源码下载]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐