
HttpRuntime.Cache
SendMessage.aspx:發送訊息頁面ISendMessageService.cs / SendMessageService.svc:WCF 雙工服務定義與實作GetMessageForm.cs:WinForms 接收視窗MessageEntity.cs:訊息資料合約[DataContract]
public class MessageEntity {
[DataMember] public string Content { get; set; }
}
[ServiceContract(CallbackContract = typeof(ISendMessageServiceCallback))]
public interface ISendMessageService {
[OperationContract(IsOneWay = true)] void GetMessage();
}
public interface ISendMessageServiceCallback {
[OperationContract(IsOneWay = true)] void ReceiveMessage(MessageEntity messageEntity);
}
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class SendMessageService : ISendMessageService
{
ISendMessageServiceCallback _callback;
Timer _timer;
Random _rnd = new Random();
public void GetMessage()
{
_callback = OperationContext.Current.GetCallbackChannel();
_timer = new Timer(PollCache, null, 3000, Timeout.Infinite);
}
void PollCache(object state)
{
var list = HttpRuntime.Cache["MessageEntityList"] as List;
if (list != null && list.Count > 0)
{
var msg = list[0];
list.RemoveAt(0);
HttpRuntime.Cache["MessageEntityList"] = list;
_callback.ReceiveMessage(msg);
}
_timer.Change(_rnd.Next(2000, 5000), Timeout.Infinite);
}
}
<service behaviorConfiguration="WebApp.SendMessageServiceBehavior" name="WebApp.SendMessageService">
<endpoint address="" binding="wsDualHttpBinding" contract="WebApp.ISendMessageService">
<identity><dns value="localhost"/></identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
必須使用 wsDualHttpBinding 支援雙工通訊。
protected void btnSend_Click(object sender, EventArgs e)
{
var msg = new MessageEntity { Content = txtMessageContent.Text };
var list = HttpRuntime.Cache["MessageEntityList"] as List ?? new List();
list.Add(msg);
HttpRuntime.Cache["MessageEntityList"] = list;
lbCacheCount.Text = list.Count.ToString();
}
public partial class GetMessageForm : Form, ISendMessageServiceCallback
{
SendMessageServiceClient _client;
public GetMessageForm()
{
InitializeComponent();
_client = new SendMessageServiceClient(new InstanceContext(this));
}
private void btnStartGet_Click(object sender, EventArgs e)
{
_client.GetMessage();
}
public void ReceiveMessage(MessageEntity messageEntity)
{
if (listbMessage.InvokeRequired)
listbMessage.Invoke(new Action(() => listbMessage.Items.Add(messageEntity.Content)));
else
listbMessage.Items.Add(messageEntity.Content);
}
}
.svc 可正常瀏覽wsDualHttpBinding 需要客戶端可對外開啟連接埠 (防火牆/NAT 環境需額外配置)netTcpBinding + 雙工或 SignalR 等現代替代方案