silverlight
发布时间:2022-05-04 发布网站:大佬教程 code.js-code.com
大佬教程收集整理的这篇文章主要介绍了稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service),大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
概述
[索引页] [源码下载] 稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex
servic
E) 作者: webabcd 介绍 Silverlight 2.0 调用 WCF 的双向通信服务(Duplex
servic
E) 。开发一个服务端主动向客服端发送股票信息的程序,首先客户端先向服务端发送需要监控的股票的股票代码,然后服务端在该股信息发生变化的时候将信息推
[索引页]
[源码下载]
稳扎稳打Silverlight(23) - 2.0通信之
调用WCF的双向通信(Duplex
servic
E)
作者:
webabcd
介绍
Silverlight 2.0
调用 WCF 的双向通信服务(Duplex
servic
E) 。开发
一个服务端主动向客服端发送股票信息的程序,首先客户端先向服务端发送需要监控的股票的股票
代码,然后服务端在该股信息发生变化的时候将信息推送到客户端。
服务端:
定义服务契约及回调接口
从当前上下文
获取回调的客户端信道
需要的话则向客户端信道“推”消息
客户端:
构造 PollingDuplex
httpBinding 并在其上创建 IDuplexSessionCh
Annel 的信道工厂
异步方式打开信道工厂
异步方式打开信道
构造需要发送到服务端的消息 Sy
stem.
serviceMode
l.Ch
Annel
s.message
异步向服务端发送消息
监听指定信道,用于异步方式接收服务端返回的消息
不需要再接收服务端的消息则
关闭信道
在线DEMO
http://www.cnblogs.com/webabcd/archive/2008/10/09/1307486.html
示例
服务端:
IDuplex
service.cs
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Runtime.serialization;
using
System.serviceModel;
using
System.Text;
using
System.serviceModel.ChAnnels;
/**/
/// <sumMary>
/// IDuplexservice - 双工(Duplex)服务契约
/// CallBACkContract - 双工(Duplex)服务的回调类型
/// </sumMary>
[serviceContract(Namespace
=
"
Silverlight20
"
, CallBACkContract
=
typeof
(IDuplexClient))]
public
interface
IDuplexservice
{
/**//// <sumMary>
/// 客户端向服务端发送消息的方法
/// </sumMary>
/// <param NAME="receivedmessage">客户端向服务端发送的消息 System.serviceModel.ChAnnels.message</param>
[OperationContract(IsOneWay = true)]
void SendStockCode(message receivedmessagE);
}
@H_607_363@
@H_675_368@
/**/
/// <sumMary>
/// 双工(Duplex)服务的回调接口
/// </sumMary>
public
interface
IDuplexClient
{
/**//// <sumMary>
/// 客户端接收服务端发送过来的消息的方法
/// </sumMary>
/// <param NAME="returnmessage">服务端向客户端发送的消息 System.serviceModel.ChAnnels.message</param>
[OperationContract(IsOneWay = true)]
void receiveStockmessage(message returnmessagE);
}
Duplex
service.cs
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Runtime.serialization;
using
System.serviceModel;
using
System.Text;
using
System.serviceModel.ChAnnels;
using
System.Threading;
using
System.serviceModel.Activation;
using
System.IO;
/**/
/// <sumMary>
/// Duplex 服务的服务端的实现
/// 本文以客户端向服务端提交股票代码,服务端定时向客户端发送股票信息为例
/// </sumMary>
public
class
Duplexservice : IDuplexservice
{
IDuplexClient _client;
bool _status = true;
/**//// <sumMary>
/// 客户端向服务端发送股票代码的方法
/// </sumMary>
/// <param NAME="receivedmessage">包含股票代码的 System.serviceModel.ChAnnels.message </param>
public void SendStockCode(message receivedmessagE)
{
// 获取当前上下文的回调信道
_client = OperationContext.Current.GetCallBACkChAnnel<IDuplexClient>();
// 如果发生错误则不再执行
OperationContext.Current.ChAnnel.Faulted += new EventHandler(delegate { _status = false; });
// 获取用户提交的股票代码
String stockCode = receivedmessage.GetBody<String>();
// 每3秒向客户端发送一次股票信息
while (_status)
{
// 构造需要发送到客户端的 System.serviceModel.ChAnnels.message
// Duplex 服务仅支持 Soap11 , Action 为请求的目的地(需要执行的某行为的路径)
message stockmessage = message.Createmessage(
messageVersion.soap11,
"Silverlight20/IDuplexservice/ReceiveStockmessage",
String.Format("StockCode: {0}; StockPrice: {1}; CurrentTime: {2}",
stockCode,
new random().Next(1, 200),
datetiR_461_11845@e.Now.ToString()));
try
{
// 向客户端“推”数据
_client.ReceiveStockmessage(stockmessagE);
}
catch (Exception eX)
{
// 出错则记日志
using (StreamWriter sw = new StreamWriter(@"C:/Silverlight_Duplex_Log.txt", true))
{
sw.Write(ex.ToString());
sw.WriteLine();
}
}
System.Threading.Thread.Sleep(3000);
}
}
}
PollingDuplex
serviceHostFactory.cs
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
System.serviceModel;
using
System.serviceModel.ChAnnels;
using
System.serviceModel.Activation;
/**/
/* 以下部分摘自文档 */
//
服务 svc 文件的 Factory 要指定为此类
public
class
PollingDuplexserviceHostFactory : serviceHostFactoryBase
{
public override serviceHostBase CreateserviceHost(String constructorString,
UrI[] baseAddresses)
{
return new PollingDuplexSimplexserviceHost(baseAddresses);
}
}
class
PollingDuplexSimplexserviceHost : serviceHost
@H_720_1675@
{
public PollingDuplexSimplexserviceHost(params System.UrI[] addresses)
{
base.InitializeDescription(typeof(DuplexservicE), new UrischeR_461_11845@eKeyedCollection(addresses));
}
protected override void InitializeRuntime()
{
// 配置 WCF 服务与 Silverlight 客户端之间的 Duplex 通信
// Silverlight 客户端定期轮询网络层上的服务,并检查回调信道上由服务端发送的所有新的消息
// 该服务会将回调信道上的由服务端发送的所有消息进行排队,并在客户端轮询服务时将这些消息传递到该客户端
PollingDuplexBindingElement pdbe = new PollingDuplexBindingElement()
{
// ServerPollTimeout - 轮询超时时间
// InactivityTimeout - 服务端与客户端在此超时时间内无任何消息交换的情况下,服务会关闭其会话
ServerPollTimeout = TimeSpan.FromSeconds(3),
inactivityTimeout = TimeSpan.Fromminutes(1)
};
// 为服务契约(service contract)添加一个终结点(endpoint)
// Duplex 服务仅支持 Soap11
this.AddserviceEndpoint(
typeof(IDuplexservicE),
new CustomBinding(
pdbe,
new textmessageEncodingBindingElement(
messageVersion.soap11,
System.Text.Encoding.UTF8),
new httpTransportBindingElement()),
"");
base.InitializeRuntime();
}
}
Duplex
service.svc
<%
@ serviceHost Language="C#" Debug="true" service="Duplexservice" CodeBehind="~/App_Code/Duplexservice.cs" Factory="PollingDuplexserviceHostFactory"
%>
客户端:
Duplex
service.xaml
<
UserControl
x:Class
="Silverlight20.Communication.Duplexservice"
xmlns
="http://scheR_461_11845@as.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://scheR_461_11845@as.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
>
Duplex
service.xam
l.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.serviceModel;
using
System.serviceModel.ChAnnels;
using
System.Threading;
using
System.IO;
namespace
Silverlight20.Communication
@H_
489_2593@
{
public partial class Duplexservice : UserControl
@H_227_2623@
@H_304_2628@
{
SynchronizationContext _syncContext;
// 是否接收服务端发送过来的消息
bool _status = true;
public Duplexservice()
{
initializeComponent();
}
private void btnSubmit_Click(object sender, routedEventArgs E)
{
_status = true;
// UI 线程
_syncContext = SynchronizationContext.Current;
PollingDuplexhttpBinding binding = new PollingDuplexhttpBinding()
{
// InactivityTimeout - 服务端与客户端在此超时时间内无任何消息交换的情况下,服务会关闭其会话
InactivityTimeout = TimeSpan.Fromminutes(1)
};
// 构造 IDuplexSessionChAnnel 的信道工厂
IChAnnelFactory<IDuplexSessionChAnnel> factory =
binding.buildChAnnelFactory<IDuplexSessionChAnnel>(new BindingParameterCollection());
// 打开信道工厂
IAsyncResult factoryOpenResult =
factory.beginOpen(new AsyncCallBACk(OnOpenCompleteFactory), factory);
if (factoryOpenResult.CompletedSynchronously)
{
// 如果信道工厂被打开的这个 异步操作 已经被 同步完成 则执行下一步
CompleteOpenFactory(factoryOpenResult);
}
}
private void btnStop_Click(object sender, routedEventArgs E)
@H_404_2522@{
_status = false;
}
void OnOpenCompleteFactory(IAsyncResult result)
{
// 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步
if (result.CompletedSynchronously)
return;
else
CompleteOpenFactory(result);
}
void CompleteOpenFactory(IAsyncResult result)
@H_443_3262@
{
IChAnnelFactory<IDuplexSessionChAnnel> factory = result.AsyncState as IChAnnelFactory<IDuplexSessionChAnnel>;
// 完成异步操作,以打开信道工厂
factory.Endopen(result);
// 在信道工厂上根据指定的地址创建信道
IDuplexSessionChAnnel chAnnel =
factory.CreateChAnnel(new EndpointAddress("http://localhost:3036/Duplexservice.svc"));
// 打开信道
IAsyncResult chAnnelOpenResult =
chAnnel.beginOpen(new AsyncCallBACk(OnOpenCompleteChAnnel), chAnnel);
if (chAnnelOpenResult.CompletedSynchronously)
{
// 如果信道被打开的这个 异步操作 已经被 同步完成 则执行下一步
CompleteOpenChAnnel(chAnnelOpenResult);
}
}
void OnOpenCompleteChAnnel(IAsyncResult result)
{
// 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步
if (result.CompletedSynchronously)
return;
else
CompleteOpenChAnnel(result);
}
void CompleteOpenChAnnel(IAsyncResult result)
@H_366_3618@{
IDuplexSessionChAnnel chAnnel = result.AsyncState as IDuplexSessionChAnnel;
// 完成异步操作,以打开信道
chAnnel.Endopen(result);
// 构造需要发送到服务端的 System.serviceModel.ChAnnels.message (客户端终结点与服务端终结点之间的通信单元)
message message = message.Createmessage(
chAnnel.GetProperty<messageVersion>(), // messageVersion.soap11 (Duplex 服务仅支持 Soap11)
"Silverlight20/IDuplexservice/SendStockCode", // Action 为请求的目的地(需要执行的某行为的路径)
txtStockCode.Text);
// 向目的地发送消息
IAsyncResult resultChAnnel =
chAnnel.beginSend(message, new AsyncCallBACk(OnSend), chAnnel);
if (resultChAnnel.CompletedSynchronously)
{
// 如果向目的地发送消息的这个 异步操作 已经被 同步完成 则执行下一步
CompleteOnSend(resultChAnnel);
}
// 监听指定的信道,用于接收返回的消息
receiveLoop(chAnnel);
}
void OnSend(IAsyncResult result)
{
// 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步
if (result.CompletedSynchronously)
return;
else
CompleteOnSend(result);
}
void CompleteOnSend(IAsyncResult result)
@H_
502_3230@
{
try
@H_489_4038@
{
IDuplexSessionChAnnel chAnnel = (IDuplexSessionChAnnel)result.AsyncState;
// 完成异步操作,以完成向目的地发送消息的操作
chAnnel.EndSend(result);
}
catch (Exception eX)
{
_syncContext.Post(WriteText, ex.ToString() + Environment.NewLinE);
}
}
void receiveLoop(IDuplexSessionChAnnel chAnnel)
{
// 监听指定的信道,用于接收返回的消息
IAsyncResult result =
chAnnel.beginReceive(new AsyncCallBACk(OnReceiveCompletE), chAnnel);
if (result.CompletedSynchronously)
@H_941_3404@
{
CompleteReceive(result);
}
}
void OnReceiveComplete(IAsyncResult result)
{
if (result.CompletedSynchronously)
return;
else
CompleteReceive(result);
}
void CompleteReceive(IAsyncResult result)
{
IDuplexSessionChAnnel chAnnel = (IDuplexSessionChAnnel)result.AsyncState;
try
@H_404_3549@
{
// 完成异步操作,以接收到服务端发过来的消息
message receivedmessage = chAnnel.EndReceive(result);
if (receivedmessage == null)
@H_549_4503@
@H_489_4507@{
// 服务端会话已被关闭
// 此时应该关闭客户端会话,或向服务端发送消息以启动一个新的会话
}
else
{
// 将接收到的信息@L_874_106@到界面上
String text = receivedmessage.GetBody<String>();
_syncContext.Post(WriteText, text + Environment.NewLinE);
if (!_status)
{
// 关闭信道
IAsyncResult resultFactory =
chAnnel.beginClose(new AsyncCallBACk(OnCloseChAnnel), chAnnel);
if (resultFactory.CompletedSynchronously)
{
CompleteCloseChAnnel(result);
}
}
else
{
// 继续监听指定的信道,用于接收返回的消息
receiveLoop(chAnnel);
}
}
}
catch (Exception eX)
{
// 出错则记日志
using (StreamWriter sw = new StreamWriter(@"C:/Silverlight_Duplex_Log.txt", true))
{
sw.Write(ex.ToString());
sw.WriteLine();
}
}
}
void OnCloseChAnnel(IAsyncResult result)
{
if (result.CompletedSynchronously)
return;
else
CompleteCloseChAnnel(result);
}
void CompleteCloseChAnnel(IAsyncResult result)
{
IDuplexSessionChAnnel chAnnel = (IDuplexSessionChAnnel)result.AsyncState;
// 完成异步操作,以关闭信道
chAnnel.EndClose(result);
}
void WriteText(object text)
{
// 将信息打到界面上
lblStockmessage.Text += (String)text;
}
}
}
OK
[源码下载]
大佬总结
以上是大佬教程为你收集整理的稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service)全部内容,希望文章能够帮你解决稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service)所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。