I have created a web application with a Silverlight project embedded in it, using VS 2008 SP 1, and the Silverlight 3 tools, on Vista and Windows 7.
The duplex service code:
[ServiceContract(Namespace = "cotoco", CallbackContract = typeof(IDuplexClient))]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class DuplexServer
{
private IDuplexClient _client;
private string _message;
private int _messageCounter;
private Timer _timer;
public DuplexServer()
{
}
#region IDuplexServer Members
[OperationContract(IsOneWay = true)]
public void SendEcho(string message)
{
_client = OperationContext.Current.GetCallbackChannel<IDuplexClient>();
_message = message;
_timer = new Timer();
_timer.Interval = 2000;
_timer.Enabled = true;
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
_client.ReturnEcho(string.Format("Duplex Echo {0}: {1}", _messageCounter, _message));
_messageCounter++;
if (_messageCounter > 5)
_timer.Dispose();
}
#endregion
}
[ServiceContract]
public interface IDuplexClient
{
[OperationContract(IsOneWay = true)]
void ReturnEcho(string message);
}
The duplex config section:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name=”DuplexServerBehavior”>
<serviceMetadata httpGetEnabled=”true” />
<serviceDebug includeExceptionDetailInFaults=”false” />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled=”true” />
<services>
<service behaviorConfiguration=”DuplexServerBehavior” name=”DuplexServer”>
<endpoint address=”” binding=”wsDualHttpBinding” contract=”DuplexServer” />
<endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange” />
</service>
</services>
</system.serviceModel>
I have setup a Duplex service in the client application as follows:
Binding svcBinding;
EndpointAddress svcAddress;
svcBinding = new PollingDuplexHttpBinding() { UseTextEncoding = true };
svcAddress = new EndpointAddress("http://localhost/CTC.Test.WCF.Server/DuplexServer.svc");
_duplex = new DuplexServerClient(svcBinding, svcAddress);
I have used a Simplex service in tandem with this, and calls to the Simplex service hit the breakpoints setup on the server and i can step through.
Calls to the Duplex service do not hit the breakpoints, although no error is raised on the client. If i inspect the HTTP traffic with Fiddler, i can see hundreds of 202 requests being fired after the initial request – i assume these are the polling requests.
Initial Duplex Request:
POST http://localhost/CTC.Test.WCF.Server/DuplexServer.svc HTTP/1.1
Accept: /
Content-Length: 665
Content-Type: application/soap+xml; charset=utf-8
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; (R1 1.6); SLCC1; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618)
Host: cotocovista4.cotoco.local
Connection: Keep-Alive
Pragma: no-cache
<s:Envelope xmlns:a=”http://www.w3.org/2005/08/addressing” xmlns:s=”http://www.w3.org/2003/05/soap-envelope”><s:Header><a:Action s:mustUnderstand=”1″>urn:IDuplexServer/SendEcho</a:Action><netdx:Duplex xmlns:netdx=”http://schemas.microsoft.com/2008/04/netduplex”><netdx:Address>http://docs.oasis-open.org/ws-rx/wsmc/200702/anonymous?id=ae3e3139-0df8-41eb-97db-69c2c48782b7</netdx:Address><netdx:SessionId>43f9e320-cde3-4e21-a748-e5b29c10ee25</netdx:SessionId></netdx:Duplex><a:To s:mustUnderstand=”1″>http://cotocovista4.cotoco.local/CTC.Test.WCF.Server/DuplexServer.svc</a:To></s:Header><s:Body><SendEcho><message>Message!</message></SendEcho></s:Body></s:Envelope>
Subsequent Duplex Requests:
POST http://localhost/CTC.Test.WCF.Server/DuplexServer.svc HTTP/1.1
Accept: /
Content-Length: 588
Content-Type: application/soap+xml; charset=utf-8
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; (R1 1.6); SLCC1; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618)
Host: cotocovista4.cotoco.local
Connection: Keep-Alive
Pragma: no-cache
<s:Envelope xmlns:a=”http://www.w3.org/2005/08/addressing” xmlns:s=”http://www.w3.org/2003/05/soap-envelope”><s:Header><a:Action s:mustUnderstand=”1″>http://docs.oasis-open.org/ws-rx/wsmc/200702/MakeConnection</a:Action><a:To s:mustUnderstand=”1″>http://cotocovista4.cotoco.local/CTC.Test.WCF.Server/DuplexServer.svc</a:To></s:Header><s:Body><wsmc:MakeConnection xmlns:wsmc=”http://docs.oasis-open.org/ws-rx/wsmc/200702″><wsmc:Address>http://docs.oasis-open.org/ws-rx/wsmc/200702/anonymous?id=ae3e3139-0df8-41eb-97db-69c2c48782b7</wsmc:Address></wsmc:MakeConnection></s:Body></s:Envelope>
Does anyone know why this would happen, i thought I’d finally sussed the last problem when it stopped throwing connection exceptions….
Regards
Tris
Update: I have tried recreating this in the following project types: WCF Application, Web Application, Web Project. I have succeeded in implementing the MS Example that uses WCF Message’s for the Duplex parameters without problem, but i was looking for a rapid way of assembling duplex web services using WSDL.
So – i managed to finally get it working using the following web config section, and adjusting the client side accordingly:
If anyone can explain why this worked, but using wsDualHttpBinding did not, that would be really helpful. 🙂
(Also – why is that displayed in a code block? :/ )
Regards
Tristan