Dennis van der Stelt

If you have one problem and use cache to solve it, you now have two problems.

Community

Email Notifications

News

  • Addicted to Refactor! Pro

I read...

I Use...

Tags

Recent Posts

Archives

Blog Subscription Form

  • Email Notifications
    Go

Finding available callback tcp port for a WCF chat client

While having some fun writing a WCF chat application, I was having some troubles.

I was using duplex communication over http, using the WsDualHttpBinding. The client needs to setup a callback channel for the service to... well, call back actually. Hence the name, I guess ;-) Anyway, by default it wants to create this channel on port 80, which wasn't possible because IIS is already listening on that port. For that you need to specify the ClientbaseAddress on your binding.

DuplexChannelFactory<IChatService> dcf = new DuplexChannelFactory<IChatService>(client, "ChatService");
Uri uri = new Uri(@"http://localhost:8000/callbackchannel");
((WSDualHttpBinding)dcf.Endpoint.Binding).ClientBaseAddress = uri;

Now the callback channel is on port 8000. But, you might want to start multiple clients to test your service. So you need to know what port isn't taken yet. I wasn't the first to ask this question, but either I'm really lousy in searching Google, or nobody has blogged a complete answer yet. Either way, here's what I used.

int selectedPort = 8000;
bool goodPort = false;
IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
//
while (!goodPort)
{
 
  IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, selectedPort);
  TcpListener list = new TcpListener(ipLocalEndPoint);
  try
  {
    list.Start();
    goodPort = true;
    list.Stop();
  }
  catch
  {
    selectedPort++;
  }
}

There you go, now you know as well.

Update : Was having some problems with CopySourceAsHtml after changing some settings. Should work now.

Comments

Waseem Sadiq said:

Dennis,

There might be an easier way for doing this (works with peerChannel, not sure about regular callbacks), check it out:

http://blogs.msdn.com/kevin_ransom/archive/2006/06/10/Automatic-port-number-generation.aspx

# November 14, 2006 6:55 AM

Jan Schreuder said:

I saw the duplex option at Tech-Ed. I was really impressed with that option.

# November 14, 2006 7:02 AM

Dennis van der Stelt said:

Waseem, I tried the port 0 in code, as I read somewhere else (not a WCF reference) that it would use any available port. But it returned an error.

Will try it again using config though, perhaps it'll work than.

# November 14, 2006 12:28 PM

Mohamed Amine AZZI said:

Hi Dennis, Did you use a web client or windows forms clients for your chat application? I need to know how to make a dual communnication when using asp.net pages. Regards
# December 5, 2006 7:53 AM

Hazem Salem said:

Hi Dennis, I'm also interesting to use this dual application with wep.net page, did you make it before?

best reards

# May 17, 2007 10:44 AM

Dennis van der Stelt said:

@Hazem: I seriously have no idea what you're talking about, sorry :)

# May 17, 2007 2:33 PM

Mike said:

Try this instead: IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0); using( Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { socket.Bind(endPoint); IPEndPoint local = (IPEndPoint)socket.LocalEndPoint; return local.Port; }
# June 1, 2007 8:40 PM

jimi said:

hi,

   i m trying to use Duplex channel factory along with te to create a IClientChannel to create a pda chat client. both are not support in .net 3.5 WCF. Any one has done a WCF chat app ?

jimi

# September 11, 2008 11:36 AM

Robbert said:

Hi Dennis,

You can find some good explanations here:

codeidol.com/.../Callback-Operations

In the book Programming WCF Services written by Juval Lowy, there is some code, that can let you set the port to any free port.

It can be done by attributes, but the simple thing is do it programmaticly with a helperClass.

  public static class WsDualProxyHelper

  {

     public static void SetClientBaseAddress<T>(DuplexClientBase<T> proxy,int port) where T : class

     {

        if(proxy.State == CommunicationState.Opened)

        {

           throw new InvalidOperationException("Proxy is already opened");

        }

        WSDualHttpBinding binding = proxy.Endpoint.Binding as WSDualHttpBinding;

        Debug.Assert(binding != null);

        binding.ClientBaseAddress = new Uri("http://localhost:" + port +"/");

     }

     public static void SetClientBaseAddress<T>(DuplexClientBase<T> proxy) where T : class

     {

        lock(typeof(WsDualProxyHelper))

        {

           int portNumber = FindPort();

           SetClientBaseAddress(proxy,portNumber);

           proxy.Open();

        }

     }

     internal static int FindPort()

     {

        IPEndPoint endPoint = new IPEndPoint(IPAddress.Any,0);

        using(Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp))

        {

           socket.Bind(endPoint);

           IPEndPoint local = (IPEndPoint)socket.LocalEndPoint;

           return local.Port;

        }

     }

  }

After declaring the proxy, just assign clientBaseAddress like this:

WsDualProxyHelper.SetClientBaseAddress(proxy); or WsDualProxyHelper.SetClientBaseAddress(proxy, 3000);

# April 15, 2009 12:18 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Please add 6 and 3 and type the answer here: