Creating an IIS hosted web service that uses callbacks and publishes metadata.
For callbacks to work, WCF requires the use of a network protocol that is session based, ruling out http
as a
protocol. Instead, we’ll use net.tcp
as the protocol.
Service Contract
In our example, we’ll create a simple IM chat system. The service contract is very simple:
-
Marking the interface as
SessionMode.Required
ensures that a session based protocol is used, allowing callbacks to be specified. -
The callback interface is specified by
CallbackContract
.
On the server side, the callback contract can have any name - but when the client proxies are generated by svcutil
,
the name used will be the name of the service suffixed with “Callback”. For consistency between client and server code,
I suggest following this convention on the server as well.
Our callback contract looks like this:
Service Implementation
Implementation of the service is straightforward. The class declaration needs some WCF magic:
-
Specifying
InstanceContextMode.PerSession
ensures that we have a separate context for each session. -
ConcurrencyMode.Multiple
is necessary to allow the callbacks to be used.
The implementations of Subscribe()
is simple - we just keep a reference to the OperationContext for later use.
Note that I’ve chosen to retain references to the OperationContext, instead of the callback interface itself. Doing this allows us to check the state of the connection to see if it’s still open before we use the callback.
Using the callback is relatively simple, as can be seen from the implementation of SayMessage()
.
-
The method begins by discarding any channels that are unusable, because the client’s closed the connection or because of an error.
-
For each remaining connection, the callback is obtained and the message published.
-
For clarity, exception handling isn’t shown, but in a real system you’d need to capture any exceptions thrown by the
MessagePublished()
call and handle them appropriately (logging would be a good start).
Client Implementation
Calling the service from the client follows pretty much the regular WCF style, but with the minor complication that you need to supply an object implementing the callback interface to handle the servers callbacks.
MessageReceiver
is a class implementingIChatServicesCallback
that we provide to theInstanceContext
for WCF to callback.
IIS Configuration
Configuration of IIS to host the web service is mostly simple, but has a couple of traps for the unwary or uninformed.
Within the IIS Manager, select your web site (possibly Default Web Site) and choose Edit Bindingsfrom the context menu. Check that both http and net.tcp are shown correctly.
Why do we need to include http? While the service itself will be accessed through net.tcp, we still need to support http for publishing of metadata.
Select the virtual directory for your web application, and choose Advanced Settingsfrom the Actions sidebar.
Make sure that both http and net.tcp are listed under Enabled Protocols.
Web.Config
Make sure your service behavior includes a <serviceMetadata>
element:
In my testing, it doesn’t seem to matter whether you have httpGetEnabled
turned on (true
) or off (false
), but it
does matter that you have a configuration setting at all.
Now, move on to the declaration of the service itself:
The first endpoint we need is for the service itself:
The second end point is to publish metadata about the service.
Note that we have specified a relative url for the metadata endpoint address attribute. With this endpoint, metadata
about the service will be available through http
. If you are using svcutil
to generate your service proxies, the
commandline will look something like this:
Comments
blog comments powered by Disqus