<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Paul Mrozowski's Blog - WCF</title>
    <link>http://www.rcs-solutions.com/blog/</link>
    <description>A day in the life (of a developer)</description>
    <language>en-us</language>
    <copyright>Paul Mrozowski / RCS Solutions, Inc.</copyright>
    <lastBuildDate>Thu, 06 Nov 2008 02:35:49 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>paulm@rcs-solutions.com</managingEditor>
    <webMaster>paulm@rcs-solutions.com</webMaster>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=104bb1f4-147b-4c34-8685-67b82482b6cc</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,104bb1f4-147b-4c34-8685-67b82482b6cc.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,104bb1f4-147b-4c34-8685-67b82482b6cc.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=104bb1f4-147b-4c34-8685-67b82482b6cc</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <style type="text/css">
.code { background-color: #efefef; font-family:consolas,courier new; }
</style>
        <p>
I'm working on an application which is going to use WCF heavily for communications
between a client side application and a server-based service application. One aspect
of the application that I've been ignoring during testing was WCF authentication.
During testing the application has been running on my local network. I had enabled
connection based authentication (ex.SSL) and it is using TCP as it's binding since
I do a lot of callback messaging. In the back of my mind I realized that when it's
deployed the client will be on a different network, communicating over the internet,
so there may be some issues with the current security model. 
</p>
        <p>
A week ago I finally got around to looking at it and it completely breaks when the
client isn't local, since it was using Windows authentication to do it's authentication.
Microsoft has a nice manual which walks through the various ways of configuring security
in WCF, which you should choose (and why) under various scenarios. <a href="http://msdn.microsoft.com/en-us/library/aa480545.aspx " target="_blank">Scenarios,
Patterns, and Implementation Guidance for Web Services Enhancements</a> (WSE) 3.0
from their patterns &amp; practices team. Based on a number of factors, it suggested
I use SSL along with message based security. I'm not going to be hosting this in IIS,
so HTTPS wasn't an option for the SSL connection. I also wasn't using Windows authentication
and didn't want to deal with some of the issues of the other credential types (IssuedToken,
Digest, etc.). So I decided on UserName. 
</p>
        <p>
I now had two things to fix - first, I needed to implement my own UserName authentication
scheme (again, I like making my life hard so I wasn't using the default authentication
provider in ASP.NET that used SQL Server). This turns out to be pretty simple by inheriting
from the UserNamePasswordValidator class in the System.IndentityMode.Selectors namespace
and overriding the Validate method: 
</p>
        <p>
          <span style="color: blue">using</span> System;<br /><span style="color: blue">using</span> System.Collections.Generic;<br /><span style="color: blue">using</span> System.IdentityModel.Selectors;<br /><span style="color: blue">using</span> System.IdentityModel.Tokens;<br /><span style="color: blue">using</span> System.Linq;<br /><span style="color: blue">using</span> System.Text; 
</p>
        <div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new">
          <p style="margin: 0px">
            <span style="color: blue">namespace</span> MySampleApp.Server
</p>
          <p style="margin: 0px">
{
</p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;summary&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> This
class is responsible for validating the username/password</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> used
by the connecting WCF client.</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;/summary&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;remarks&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;para&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> The
server is configured to use this class in the Service Behavior</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> serviceCredentials
section of the config file. </span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> CustomUserNamePasswordValidatorType
is set to SampleValidator</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> UseNamePasswordValidationMode
is set to Custom</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;/para&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;/remarks&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;developer&gt;</span><span style="background: #ffffbf">Paul
Mrozowski</span><span style="color: gray">&lt;/developer&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;created&gt;</span><span style="background: #ffffbf">10/13/2008</span><span style="color: gray">&lt;/created&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: blue">public</span><span style="color: blue">class</span><span style="color: #2b91af">SampleValidator</span> : <span style="color: #2b91af">UserNamePasswordValidator</span></p>
          <p style="margin: 0px">
    {
</p>
          <p style="margin: 0px">
        <span style="color: blue">public</span><span style="color: blue">override</span><span style="color: blue">void</span> Validate(<span style="color: blue">string</span> userName, <span style="color: blue">string</span> password)
</p>
          <p style="margin: 0px">
        {
</p>
          <p style="margin: 0px">
            <span style="background: #ffffbf">//
TODO: Finish, this is just here to test out the idea.</span></p>
          <p style="margin: 0px">
            <span style="color: blue">if</span> (userName
!= <span style="background: #e5e5e5">"user"</span> || password != <span style="background: #e5e5e5">"pass"</span>)
</p>
          <p style="margin: 0px">
                <span style="color: blue">throw</span><span style="color: blue">new</span><span style="color: #2b91af">SecurityTokenException</span>(<span style="background: #e5e5e5">"Unknown
user."</span>);
</p>
          <p style="margin: 0px">
        }
</p>
          <p style="margin: 0px">
    }
</p>
          <p style="margin: 0px">
}
</p>
        </div>
        <p>
 
</p>
        <p>
If the passed in username/password is invalid, throw an exception. Easy. I added this
new class to my server project, then modified the app.config file to let WCF know
to use this for authentication. 
</p>
        <pre class="code">&lt;bindings&gt;
      &lt;nettcpbinding&gt;
          &lt;binding name="StandardServerBinding" maxbuffersize="8192000" 
              maxreceivedmessagesize="8192000" listenbacklog="5000" maxconnections="1000"&gt; 
              &lt;readerquotas maxdepth="24" maxstringcontentlength="8192000" maxarraylength="8192000" 
               maxbytesperread="8192000" maxnametablecharcount="8192000" /&gt;
              &lt;reliablesession inactivitytimeout="01:00:00" /&gt;
              &lt;security mode="Message"&gt;                  
                  &lt;message clientcredentialtype="UserName" /&gt;
              &lt;/security&gt;
          &lt;/binding&gt;
      &lt;/nettcpbinding&gt;
  &lt;/bindings&gt;
        &lt;behaviors&gt;
            &lt;servicebehaviors&gt;
                &lt;behavior name="RegisterBehavior"&gt;					
                    &lt;servicedebug includeexceptiondetailinfaults="true" /&gt;
                    &lt;servicemetadata /&gt;
                    &lt;servicethrottling maxconcurrentcalls="48" maxconcurrentsessions="5000" 
                      maxconcurrentinstances="5000" /&gt;
                    &lt;servicecredentials&gt;
                        &lt;usernameauthentication usernamepasswordvalidationmode="Custom" 
          customusernamepasswordvalidatortype="MySampleApp.Server.SampleValidator,MySampleApp.Server" 
                          cachelogontokens="true" cachedlogontokenlifetime="01:00:00" /&gt;
                    &lt;/servicecredentials&gt;					
                &lt;/behavior&gt;
                &lt;behavior name="ThrottlingBehavior"&gt;
                    &lt;servicethrottling maxconcurrentcalls="48" maxconcurrentsessions="5000" 
                        maxconcurrentinstances="5000" /&gt;
                &lt;/behavior&gt;
            &lt;/servicebehaviors&gt;
        &lt;/behaviors&gt;		
        &lt;services&gt;
            &lt;service name="MySampleApp.ServerProcess" behaviorconfiguration="RegisterBehavior"&gt;
                &lt;endpoint name="PrimaryEndpoint" contract="MySampleApp.Server.Contracts.IServer" 
                   binding="netTcpBinding" address="net.tcp://localhost" 
                   bindingconfiguration="StandardServerBinding" /&gt;
                &lt;endpoint name="MEXEndpoint" contract="IMetadataExchange" 
                   binding="mexHttpBinding" address="http://localhost/MEX/" bindingconfiguration="" /&gt;
            &lt;/service&gt;
        &lt;/services&gt;
</pre>
        <p>
You add a &lt;serviceCreditials\userNameAuthentication section to the ServiceBehavior
and specify a Custom userNamePasswodValidationMode. I tell it to use the full name
of the class, the second part of that after the comma tells it which assembly it's
located in. In the netTcpBinding you can see that I've enabled security on the message,
and told it to use the UserName authentication type.
</p>
        <pre class="code">        &lt;bindings&gt;
            &lt;netTcpBinding&gt;
                &lt;binding name="NewBinding0" maxBufferSize="8192000" maxReceivedMessageSize="8192000"&gt;
                    &lt;readerQuotas maxDepth="24" maxStringContentLength="8192000"
                        maxArrayLength="8192000" maxBytesPerRead="8192000" maxNameTableCharCount="8192000" /&gt;
                    &lt;reliableSession inactivityTimeout="01:00:00" /&gt;
                    &lt;security mode="Message"&gt;
                        &lt;transport clientCredentialType="None" protectionLevel="None" /&gt;
                        &lt;message clientCredentialType="UserName" /&gt;
                    &lt;/security&gt;
                &lt;/binding&gt;
            &lt;/netTcpBinding&gt;
</pre>
        <p>
I've set the security mode to Message and clientCredentialType to UserName as well.
Now I needed to somehow get my client application to pass the user name and password.
I had used Visual Studio and let it build my client proxy, so I thought I'd be able
to set this immediately after I created the proxy, ex: 
</p>
        <div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new">
          <p style="margin: 0px">
            <span style="color: #2b91af">InstanceContext</span> context = <span style="color: blue">new</span><span style="color: #2b91af">InstanceContext</span>(<span style="color: blue">this</span>);
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
            <span style="color: blue">this</span>.m_client = <span style="color: blue">new</span><span style="color: #2b91af">ServerClient</span>(context);
</p>
          <p style="margin: 0px">
            <span style="color: blue">this</span>.m_client.ClientCredentials.UserName.UserName
= <span style="background: #e5e5e5">"user"</span>;
</p>
          <p style="margin: 0px">
            <span style="color: blue">this</span>.m_client.ClientCredentials.UserName.Password
= <span style="background: #e5e5e5">"pass"</span>;
</p>
        </div>
        <p>
Unfortunately, that doesn't work - I was getting "Object is read only" when I attempted
to do this. From some searching I was able to find out that this can occur when the
connection has already been opened, but in my case I hadn't done that yet. I spent
a bunch of time trying to figure out why it wouldn't work and finally ended up putting
the code inside of the proxy class VS had generated by editing the constructor and
setting things up there. 
</p>
        <div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new">
          <p style="margin: 0px">
            <span style="color: blue">public</span> ServerClient(System.ServiceModel.<span style="color: #2b91af">InstanceContext</span> callbackInstance)
: 
</p>
          <p style="margin: 0px">
        <span style="color: blue">base</span>(callbackInstance)
</p>
          <p style="margin: 0px">
{        
</p>
          <p style="margin: 0px">
    <span style="color: blue">base</span>.ClientCredentials.UserName.UserName
= <span style="background: #e5e5e5">"user"</span>;
</p>
          <p style="margin: 0px">
    <span style="color: blue">base</span>.ClientCredentials.UserName.Password
= <span style="background: #e5e5e5">"pass"</span>;       
</p>
          <p style="margin: 0px">
}
</p>
        </div>
        <p>
At this point, I thought I was all set to go. I fired things up and it immediately
faulted the connection. I opened up the WCF Service Configuration Editor (C:\Program
Files\Microsoft SDKs\Windows\v6.0A\bin\svcconfigeditor.exe) and enabled tracing on
both the server and client and re-ran things so I could capture a trace. Once that
was done I opened up the WCF Svc Trace Log Viewer (which is part of the Windows SDK,
mine is located at: C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SvcTraceViewer.exe).
After looking through the log, it appeared to be failing with a "The security protocol
cannot secure the outgoing message" error. 
</p>
        <p>
Again, I did a bunch of searching, reading, and testing and finally realized that
it wanted to encrypt the connection but couldn't. I mentioned earlier that I decided
to use SSL for the connection, but when I was working on this I didn't realize that
it didn't magically decide how to do that. It looked like I could use an X509 certificate
to enable encryption, but I wasn't at all thrilled with the prospect of trying to
get that cert. install on client machines. From the couple of times I've seen it needed,
it never seems to run particularly smoothly (when it works, it just works, but when
it fails, you have no idea why it's failing). So I essentially wanted to be able to
load my cert. at runtime instead of loading it into the Windows cert. store. I could
buy a real cert., but for this app. it just wasn't necessary. VS includes some tools
for self-signing certificates so I looked into that instead. 
</p>
        <p>
If you open a Visual Studio command prompt (hiding in the Visual Studio Tools subdirectory
of Visual Studio on the Start menu), it sets up the pathing so you can use the various
command line tools. The first thing I needed to do was create a key for the server: 
</p>
        <pre class="code">makecert -r -pe -n "CN=RCS Solutions, Inc." -b 01/01/2008 -e 12/31/2099 -sky exchange </pre>
Where:<br />
Server.cer -sv Server.pvk Server.cer - the certificate (public key) 
<br />
Server.pvk - the private key 
<p>
When it runs, it prompts for a password used to encrypt the private key. You can leave
it blank, but it's suggested you fill it in (so I did). 
</p><p>
Next I decided to merge the public and private key into a single file with a PFX extension.
It requires you to re-enter the password you used to encrypt the private key (or pass
in in the command line, which is what I did). 
</p><pre class="code">pvk2pfx.exe -pvk Server.pvk -spc Server.cer -pfx Server.pfx -pi mycertpassword</pre><p>
At this point I added all three files to my project. I also needed to get my proxy
to use this cert. Since it's not a real certificate (meaning there isn't a chain of
trust established between my cert at some known/trusted provider) I had to disable
certificate validation. Yeah, pretty secure stuff ;-) 
<g></g></p><div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"><p style="margin: 0px"><span style="color: #2b91af">          
ServiceHost</span> host = <span style="color: blue">null</span>;
</p><p style="margin: 0px">
           <span style="color: blue">try</span></p><p style="margin: 0px">
           {
</p><p style="margin: 0px">
               <span style="background: #ffffbf">//
Specifically not calling Dispose() on host since it also calls Close and if we've</span></p><p style="margin: 0px">
               <span style="background: #ffffbf">//
disposed after calling Close that will cause errors.</span></p><p style="margin: 0px">
              
host = <span style="color: blue">new</span><span style="color: #2b91af">ServiceHost</span>(<span style="color: blue">typeof</span>(<span style="color: #2b91af">ServerProcess</span>));
</p><p style="margin: 0px">
 
</p><p style="margin: 0px">
               <span style="color: blue">string</span> dir
= System.IO.<span style="color: #2b91af">Directory</span>.GetCurrentDirectory();
</p><p style="margin: 0px">
 
</p><p style="margin: 0px">
               <span style="color: #2b91af">X509Certificate2</span> cert
= <span style="color: blue">new</span><span style="color: #2b91af">X509Certificate2</span>(dir
+ <span style="background: #e5e5e5">"\\Server.pfx"</span>, <span style="color: #a31515">@"mycertpassword"</span>);
</p><p style="margin: 0px">
              
host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.<span style="color: #2b91af">X509CertificateValidationMode</span>.None;                                
</p><p style="margin: 0px">
              
host.Credentials.ServiceCertificate.Certificate = cert;
</p><p style="margin: 0px">
 
</p><p style="margin: 0px">
              
host.Open();
</p></div><p>
 
</p><p>
I repeated the above sequence for my client, creating it's own public/private key.
I added the same code to configure the cert, except I put it in the pre-generated
proxy constructor. 
</p><div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"><p style="margin: 0px"><span style="color: blue">public</span> ServerClient(System.ServiceModel.<span style="color: #2b91af">InstanceContext</span> callbackInstance)
: 
</p><p style="margin: 0px">
        <span style="color: blue">base</span>(callbackInstance)
</p><p style="margin: 0px">
{        
</p><p style="margin: 0px">
    <span style="color: blue">base</span>.ClientCredentials.UserName.UserName
= <span style="background: #e5e5e5">"1"</span>;
</p><p style="margin: 0px">
    <span style="color: blue">base</span>.ClientCredentials.UserName.Password
= <span style="background: #e5e5e5">"2"</span>;
</p><p style="margin: 0px">
 
</p><p style="margin: 0px">
    <span style="background: #ffffbf">// TODO: Fill in with correct
credentials</span></p><p style="margin: 0px">
 
</p><p style="margin: 0px">
    <span style="color: blue">string</span> dir = System.IO.<span style="color: #2b91af">Directory</span>.GetCurrentDirectory();
</p><p style="margin: 0px">
    <span style="color: #2b91af">X509Certificate2</span> cert = <span style="color: blue">new</span><span style="color: #2b91af">X509Certificate2</span>(dir
+ <span style="background: #e5e5e5">"\\Client.pfx"</span>, <span style="color: #a31515">@"mycertpassword"</span>);
</p><p style="margin: 0px">
    <span style="color: blue">base</span>.ClientCredentials.ClientCertificate.Certificate
= cert;        
</p><p style="margin: 0px">
    <span style="color: blue">base</span>.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode
= System.ServiceModel.Security.<span style="color: #2b91af">X509CertificateValidationMode</span>.None;          
</p><p style="margin: 0px">
 
</p><p style="margin: 0px">
}
</p></div><p>
 
</p><p>
I thought I was good to go, so I started everything back up. It failed with the same
error as before. Yet more searching revealed that I needed to include a copy of the
server's certificate inside of the client's app.config (I have no idea why, it seems
like it should happen automatically as part of it's public key exchange). The problem
was getting it in the format it required. I tried a few of the various ways that were
suggested, but didn't have much luck with them. I finally regenerated the client side
proxy using the svcutil command line app. and pointing it to a MEX (Metadata EXchange)
endpoint and it magically created the certificate value I needed. I cut and pasted
that code into my production proxy. 
</p><pre class="code">       &lt;client&gt;
            &lt;endpoint address="net.tcp://localhost/" binding="netTcpBinding"
                bindingConfiguration="PrimaryEndpoint" contract="Server" name="PrimaryEndpoint"&gt;
                &lt;identity&gt;
			&lt;certificate encodedValue="AwAAAA(long value removed)" /&gt;                    
                &lt;/identity&gt;
            &lt;/endpoint&gt;
</pre><p>
When I restarted everything it was finally able to open a connection. I still need
to figure out how to get my WCF service and IIS to share the same port, but I'm making
some progress at least. 
</p><img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=104bb1f4-147b-4c34-8685-67b82482b6cc" /></body>
      <title>Custom Authentication and Encryption with WCF</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,104bb1f4-147b-4c34-8685-67b82482b6cc.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2008/11/06/CustomAuthenticationAndEncryptionWithWCF.aspx</link>
      <pubDate>Thu, 06 Nov 2008 02:35:49 GMT</pubDate>
      <description> &lt;style type="text/css"&gt;
.code { background-color: #efefef; font-family:consolas,courier new; }
&lt;/style&gt;
&lt;p&gt;
I'm working on an application which is going to use WCF heavily for communications
between a client side application and a server-based service application. One aspect
of the application that I've been ignoring during testing was WCF authentication.
During testing the application has been running on my local network. I had enabled
connection based authentication (ex.SSL) and it is using TCP as it's binding since
I do a lot of callback messaging. In the back of my mind I realized that when it's
deployed the client will be on a different network, communicating over the internet,
so there may be some issues with the current security model. 
&lt;/p&gt;
&lt;p&gt;
A week ago I finally got around to looking at it and it completely breaks when the
client isn't local, since it was using Windows authentication to do it's authentication.
Microsoft has a nice manual which walks through the various ways of configuring security
in WCF, which you should choose (and why) under various scenarios. &lt;a href="http://msdn.microsoft.com/en-us/library/aa480545.aspx " target="_blank"&gt;Scenarios,
Patterns, and Implementation Guidance for Web Services Enhancements&lt;/a&gt; (WSE) 3.0
from their patterns &amp;amp; practices team. Based on a number of factors, it suggested
I use SSL along with message based security. I'm not going to be hosting this in IIS,
so HTTPS wasn't an option for the SSL connection. I also wasn't using Windows authentication
and didn't want to deal with some of the issues of the other credential types (IssuedToken,
Digest, etc.). So I decided on UserName. 
&lt;/p&gt;
&lt;p&gt;
I now had two things to fix - first, I needed to implement my own UserName authentication
scheme (again, I like making my life hard so I wasn't using the default authentication
provider in ASP.NET that used SQL Server). This turns out to be pretty simple by inheriting
from the UserNamePasswordValidator class in the System.IndentityMode.Selectors namespace
and overriding the Validate method: 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br&gt;
&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br&gt;
&lt;span style="color: blue"&gt;using&lt;/span&gt; System.IdentityModel.Selectors;&lt;br&gt;
&lt;span style="color: blue"&gt;using&lt;/span&gt; System.IdentityModel.Tokens;&lt;br&gt;
&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Linq;&lt;br&gt;
&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Text; 
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;namespace&lt;/span&gt; MySampleApp.Server
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; This
class is responsible for validating the username/password&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; used
by the connecting WCF client.&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;para&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; The
server is configured to use this class in the Service Behavior&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; serviceCredentials
section of the config file. &lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; CustomUserNamePasswordValidatorType
is set to SampleValidator&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; UseNamePasswordValidationMode
is set to Custom&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/para&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;developer&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;Paul
Mrozowski&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/developer&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;created&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;10/13/2008&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/created&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SampleValidator&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;UserNamePasswordValidator&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Validate(&lt;span style="color: blue"&gt;string&lt;/span&gt; userName, &lt;span style="color: blue"&gt;string&lt;/span&gt; password)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
TODO: Finish, this is just here to test out the idea.&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (userName
!= &lt;span style="background: #e5e5e5"&gt;"user"&lt;/span&gt; || password != &lt;span style="background: #e5e5e5"&gt;"pass"&lt;/span&gt;)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SecurityTokenException&lt;/span&gt;(&lt;span style="background: #e5e5e5"&gt;"Unknown
user."&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
If the passed in username/password is invalid, throw an exception. Easy. I added this
new class to my server project, then modified the app.config file to let WCF know
to use this for authentication. 
&lt;/p&gt;
&lt;pre class="code"&gt;&amp;lt;bindings&amp;gt;
      &amp;lt;nettcpbinding&amp;gt;
          &amp;lt;binding name="StandardServerBinding" maxbuffersize="8192000" 
              maxreceivedmessagesize="8192000" listenbacklog="5000" maxconnections="1000"&amp;gt; 
              &amp;lt;readerquotas maxdepth="24" maxstringcontentlength="8192000" maxarraylength="8192000" 
               maxbytesperread="8192000" maxnametablecharcount="8192000" /&amp;gt;
              &amp;lt;reliablesession inactivitytimeout="01:00:00" /&amp;gt;
              &amp;lt;security mode="Message"&amp;gt;                  
                  &amp;lt;message clientcredentialtype="UserName" /&amp;gt;
              &amp;lt;/security&amp;gt;
          &amp;lt;/binding&amp;gt;
      &amp;lt;/nettcpbinding&amp;gt;
  &amp;lt;/bindings&amp;gt;
        &amp;lt;behaviors&amp;gt;
            &amp;lt;servicebehaviors&amp;gt;
                &amp;lt;behavior name="RegisterBehavior"&amp;gt;					
                    &amp;lt;servicedebug includeexceptiondetailinfaults="true" /&amp;gt;
                    &amp;lt;servicemetadata /&amp;gt;
                    &amp;lt;servicethrottling maxconcurrentcalls="48" maxconcurrentsessions="5000" 
                      maxconcurrentinstances="5000" /&amp;gt;
                    &amp;lt;servicecredentials&amp;gt;
                        &amp;lt;usernameauthentication usernamepasswordvalidationmode="Custom" 
          customusernamepasswordvalidatortype="MySampleApp.Server.SampleValidator,MySampleApp.Server" 
                          cachelogontokens="true" cachedlogontokenlifetime="01:00:00" /&amp;gt;
                    &amp;lt;/servicecredentials&amp;gt;					
                &amp;lt;/behavior&amp;gt;
                &amp;lt;behavior name="ThrottlingBehavior"&amp;gt;
                    &amp;lt;servicethrottling maxconcurrentcalls="48" maxconcurrentsessions="5000" 
                        maxconcurrentinstances="5000" /&amp;gt;
                &amp;lt;/behavior&amp;gt;
            &amp;lt;/servicebehaviors&amp;gt;
        &amp;lt;/behaviors&amp;gt;		
        &amp;lt;services&amp;gt;
            &amp;lt;service name="MySampleApp.ServerProcess" behaviorconfiguration="RegisterBehavior"&amp;gt;
                &amp;lt;endpoint name="PrimaryEndpoint" contract="MySampleApp.Server.Contracts.IServer" 
                   binding="netTcpBinding" address="net.tcp://localhost" 
                   bindingconfiguration="StandardServerBinding" /&amp;gt;
                &amp;lt;endpoint name="MEXEndpoint" contract="IMetadataExchange" 
                   binding="mexHttpBinding" address="http://localhost/MEX/" bindingconfiguration="" /&amp;gt;
            &amp;lt;/service&amp;gt;
        &amp;lt;/services&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
You add a &amp;lt;serviceCreditials\userNameAuthentication section to the ServiceBehavior
and specify a Custom userNamePasswodValidationMode. I tell it to use the full name
of the class, the second part of that after the comma tells it which assembly it's
located in. In the netTcpBinding you can see that I've enabled security on the message,
and told it to use the UserName authentication type.
&lt;/p&gt;
&lt;pre class="code"&gt;        &amp;lt;bindings&amp;gt;
            &amp;lt;netTcpBinding&amp;gt;
                &amp;lt;binding name="NewBinding0" maxBufferSize="8192000" maxReceivedMessageSize="8192000"&amp;gt;
                    &amp;lt;readerQuotas maxDepth="24" maxStringContentLength="8192000"
                        maxArrayLength="8192000" maxBytesPerRead="8192000" maxNameTableCharCount="8192000" /&amp;gt;
                    &amp;lt;reliableSession inactivityTimeout="01:00:00" /&amp;gt;
                    &amp;lt;security mode="Message"&amp;gt;
                        &amp;lt;transport clientCredentialType="None" protectionLevel="None" /&amp;gt;
                        &amp;lt;message clientCredentialType="UserName" /&amp;gt;
                    &amp;lt;/security&amp;gt;
                &amp;lt;/binding&amp;gt;
            &amp;lt;/netTcpBinding&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
I've set the security mode to Message and clientCredentialType to UserName as well.
Now I needed to somehow get my client application to pass the user name and password.
I had used Visual Studio and let it build my client proxy, so I thought I'd be able
to set this immediately after I created the proxy, ex: 
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;InstanceContext&lt;/span&gt; context = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;InstanceContext&lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;this&lt;/span&gt;.m_client = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ServerClient&lt;/span&gt;(context);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;this&lt;/span&gt;.m_client.ClientCredentials.UserName.UserName
= &lt;span style="background: #e5e5e5"&gt;"user"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;this&lt;/span&gt;.m_client.ClientCredentials.UserName.Password
= &lt;span style="background: #e5e5e5"&gt;"pass"&lt;/span&gt;;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
Unfortunately, that doesn't work - I was getting "Object is read only" when I attempted
to do this. From some searching I was able to find out that this can occur when the
connection has already been opened, but in my case I hadn't done that yet. I spent
a bunch of time trying to figure out why it wouldn't work and finally ended up putting
the code inside of the proxy class VS had generated by editing the constructor and
setting things up there. 
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;public&lt;/span&gt; ServerClient(System.ServiceModel.&lt;span style="color: #2b91af"&gt;InstanceContext&lt;/span&gt; callbackInstance)
: 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;base&lt;/span&gt;(callbackInstance)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;base&lt;/span&gt;.ClientCredentials.UserName.UserName
= &lt;span style="background: #e5e5e5"&gt;"user"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;base&lt;/span&gt;.ClientCredentials.UserName.Password
= &lt;span style="background: #e5e5e5"&gt;"pass"&lt;/span&gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
At this point, I thought I was all set to go. I fired things up and it immediately
faulted the connection. I opened up the WCF Service Configuration Editor (C:\Program
Files\Microsoft SDKs\Windows\v6.0A\bin\svcconfigeditor.exe) and enabled tracing on
both the server and client and re-ran things so I could capture a trace. Once that
was done I opened up the WCF Svc Trace Log Viewer (which is part of the Windows SDK,
mine is located at: C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SvcTraceViewer.exe).
After looking through the log, it appeared to be failing with a "The security protocol
cannot secure the outgoing message" error. 
&lt;/p&gt;
&lt;p&gt;
Again, I did a bunch of searching, reading, and testing and finally realized that
it wanted to encrypt the connection but couldn't. I mentioned earlier that I decided
to use SSL for the connection, but when I was working on this I didn't realize that
it didn't magically decide how to do that. It looked like I could use an X509 certificate
to enable encryption, but I wasn't at all thrilled with the prospect of trying to
get that cert. install on client machines. From the couple of times I've seen it needed,
it never seems to run particularly smoothly (when it works, it just works, but when
it fails, you have no idea why it's failing). So I essentially wanted to be able to
load my cert. at runtime instead of loading it into the Windows cert. store. I could
buy a real cert., but for this app. it just wasn't necessary. VS includes some tools
for self-signing certificates so I looked into that instead. 
&lt;/p&gt;
&lt;p&gt;
If you open a Visual Studio command prompt (hiding in the Visual Studio Tools subdirectory
of Visual Studio on the Start menu), it sets up the pathing so you can use the various
command line tools. The first thing I needed to do was create a key for the server: 
&lt;/p&gt;
&lt;pre class="code"&gt;makecert -r -pe -n "CN=RCS Solutions, Inc." -b 01/01/2008 -e 12/31/2099 -sky exchange &lt;/pre&gt;
Where:&lt;br&gt;
Server.cer -sv Server.pvk Server.cer - the certificate (public key) 
&lt;br&gt;
Server.pvk - the private key 
&lt;p&gt;
When it runs, it prompts for a password used to encrypt the private key. You can leave
it blank, but it's suggested you fill it in (so I did). 
&lt;/p&gt;
&lt;p&gt;
Next I decided to merge the public and private key into a single file with a PFX extension.
It requires you to re-enter the password you used to encrypt the private key (or pass
in in the command line, which is what I did). 
&lt;/p&gt;
&lt;pre class="code"&gt;pvk2pfx.exe -pvk Server.pvk -spc Server.cer -pfx Server.pfx -pi mycertpassword&lt;/pre&gt;
&lt;p&gt;
At this point I added all three files to my project. I also needed to get my proxy
to use this cert. Since it's not a real certificate (meaning there isn't a chain of
trust established between my cert at some known/trusted provider) I had to disable
certificate validation. Yeah, pretty secure stuff ;-) 
&lt;g&gt;
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ServiceHost&lt;/span&gt; host = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;try&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
Specifically not calling Dispose() on host since it also calls Close and if we've&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
disposed after calling Close that will cause errors.&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
host = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ServiceHost&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ServerProcess&lt;/span&gt;));
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; dir
= System.IO.&lt;span style="color: #2b91af"&gt;Directory&lt;/span&gt;.GetCurrentDirectory();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;X509Certificate2&lt;/span&gt; cert
= &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;X509Certificate2&lt;/span&gt;(dir
+ &lt;span style="background: #e5e5e5"&gt;"\\Server.pfx"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;@"mycertpassword"&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.&lt;span style="color: #2b91af"&gt;X509CertificateValidationMode&lt;/span&gt;.None;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
host.Credentials.ServiceCertificate.Certificate = cert;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
host.Open();
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
I repeated the above sequence for my client, creating it's own public/private key.
I added the same code to configure the cert, except I put it in the pre-generated
proxy constructor. 
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;public&lt;/span&gt; ServerClient(System.ServiceModel.&lt;span style="color: #2b91af"&gt;InstanceContext&lt;/span&gt; callbackInstance)
: 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;base&lt;/span&gt;(callbackInstance)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;base&lt;/span&gt;.ClientCredentials.UserName.UserName
= &lt;span style="background: #e5e5e5"&gt;"1"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;base&lt;/span&gt;.ClientCredentials.UserName.Password
= &lt;span style="background: #e5e5e5"&gt;"2"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;// TODO: Fill in with correct
credentials&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; dir = System.IO.&lt;span style="color: #2b91af"&gt;Directory&lt;/span&gt;.GetCurrentDirectory();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;X509Certificate2&lt;/span&gt; cert = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;X509Certificate2&lt;/span&gt;(dir
+ &lt;span style="background: #e5e5e5"&gt;"\\Client.pfx"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;@"mycertpassword"&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;base&lt;/span&gt;.ClientCredentials.ClientCertificate.Certificate
= cert;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;base&lt;/span&gt;.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode
= System.ServiceModel.Security.&lt;span style="color: #2b91af"&gt;X509CertificateValidationMode&lt;/span&gt;.None;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
I thought I was good to go, so I started everything back up. It failed with the same
error as before. Yet more searching revealed that I needed to include a copy of the
server's certificate inside of the client's app.config (I have no idea why, it seems
like it should happen automatically as part of it's public key exchange). The problem
was getting it in the format it required. I tried a few of the various ways that were
suggested, but didn't have much luck with them. I finally regenerated the client side
proxy using the svcutil command line app. and pointing it to a MEX (Metadata EXchange)
endpoint and it magically created the certificate value I needed. I cut and pasted
that code into my production proxy. 
&lt;/p&gt;
&lt;pre class="code"&gt;       &amp;lt;client&amp;gt;
            &amp;lt;endpoint address="net.tcp://localhost/" binding="netTcpBinding"
                bindingConfiguration="PrimaryEndpoint" contract="Server" name="PrimaryEndpoint"&amp;gt;
                &amp;lt;identity&amp;gt;
			&amp;lt;certificate encodedValue="AwAAAA(long value removed)" /&amp;gt;                    
                &amp;lt;/identity&amp;gt;
            &amp;lt;/endpoint&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
When I restarted everything it was finally able to open a connection. I still need
to figure out how to get my WCF service and IIS to share the same port, but I'm making
some progress at least. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=104bb1f4-147b-4c34-8685-67b82482b6cc" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,104bb1f4-147b-4c34-8685-67b82482b6cc.aspx</comments>
      <category>WCF</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=d088853d-a3e6-4e33-8446-ac6d2dfc9c70</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,d088853d-a3e6-4e33-8446-ac6d2dfc9c70.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,d088853d-a3e6-4e33-8446-ac6d2dfc9c70.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d088853d-a3e6-4e33-8446-ac6d2dfc9c70</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I received a question regarding <a href="http://www.rcs-solutions.com/blog/2008/07/06/WCFNotificationOnDisconnect.aspx">this
post</a> on WCF and what my handlers look like when a client disconnects (either because
of a fault or the client connection is closed). It's fairly simple. Here's the code
used to hook up the events: 
</p>
        <div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new">
          <p style="margin: 0px">
            <span style="color: #2b91af">IClientCallback</span> remoteMachine = <span style="color: #2b91af">OperationContext</span>.Current.GetCallbackChannel&lt;<span style="color: #2b91af">IClientCallback</span>&gt;();
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">OperationContext</span>.Current.Channel.Faulted += <span style="color: blue">new</span><span style="color: #2b91af">EventHandler</span>(ClientFaulted);
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">OperationContext</span>.Current.Channel.Closed += <span style="color: blue">new</span><span style="color: #2b91af">EventHandler</span>(ClientClosed);
</p>
        </div>
        <p>
 
</p>
        <p>
As a side note, I haven't quite gotten in the habit of using the new/shortened syntax
for hooking up delegates. The code above can actually now be written as: 
</p>
        <div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new">
          <p style="margin: 0px">
            <span style="color: #2b91af">IClientCallback</span> remoteMachine = <span style="color: #2b91af">OperationContext</span>.Current.GetCallbackChannel&lt;<span style="color: #2b91af">IClientCallback</span>&gt;();
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">OperationContext</span>.Current.Channel.Faulted += ClientFaulted;
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">OperationContext</span>.Current.Channel.Closed += ClientClosed;
</p>
        </div>
        <p>
 
</p>
        <p>
At any rate, the code in both handlers is actually the same, so I'll just show ClientClosed: 
</p>
        <div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new">
          <p style="margin: 0px">
            <span style="color: gray">///</span>
            <span style="background: #ffffbf">
            </span>
            <span style="color: gray">&lt;summary&gt;</span>
          </p>
          <p style="margin: 0px">
 <span style="color: gray">///</span><span style="background: #ffffbf"> Called
whenever a client machine's connection is closed.</span></p>
          <p style="margin: 0px">
 <span style="color: gray">///</span><span style="background: #ffffbf"> Automatically
removes them from our internal list of clients.</span></p>
          <p style="margin: 0px">
 <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;/summary&gt;</span></p>
          <p style="margin: 0px">
 <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;param
name="sender"&gt;&lt;/param&gt;</span></p>
          <p style="margin: 0px">
 <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;param
name="e"&gt;&lt;/param&gt;</span></p>
          <p style="margin: 0px">
 <span style="color: blue">void</span> ClientClosed(<span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)
</p>
          <p style="margin: 0px">
{
</p>
          <p style="margin: 0px">
    <span style="color: #2b91af">IClientCallback</span> remoteMachine
= sender <span style="color: blue">as</span><span style="color: #2b91af">IClientCallback</span>;
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
    <span style="color: blue">this</span>.RemoveClientMachine(remoteMachine);            
</p>
          <p style="margin: 0px">
}
</p>
        </div>
        <p>
 
</p>
        <p>
All it does is cast the sender to the IClientCallback interface and call another method
which actually removes it from my internal list. Here's what that code is doing (actually,
I send out another notification in the real code to any other clients to let them
know something has changed). It just locks the list then uses a lambda to find the
client in the list, and if it's found, it's removed. 
</p>
        <div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new">
          <p style="margin: 0px">
            <span style="color: blue">private</span>
            <span style="color: blue">void</span> RemoveClientMachine(<span style="color: #2b91af">IClientCallback</span> remoteMachine)
</p>
          <p style="margin: 0px">
{
</p>
          <p style="margin: 0px">
    <span style="color: blue">if</span> (remoteMachine != <span style="color: blue">null</span>)
</p>
          <p style="margin: 0px">
    {
</p>
          <p style="margin: 0px">
        <span style="color: #2b91af">RegisteredClient</span> client;
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
        <span style="background: #ffffbf">// Unregister
them automatically</span></p>
          <p style="margin: 0px">
        <span style="color: blue">lock</span> (m_callbackList)
</p>
          <p style="margin: 0px">
        {
</p>
          <p style="margin: 0px">
            client = m_callbackList.Find(c
=&gt; c.CallBack == remoteMachine); 
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
            <span style="color: blue">if</span> (client
!= <span style="color: blue">null</span>)
</p>
          <p style="margin: 0px">
               
m_callbackList.Remove(client);                    
</p>
          <p style="margin: 0px">
        }
</p>
        </div>
        <p>
 
</p>
        <p>
One interesting failure scenario I found occurred when you had a large number of clients
connected and something like your main network line goes down. In some cases I wouldn't
receive a notification for every client to remove them from a list (I'm guessing it
was firing so many events some of them were being lost). At any rate, the easiest
way for me to address this was to include a watchdog timer which would periodically
sweep through the connections and attempt to determine if they were still valid. Here's
what that looks like: 
</p>
        <div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new">
          <p style="margin: 0px">
            <span style="color: blue">public</span>
            <span style="color: blue">void</span> CheckCallbackChannels()
</p>
          <p style="margin: 0px">
{
</p>
          <p style="margin: 0px">
    <span style="color: #2b91af">RegisteredClient</span>[] clientList
= <span style="color: blue">new</span><span style="color: #2b91af">RegisteredClient</span>[0];
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
    <span style="color: blue">lock</span> (m_callbackList)
</p>
          <p style="margin: 0px">
    {
</p>
          <p style="margin: 0px">
        clientList = <span style="color: blue">new</span><span style="color: #2b91af">RegisteredClient</span>[m_callbackList.Count];
</p>
          <p style="margin: 0px">
        m_callbackList.CopyTo(clientList);
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
        <span style="color: blue">foreach</span> (<span style="color: #2b91af">RegisteredClient</span> registeredClient <span style="color: blue">in</span> clientList)
</p>
          <p style="margin: 0px">
        {
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">ICommunicationObject</span> callbackChannel
= registeredClient.CallBack <span style="color: blue">as</span><span style="color: #2b91af">ICommunicationObject</span>;
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
            <span style="color: blue">if</span> (callbackChannel.State
== <span style="color: #2b91af">CommunicationState</span>.Closed || callbackChannel.State
== <span style="color: #2b91af">CommunicationState</span>.Faulted)
</p>
          <p style="margin: 0px">
            {
</p>
          <p style="margin: 0px">
                <span style="color: blue">this</span>.RemoveClientMachine(registeredClient.CallBack);                        
</p>
          <p style="margin: 0px">
            }
</p>
          <p style="margin: 0px">
        }
</p>
          <p style="margin: 0px">
    }                        
</p>
          <p style="margin: 0px">
}
</p>
        </div>
        <p>
 
</p>
        <p>
          <strong>Links: </strong>
        </p>
        <p>
 <a title="http://www.rcs-solutions.com/blog/2008/07/06/WCFNotificationOnDisconnect.aspx" href="http://www.rcs-solutions.com/blog/2008/07/06/WCFNotificationOnDisconnect.aspx">http://www.rcs-solutions.com/blog/2008/07/06/WCFNotificationOnDisconnect.aspx</a></p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=d088853d-a3e6-4e33-8446-ac6d2dfc9c70" />
      </body>
      <title>Handling Disconnects with WCF</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,d088853d-a3e6-4e33-8446-ac6d2dfc9c70.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2008/09/24/HandlingDisconnectsWithWCF.aspx</link>
      <pubDate>Wed, 24 Sep 2008 23:14:24 GMT</pubDate>
      <description>&lt;p&gt;
I received a question regarding &lt;a href="http://www.rcs-solutions.com/blog/2008/07/06/WCFNotificationOnDisconnect.aspx"&gt;this
post&lt;/a&gt; on WCF and what my handlers look like when a client disconnects (either because
of a fault or the client connection is closed). It's fairly simple. Here's the code
used to hook up the events: 
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;IClientCallback&lt;/span&gt; remoteMachine = &lt;span style="color: #2b91af"&gt;OperationContext&lt;/span&gt;.Current.GetCallbackChannel&amp;lt;&lt;span style="color: #2b91af"&gt;IClientCallback&lt;/span&gt;&amp;gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;OperationContext&lt;/span&gt;.Current.Channel.Faulted += &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt;(ClientFaulted);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;OperationContext&lt;/span&gt;.Current.Channel.Closed += &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt;(ClientClosed);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
As a side note, I haven't quite gotten in the habit of using the new/shortened syntax
for hooking up delegates. The code above can actually now be written as: 
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;IClientCallback&lt;/span&gt; remoteMachine = &lt;span style="color: #2b91af"&gt;OperationContext&lt;/span&gt;.Current.GetCallbackChannel&amp;lt;&lt;span style="color: #2b91af"&gt;IClientCallback&lt;/span&gt;&amp;gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;OperationContext&lt;/span&gt;.Current.Channel.Faulted += ClientFaulted;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;OperationContext&lt;/span&gt;.Current.Channel.Closed += ClientClosed;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
At any rate, the code in both handlers is actually the same, so I'll just show ClientClosed: 
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; Called
whenever a client machine's connection is closed.&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; Automatically
removes them from our internal list of clients.&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;param
name="sender"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;param
name="e"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span style="color: blue"&gt;void&lt;/span&gt; ClientClosed(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;IClientCallback&lt;/span&gt; remoteMachine
= sender &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IClientCallback&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.RemoveClientMachine(remoteMachine);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
All it does is cast the sender to the IClientCallback interface and call another method
which actually removes it from my internal list. Here's what that code is doing (actually,
I send out another notification in the real code to any other clients to let them
know something has changed). It just locks the list then uses a lambda to find the
client in the list, and if it's found, it's removed. 
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; RemoveClientMachine(&lt;span style="color: #2b91af"&gt;IClientCallback&lt;/span&gt; remoteMachine)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (remoteMachine != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;RegisteredClient&lt;/span&gt; client;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;// Unregister
them automatically&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;lock&lt;/span&gt; (m_callbackList)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; client = m_callbackList.Find(c
=&amp;gt; c.CallBack == remoteMachine); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (client
!= &lt;span style="color: blue"&gt;null&lt;/span&gt;)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
m_callbackList.Remove(client);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
One interesting failure scenario I found occurred when you had a large number of clients
connected and something like your main network line goes down. In some cases I wouldn't
receive a notification for every client to remove them from a list (I'm guessing it
was firing so many events some of them were being lost). At any rate, the easiest
way for me to address this was to include a watchdog timer which would periodically
sweep through the connections and attempt to determine if they were still valid. Here's
what that looks like: 
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; CheckCallbackChannels()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;RegisteredClient&lt;/span&gt;[] clientList
= &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RegisteredClient&lt;/span&gt;[0];
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;lock&lt;/span&gt; (m_callbackList)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clientList = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RegisteredClient&lt;/span&gt;[m_callbackList.Count];
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_callbackList.CopyTo(clientList);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;RegisteredClient&lt;/span&gt; registeredClient &lt;span style="color: blue"&gt;in&lt;/span&gt; clientList)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;ICommunicationObject&lt;/span&gt; callbackChannel
= registeredClient.CallBack &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ICommunicationObject&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (callbackChannel.State
== &lt;span style="color: #2b91af"&gt;CommunicationState&lt;/span&gt;.Closed || callbackChannel.State
== &lt;span style="color: #2b91af"&gt;CommunicationState&lt;/span&gt;.Faulted)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.RemoveClientMachine(registeredClient.CallBack);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Links: &lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&lt;a title="http://www.rcs-solutions.com/blog/2008/07/06/WCFNotificationOnDisconnect.aspx" href="http://www.rcs-solutions.com/blog/2008/07/06/WCFNotificationOnDisconnect.aspx"&gt;http://www.rcs-solutions.com/blog/2008/07/06/WCFNotificationOnDisconnect.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=d088853d-a3e6-4e33-8446-ac6d2dfc9c70" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,d088853d-a3e6-4e33-8446-ac6d2dfc9c70.aspx</comments>
      <category>WCF</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=ed29d8a8-6896-406b-a3ea-d3b14e995291</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,ed29d8a8-6896-406b-a3ea-d3b14e995291.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,ed29d8a8-6896-406b-a3ea-d3b14e995291.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ed29d8a8-6896-406b-a3ea-d3b14e995291</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've been working on an application which relies heavily on WCF to communicate. I
have a very simple interface (contract) that the server supports to connect and disconnect:
it exposes the methods Register() and Unregister(). When the client starts up and
connects, it calls the Register() method, passing in some identification info. I save
this information in a List&lt;T&gt; so that it can be used by the server to provide
callbacks. When the client disconnects, it calls Unregister() which then removes the
client from the collection.
</p>
        <p>
That works well enough, right up until a client abruptly disconnects (ex. a connection
error, network line goes down, etc.) Then suddenly I end up with a reference to a
disconnected client on the server. If I attempt to use this connection to send a message
back to the client an exception is thrown (which still works OK). It would be nice
to know immediately as soon as a client disconnects. 
</p>
        <p>
If you are using TCP (full duplex) as the communication channel, you can do this pretty
easily - note: this doesn't work for some of the other communication modes, like HTTP
duplex. For those, you might have to rely on the various timeout settings in the .config
file. 
</p>
        <p>
Here's what that ends up looking like (I happen to be taking advantage of LINQ here,
but you can easily adjust that code if you're using an older vesion of the framework): 
<br /></p>
        <div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new">
          <p style="margin: 0px">
            <span style="color: #2b91af">  203</span> <span style="color: blue">private</span><span style="color: blue">void</span><span style="color: #2b91af">IServer</span>.Register(<span style="color: blue">string</span> systemName)
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  204</span> {
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  205</span>     <span style="color: #2b91af">IClientCallback</span> remoteMachine
= <span style="color: #2b91af">OperationContext</span>.Current.GetCallbackChannel&lt;<span style="color: #2b91af">IClientCallback</span>&gt;();
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  206</span>     <span style="background: #ffffbf">//
Hook up events to let us know if the client disconnects w/o telling us.</span></p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  207</span>     <span style="color: #2b91af">OperationContext</span>.Current.Channel.Faulted
+= <span style="color: blue">new</span><span style="color: #2b91af">EventHandler</span>(ClientFaulted);
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  208</span>     <span style="color: #2b91af">OperationContext</span>.Current.Channel.Closed
+= <span style="color: blue">new</span><span style="color: #2b91af">EventHandler</span>(ClientClosed);
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  209</span> 
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  210</span>     <span style="background: #ffffbf">//
Get object reference to figure out the IP address of the connected client</span></p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  211</span>     <span style="color: #2b91af">MessageProperties</span> prop
= <span style="color: #2b91af">OperationContext</span>.Current.IncomingMessageProperties;
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  212</span>     <span style="color: #2b91af">RemoteEndpointMessageProperty</span> endpoint
= prop[<span style="color: #2b91af">RemoteEndpointMessageProperty</span>.Name] <span style="color: blue">as</span><span style="color: #2b91af">RemoteEndpointMessageProperty</span>;
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  213</span> 
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  214</span>     <span style="background: #ffffbf">//
(threading/locking code removed)</span></p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  215</span> 
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  216</span>     client = m_callbackList.Find(c
=&gt; c.SystemName == systemName);
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  217</span>     <span style="color: blue">if</span> (client
== <span style="color: blue">null</span>)
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  218</span>     {
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  219</span>         <span style="background: #ffffbf">//
It's not already on our list, add it</span></p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  220</span>        
m_callbackList.Add(<span style="color: blue">new</span><span style="color: #2b91af">RegisteredClient</span>(systemName,
endpoint.Address, remoteMachine));
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  221</span>     }
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">  222</span> }
</p>
          <p style="margin: 0px">
 
</p>
        </div>
When the client disconnects, the ClientFaulted/ClientClosed events will be fired.
Honestly, at this point, the Unregister method isn't really needed, assuming you follow
the same disconnection process in both cases. <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=ed29d8a8-6896-406b-a3ea-d3b14e995291" /></body>
      <title>WCF Notification on Disconnect</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,ed29d8a8-6896-406b-a3ea-d3b14e995291.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2008/07/06/WCFNotificationOnDisconnect.aspx</link>
      <pubDate>Sun, 06 Jul 2008 15:37:05 GMT</pubDate>
      <description>&lt;p&gt;
I've been working on an application which relies heavily on WCF to communicate. I
have a very simple interface (contract) that the server supports to connect and disconnect:
it exposes the methods Register() and Unregister(). When the client starts up and
connects, it calls the Register() method, passing in some identification info. I save
this information in a List&amp;lt;T&amp;gt; so that it can be used by the server to provide
callbacks. When the client disconnects, it calls Unregister() which then removes the
client from the collection.
&lt;/p&gt;
&lt;p&gt;
That works well enough, right up until a client abruptly disconnects (ex. a connection
error, network line goes down, etc.) Then suddenly I end up with a reference to a
disconnected client on the server. If I attempt to use this connection to send a message
back to the client an exception is thrown (which still works OK). It would be nice
to know immediately as soon as a client disconnects. 
&lt;/p&gt;
&lt;p&gt;
If you are using TCP (full duplex) as the communication channel, you can do this pretty
easily - note: this doesn't work for some of the other communication modes, like HTTP
duplex. For those, you might have to rely on the various timeout settings in the .config
file. 
&lt;/p&gt;
&lt;p&gt;
Here's what that ends up looking like (I happen to be taking advantage of LINQ here,
but you can easily adjust that code if you're using an older vesion of the framework): 
&lt;br&gt;
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 203&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IServer&lt;/span&gt;.Register(&lt;span style="color: blue"&gt;string&lt;/span&gt; systemName)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 204&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 205&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;IClientCallback&lt;/span&gt; remoteMachine
= &lt;span style="color: #2b91af"&gt;OperationContext&lt;/span&gt;.Current.GetCallbackChannel&amp;lt;&lt;span style="color: #2b91af"&gt;IClientCallback&lt;/span&gt;&amp;gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 206&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
Hook up events to let us know if the client disconnects w/o telling us.&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 207&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;OperationContext&lt;/span&gt;.Current.Channel.Faulted
+= &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt;(ClientFaulted);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 208&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;OperationContext&lt;/span&gt;.Current.Channel.Closed
+= &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt;(ClientClosed);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 209&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 210&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
Get object reference to figure out the IP address of the connected client&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 211&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;MessageProperties&lt;/span&gt; prop
= &lt;span style="color: #2b91af"&gt;OperationContext&lt;/span&gt;.Current.IncomingMessageProperties;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 212&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;RemoteEndpointMessageProperty&lt;/span&gt; endpoint
= prop[&lt;span style="color: #2b91af"&gt;RemoteEndpointMessageProperty&lt;/span&gt;.Name] &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RemoteEndpointMessageProperty&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 213&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 214&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
(threading/locking code removed)&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 215&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 216&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; client = m_callbackList.Find(c
=&amp;gt; c.SystemName == systemName);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 217&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (client
== &lt;span style="color: blue"&gt;null&lt;/span&gt;)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 218&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 219&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
It's not already on our list, add it&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 220&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
m_callbackList.Add(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RegisteredClient&lt;/span&gt;(systemName,
endpoint.Address, remoteMachine));
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 221&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: #2b91af"&gt;&amp;nbsp; 222&lt;/span&gt; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;/div&gt;
When the client disconnects, the ClientFaulted/ClientClosed events will be fired.
Honestly, at this point, the Unregister method isn't really needed, assuming you follow
the same disconnection process in both cases. &lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=ed29d8a8-6896-406b-a3ea-d3b14e995291" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,ed29d8a8-6896-406b-a3ea-d3b14e995291.aspx</comments>
      <category>WCF</category>
    </item>
  </channel>
</rss>