WCF hostname is always 0.0.0.0 - wcf

I have strange problem with my WCF REST configuration. I would like to point a network interface on which TCP is listening for incoming messages (I have two network adapters). But whatever I put as a hostname in base address, TCP is always listening on 0.0.0.0 (all interfaces).
This is my App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="RestServiceSample.ServiceImpl" behaviorConfiguration="ServiceBehaviour">
<endpoint address="service" binding="webHttpBinding"
contract="RestServiceSample.IService"
behaviorConfiguration="web">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://192.168.0.100:3880/MyService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
And code:
var serviceHost = new ServiceHost(new ServiceImpl());
serviceHost.Open();
So I want to listen on 192.168.0.100 but when I run netstat I can see that there is TCP connection listening on 0.0.0.0:3880.
When I set hostNameComparisonMode="Exact" in binding configuration then TCP listening on correct interface but I cannot connect to service by domain name - only by IP address of network adapter.
Any ideas how to play with that without setting hostNameComparisonMode="Exact" property?

Have you tried to specify ListenUri parameter for your endpoint?
<endpoint address="service" binding="webHttpBinding"
listenUri="http://192.168.0.100:3880/MyService"
contract="RestServiceSample.IService"
behaviorConfiguration="web">

use WebServiceHost for webhttpbinding
var serviceHost = new WebServiceHost(new ServiceImpl());
serviceHost.Open();

FWLIW: net.tcp works fine.
There is something strange going on with BasicHttpBinding's bindings and it looks like a bona fide bug to me.
It pays some attention to the URI specified. I observe that it adds a binding to the correct interface, but then it goes and slaps another binding for 0.0.0.0 ruining all good efforts put forth in the first step.

Related

Add service reference when using netTcp binding

I have a WCF service that I tested by copying its interfaces to a sample client project.
Now I want to work properly by adding a service reference.
The service is hosted in windows hosting (using installUtil).
The service has 2 projects - externals (interfaces + datacontracts) and internals (implementations).
For some reason it didn't have an app.config so I added one manually:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="ExecutionService" behaviorConfiguration="Default">
<endpoint name="TCPEndpoint" address="" binding ="netTcpBinding" contract="Externals.IExecutionService"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:3040/ExecutionService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Trying to add a service reference from my sample client causes the following error:
Metadata contains a reference that cannot be resolved: 'net.tcp://localhost:3040/ExecutionService/Externals.IExecutionService'.
There was no endpoint listening at net.tcp://localhost:3040/ExecutionService/Externals.IExecutionService that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
If the service is defined in the current solution, try building the solution and adding the service reference again.
I saw here that there's no need in app.config.
I'm a bit confused and I'm a beginner with WCF.
How can a nice WPF app reference my service? I want the service to be windows hosted and I don't want to drag dlls with me.
Edit
I added a metadata endpoint and my appconfig now looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="ExecutionService" behaviorConfiguration="Default">
<endpoint name="TCPEndpoint"
address=""
binding ="netTcpBinding"
contract="Externals.IExecutionService"/>
<endpoint address="mex"
binding="maxHttpBinding"
contract="Externals.IExecutionService"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:3040/ExecutionService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I tried adding a service reference by using net.tcp://localhost:3040/ExecutionService, net.tcp://localhost:3040/ExecutionService/Externals and net.tcp://localhost:3040/ExecutionService/Externals/IExecutionService and I'm still getting the same error.
You need to do:
maxHttpBinding -> mexTcpBinding - you cannot use mexHttpBinding on net.tcp endpoint (and it's mex not max)
the contract for mex endpoint must be IMetadataExchange - as you want to have service metadata available through this endpoint
httpGetEnabled="false" as there will be no http endpoint to get metadata from
When I was testing the solution in a simple console host I needed to change name in <service> tag to Externals.ExecutionService (but this depends on how you instantiate the service)
Then your service reference will be available at: net.tcp://localhost:3040/ExecutionService/mex
as base address is net.tcp://localhost:3040/ExecutionService and the relative address for the mex endpoint is set to mex
Final app.config is below:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="Externals.ExecutionService" behaviorConfiguration="Default">
<endpoint name="TCPEndpoint"
address=""
binding ="netTcpBinding"
contract="Externals.IExecutionService"/>
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:3040/ExecutionService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
For a quick test if the configuration is correct I used console host app as a service host.
Program.cs:
using System;
using System.ServiceModel;
namespace Externals
{
class Program
{
static void Main(string[] args)
{
var sh=new ServiceHost(typeof(ExecutionService));
sh.Open();
Console.WriteLine("Service running press any key to terminate...");
Console.ReadKey();
sh.Close();
}
}
}
Run the console app and try to add service reference to your project through net.tcp://localhost:3040/ExecutionService/mex.
At first glance, you've forgotten Metadata Endpoint
Change this:
<endpoint address="mex"
binding="maxHttpBinding"
contract="Externals.IExecutionService"/>
To:
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange"/>
Notice it's not maxHttpBinding but mexTcpBinding, you had typo as well there.

How config file would look at service end for multiple endpoint

i am working with wcf service application where svc file is created. now i want to design my service in such a way that people can connect to my service by http url and as well as by tcp url
so i would like to add three endpoint in my config one for wshttp, one for wsDualhttp and another one for tcp. so please someone give me sample config entry with 3 endpoints for wshttp, wsDualhttp and tcp.
in this case do i need to have three different mex endpoint for wshttp, wsDualhttp and tcp.
also tell me 3 url by which i can create proxy classes at client side. thanks
You could have something like this (assuming self-hosting, since only then can you really determine the full service addresses yourself - hosting in IIS, the service address(es) are most determined by where your .svc file lives):
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="YourNamespace.YourService" behaviorConfiguration="Default">
<endpoint name="Default"
address="http://YourServer/Services/MyService"
binding="basicHttpBinding"
contract="YourNamespace.IYourService"/>
<endpoint name="TCP"
address="net.tcp://YourServer/ServicesTCP/MyService"
binding="netTcpBinding"
contract="YourNamespace.IYourService"/>
<endpoint name="mex"
address="http://YourServer/Services/MyService/mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
<endpoint name="Dual"
address="http://YourServer/Services/MyService/Dual"
binding="wsDualHttpBinding"
clientBaseAddress="http://localhost:8001/client/"
contract="YourNamespace.IYourDualService"/>
</service>
</services>
</system.serviceModel>
This would define three endpoints:
a HTTP endpoint at http://YourServer/Services/MyService for your service
a HTTP MEX endpoint at http://YourServer/Services/MyService/mex for the metadata exchange (service discoverability)
a Net.TCP endpoint at net.tcp://YourServer/ServicesTCP/MyService for your service
You could of course also use two base addresses to make things a bit easier in the config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="YourNamespace.YourService" behaviorConfiguration="Default">
<host>
<baseAddresses>
<add baseAddress="http://YourServer/Services"/>
<add baseAddress="net.tcp://YourServer/ServicesTCP"/>
</baseAddresses>
</host>
<endpoint name="Default"
address="MyService"
binding="basicHttpBinding"
contract="YourNamespace.IYourService"/>
<endpoint name="TCP"
address="MyService"
binding="netTcpBinding"
contract="YourNamespace.IYourService"/>
<endpoint name="mex"
address="MyService/mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
This would configure the equivalent service endpoints.
The wsDualHttpBinding is different in that it requires at least a clientBaseAddress for the callback mechanism (the WCF service will call back your client to send back e.g. status messages) - so it needs some extra tweaks and it cannot really be bolted onto an existing service that works over wsHttpBinding - it needs to be done separately. But basically - it's still pretty much all the same thing....
Update: after reading up on the topic (it's not something I use very often), it does appear that duplex communication is indeed possible also using netTcpBinding, but only if you're self-hosting your service - IIS doesn't support duplex communication over netTcpBinding.
Creating a duplex service does still require extra steps and extra code - so you cannot really have a service that's both non-duplex using basicHttpBinding or wsHttpBinding and duplex at the same time. So it really doesn't make sense to have another endpoint in this example using the wsDualHttpBinding because that service either needs to be really duplex (then you can use wsDualHttpBinding and netTcpBinding) - or it's not duplex - then you can use basicHttpBinding, wsHttpBinding, netTcpBinding and a few more "exotic" bindings (like MSMQ, named pipes etc.)

How to run WCF service on a specific port

I have a .Net 4.0 WCF service running on IIS. I have not specified a port so assume it is running on port 80. I need to install my service on a server where port 80 is already being used and the network guy had asked me to change my service to run on port 443. How do I do this? I'm guessing it can be configured in app.config but I can't find an article that shows me how.
Here is my current app.config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
I am assuming you are running your services on net.tcp protocols.
1) Edit your bindings (right click Default Web Site select Edit Bindings
2) Server Side
<service name="YouServiceNameSpace.YourService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="YourBinding" contract="YourContract" />
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" contract="IMetadataExchange" />
</service>
3) Client Side
<endpoint address="net.tcp://YourHost:443/YourServiceDirecotry/YourService.svc"
behaviorConfiguration="YourBehavior" binding="netTcpBinding"
bindingConfiguration="YourTcpBinding" contract="YourContract"
name="YourContractName" />
We can do it using the .csproj file of the WCF project(in case of using VS).Just change the value of this xml tag in your corresponding file:
To Run the service at port number 60000 ,
<DevelopmentServerPort>60000</DevelopmentServerPort>
Normally you should have a services node with at least one service node and each having endpoints, where you can specify the port. See more at: http://msdn.microsoft.com/en-us/library/ms733932.aspx
For example:
<services>
<service name="MyNamespace.myServiceType">
<endpoint
address="net.tcp://0.0.0.0:8000" binding="basicHttpBinding"
bindingConfiguration="myBindingConfiguration1"
contract="MyContract" />
</service>
</services>
Specify the port in the address of the endpoint. See the 'Defining Endpoint Addresses in Code' section in this article for more details.

Unable to configure WCF service to be consumed by silverlight client

I am trying hard to develop a duplex wcf service to be consumed by silverlight clients. Now for adventure sake, I decided to use nettcpbinding. I understand that the concept of PolicyServer to be running on port 943 is obselete now and it should be served from root of the service.
given Below is config section for the service
<behaviors>
<serviceBehaviors>
<behavior name="WcfServer.WcfServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="CrossDomainServiceBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="WcfServer.WcfServiceBehavior"
name="WcfServer.MainService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="TCPBinding" contract="WCFWebFrontCommunication.IMainService">
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="CrossDomainServiceBehavior" contract="WCFWebFrontCommunication.IClientAccessPolicy" />
<host>
<baseAddresses>
<!--<add baseAddress= "http://192.168.0.101:943/WcfServer/MainService" />-->
<!--<add baseAddress= "http://localhost:943/WcfServer/MainService" />-->
<add baseAddress= "net.tcp://localhost:4502/WcfServer/MainService" />
<add baseAddress="http://localhost:4502"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
now at runtime I get an exception HTTP could not register URL http://+:4502/ because TCP port 4502 is being used by another application. when Open Method is called.
Am I doing something silly here .., although http exception was there with basicHttpBinding as well
As Troubleshooting:
checked for open port using Netstat -aon
There were some post regarding HTTP configuration followed them nothing happened
Thanks for reading.
You're trying to host a clientaccesspolicy.xml file over HTTP, and use net.tcp on the same port number, that's not going to work. While both of these protocols build on TCP/IP, they are incompatible.
As far as I understand (see also this article), port 943 is still used for this type of thing.

How to force a net.tcp mex endpoint (mexTcpBinding) to participate in port sharing?

I have a WCF service which is hosted as a Windows Service. We would like to enable a mex endpoint at the same address (but with a '/mex' suffix). I have been trying to do this (unsuccessfully) using the following configuration:
<system.serviceModel>
<services>
<service
name="MyCompany.MyService"
behaviorConfiguration="defaultServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost"/>
</baseAddresses>
</host>
<endpoint
address="MyService"
binding="netTcpBinding"
contract="MyCompany.IMyService"
bindingConfiguration="netTcpBindingConfig"
/>
<endpoint
address="MyService/mex"
binding="mexTcpBinding"
contract="IMetadataExchange"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="defaultServiceBehavior">
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="netTcpBindingConfig" portSharingEnabled="true" />
</netTcpBinding>
</bindings>
</system.serviceModel>
When it runs, the service host throws an AddressAlreadyInUseException complaining that "There is already a listener on IP endpoint 0.0.0.0:808". This actually makes sense to me because the port sharing service has opened that port in order to serve the MyService endpoint along with any other services requesting to share that port on this machine.
So it seems that the mex endpoint wants exlusive access to port 808. I can work around this by tweaking the mex endpoint like so:
<endpoint
address="net.tcp://localhost:818/MyService/mex"
binding="mexTcpBinding"
contract="IMetadataExchange"
/>
This means that the mex endpoint now has its own exclusive port. The downside with this is that any other service which wants to expose a mex endpoint will also need a unique port for its mex endpoint. This makes it very unpredictable when looking for mex endpoints.
Is there a way to force the mex endpoint to participate in port sharing?
Two options:
The easy way: Change the entire binding for the mex point to netTcpBinding and have it reuse your bindingConfiguration. mexTCPBinding is only meant to be a convenience and is optional. If its not working for you, don’t use it.
The hard way: You can modify the mexTCPBinding to enable sharing. The only example I’ve seen is in code here: Link