- Microsoft Windows Communication Foundation 4.0 Cookbook for Developing SOA Applications
- Steven Cheng
- 771字
- 2021-04-13 17:04:04
Publish-Subscribe is a common design pattern that is widely used in client/server communication applications. In WCF service development, the Publish-Subscribe pattern will also help in those scenarios where the service application will expose data to certain groups of clients that are interested in the service and the data is provided to clients as a push model actively (instead of polling by the client). This recipe will demonstrate how to implement the Publish-Subscribe pattern in a WCF service through dual binding.
The Publish-Subscribe pattern is widely adopted in various application development scenarios and there are many different kinds of descriptions for this pattern. Refer to the following links for more information:
- Publish/subscribe
- Observer pattern
To implement the Publish-Subscribe pattern, we need to put particular customization in various parts of the WCF service development, including a ServiceContract
design, binding configuration, and service hosting/consuming code. Let’s go through the following steps to build a typical list-based Publish-Subscribe service:
- The first thing to do is to design a
ServiceContract
that supports Publish-Subscribe pattern. The followingIPublicBillboard
interface represents a sample contract for publishing some announcements to client applications that are interested in the service.[ServiceContract(SessionMode=SessionMode.Required, CallbackContract=typeof(IClientReceiver))] public interface IPublicBillboard { [OperationContract(IsInitiating=true)] void Subscribe(); [OperationContract(IsTerminating=true)] void Unsubscribe(); [OperationContract(IsOneWay=true)] void Announce(string msg); } public interface IClientReceiver { [OperationContract(IsOneWay = true)] void GetAnnouncement(string msg); }
In the previous
ServiceContract
, in addition to the main contract interface, we also need to supply aCallbackContract
type, which is used for the service to notify the client proactively. Also, a session has been enabled here so that the service can conveniently identify client callback channels through theirsessionId
. - When implementing the
ServiceContract
,Subscribe
will cache the callback channel via the clientsessionId
so that it can notify the client later (by invoking the callback channel).[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] public class PublicBillboard : IPublicBillboard { object _syncobj = new object(); Dictionary<string, IClientReceiver> _receivers = new Dictionary<string, IClientReceiver>(); public void Subscribe() { string sessionId = OperationContext.Current.SessionId; lock (_syncobj) { if (_receivers.Keys.Contains(sessionId)) { _receivers.Remove(sessionId); } _receivers.Add(sessionId, OperationContext.Current.GetCallbackChannel<IClientReceiver>()); } }
The
Subscribe
method mentioned earlier, gets the clientsessionId
fromOperationContext
and caches the client’s callback channel by thissessionId
. If there is already a callback interface with the samesessionId
cached, the code will remove the existing one first. - In the service endpoint configuration, it is important to select a duplex binding. The sample service here uses WSDualHttpBinding through a configuration file.
- At the client side, we need to provide a type that implements the callback interface and supply this type instance when initializing the service proxy, which is done as follows:
public partial class MainForm : Form, BillboardProxy.IPublicBillboardCallback { BillboardProxy.PublicBillboardClient _boardclient = null; private void MainForm_Load(object sender, EventArgs e) { // Subscribe for the Billboard service _boardclient = new BillboardProxy.PublicBillboardClient(new InstanceContext(this) ); _boardclient.Subscribe(); btnSubmit.Enabled = true; } // Implement the callback interface void BillboardProxy.IPublicBillboardCallback.GetAnnouncement(string msg) { UpdateText(msg); }
The
MainForm
class implements the callback interface and is assigned to the client proxy (through a constructor) at the loading stage. - In the end, the service operation can selectively notify some or all of the clients proactively (refer to the
Announce
operation shown as follows):public void Announce(string msg) { // Enumerate all the client callback channels foreach (string key in _receivers.Keys) { IClientReceiver receiver = _receivers[key]; receiver.GetAnnouncement(string.Format(“{0} announced: {1}”, sessionId, msg)); } }
The service class is decorated as InstanceContextMode=InstanceContextMode.Single
, so that all the clients will share the same service instance. Enabling the session makes the service be able to differentiate clients by their sessionId
. The following screenshot shows the service console, which prints out all new announcements received from the client.

By invoking the Callback channel interface (from each client OperationContext
), the service proactively pushes the new announcement data to all clients immediately.
At the client side, the callback function simply updates the Forum UI and prints the new announcement in the textbox control.

Both the service callback operations are marked as one-way style. This is to make sure that the service operation won’t block the client UI thread when directly invoked in the Button_Click
event (which is also executed in the UI thread).
public interface IPublicBillboard { [OperationContract(IsOneWay=true)] void Announce(string msg); public interface IClientReceiver { [OperationContract(IsOneWay = true)] void GetAnnouncement(string msg);
If you are interested, you can also use asynchronous service execution to avoid these kinds of thread blocking issues.
- Invoking async operation via ChannelFactory in Chapter 5
- Complete source code for this recipe can be found in the
\Chapter
2\recipe3\
folder
- Drupal Multimedia
- After Effects全套影視特效制作典型實例(第2版)
- Django 1.2 E/commerce
- Adobe創意大學Illustrator CS5 產品專家認證標準教材
- Adobe創意大學Photoshop CS5 產品專家認證標準教材
- CAXA電子圖板2016基礎與實例教程
- 人人都能玩賺AI繪畫
- 三維建模與3D打印從入門到精通
- 抖音+剪映+Premiere短視頻制作從新手到高手(第2版)
- 剪映:從零開始精通短視頻剪輯(電腦版)
- Moodle 1.9 Math
- 中文版SolidWorks 2016完全實戰技術手冊
- 新編中文版Photoshop平面設計入門與提高(第2版)
- Oracle Modernization Solutions
- R語言科研繪圖與學術圖表繪制從入門到精通