using Sy
stem;
using Sy
stem.Collection
s.Generi
c;
using Sy
stem.Linq;
using Sy
stem.Net;
using Sy
stem.Windows;
using Sy
stem.Window
s.Controls;
using Sy
stem.Window
s.Documents;
using Sy
stem.Window
s.Input;
using Sy
stem.Window
s.Media;
using Sy
stem.Window
s.Media.Animation;
using Sy
stem.Window
s.Shapes;
using Sy
stem.
serviceModel;
using Sy
stem.
serviceMode
l.Ch
Annels;
using Sy
stem.Threading;
using Sy
stem.IO;
namespace Silverlight20.Communication
{
public partial
class Duplex
service : UserControl
{
SynchronizationCo
ntext _syncCo
ntext;
// 是否接收服务端发送过来的消息
bool _status =
true;
public Duplex
service()
{
initializeComponent(
);
}
private
void btnSubmit_Click(
object sender,RoutedEventArgs
E)
{
_status =
true;
// UI 线程
_syncCo
ntext = SynchronizationCo
ntext.Current;
PollingDuplex
httpBinding binding =
new PollingDuplex
httpBinding()
{
// InactivityTimeout - 服务端与客户端在此超时时间内无任何消息交换的情况下,服务会关闭其会话
inactivityTimeout = TimeSpan.From
minutes
(1)
};
// 构造 IDuplexSessionChAnnel 的信道工厂
ICh
AnnelFactory<IDuplexSessionCh
Annel> factory =
binding
.buildCh
AnnelFactory<IDuplexSessionCh
Annel>(
new BindingParameterCollection()
);
// 打开信道工厂
IAsyncResult factoryOpenResult =
factory
.beginOpen(
new AsyncCall
BACk(OnOpenCompleteFactory),factory
);
if (factoryOpenResult.CompletedSynchronously)
{
// 如果信道工厂被打开的这个 异步操作 已经被 同步完成 则执行下一步
CompleteOpenFactory(factoryOpenResult
);
}
}
private
void btnStop_Click(
object sender,RoutedEventArgs
E)
{
_status =
false;
}
void OnOpenCompleteFactory(IAsyncResult result)
{
// 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步
if (result.CompletedSynchronously)
return;
else
CompleteOpenFactory(result
);
}
void CompleteOpenFactory(IAsyncResult result)
{
ICh
AnnelFactory<IDuplexSessionCh
Annel> factory = result.AsyncState
as ICh
AnnelFactory<IDuplexSessionCh
Annel>;
// 完成异步操作,以打开信道工厂
factory.En
dopen(result
);
// 在信道工厂上根据指定的地址创建信道
IDuplexSessionCh
Annel ch
Annel =
factory.CreateCh
Annel(
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)
{
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)
{
try
{
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)
{
CompleteReceive(result);
}
}
void OnReceiveComplete(IAsyncResult result)
{
if (result.CompletedSynchronously)
return;
else
CompleteReceive(result);
}
void CompleteReceive(IAsyncResult result)
{
IDuplexSessionChAnnel chAnnel = (IDuplexSessionChAnnel)result.AsyncState;
try
{
// 完成异步操作,以接收到服务端发过来的消息
message receivedmessage = chAnnel.EndReceive(result);
if (receivedmessage == null)
{
// 服务端会话已被关闭
// 此时应该关闭客户端会话,或向服务端发送消息以启动一个新的会话
}
else
{
// 将接收到的信息输出到界面上
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;
}
}
}