MSMQ calls over HTTP not reaching destination queue - wcf

I have a WCF service that uses MSMQ communication, when i run the service on my local netwrok, i configure the service endpoints in the client config files to point to the host computer, for example if the endpoint specified on the service host is:
<endpoint address="net.msmq://localhost/private/MsmqService/MyMsmqService"
binding="netMsmqBinding" bindingConfiguration="test" contract="MsmqService.IMyMsmqService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
I configure my client to send messages to this endpoint:
<endpoint address="net.msmq://192.168.1.5/private/MsmqService/MyMsmqService"
binding="netMsmqBinding" bindingConfiguration="test" contract="MsmqService.IMyMsmqService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
Obviously 192.168.1.5 is the IP of the host computer, this works like a charm. I host my service in IIS 7, I activate the MSMQ listener on IIS, give appropriate access right etc (Pretty much everything in Tom Hollanders article) and I can even access my service over http in my browser, but when I create clients of my service which is hosted in IIS and configure the endpoints in the client App.config, naturally I configure my clients to this:
<endpoint address="net.msmq://ServiceHostPublicIP/private/MsmqService/MyMsmqService"
binding="netMsmqBinding" bindingConfiguration="test" contract="MsmqService.IMyMsmqService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
That's where things go wrong. The messages I send keep getting queued in an outgoing queue on the client machine: DIRECT=OS:[ServiceHostPublicIP]\private$\MsmqService\MyMsmqService
and the state of the queue is always: 'Waiting to Connect'. I've tried setting the queue transfer protocol to SRMP, my queue name is the same as my service name as is required by IIS, and I've given appropriate permissions on the queue. Has anybody recently encountered this problem before? Any Ideas? It'd be great if somebody could share a working sample of MSMQ over HTTP if they had one.
Any help would be greatly appreciated. Thanks in advance.

I managed to fix this, my messages were getting stuck in an outgoing queue on the client machine, "DIRECT=TCP:HOSTSERVERIP\private$\MsmqService/MyMsmqService.svc" the state of the queue was 'Waiting to connect' and the next hop was the destination servers public IP, so the client couldn't connect to the destination queue even though it could ping the destination servers public IP, turned out the port 1801 which is used by MSMQ to listen to incoming traffic was not open on the router of the network on which the service host machine resided, after opening port 1801 everything is working like a charm. It's such a fundamental issue that i guess many didn't bother mentioning it in their articles/tutorials. Hope this helps somebody later on.

Related

WCF dropping connections (random timeouts, socket aborts, endpoint not found) -Port sharing

I'm doing some wcf tracing on a sever with 800 clients (verbose clients) and I am seeing a lot of SocketConnection aborted after Process action 'http://tempuri.org/IConnectionRegister/ValidateUriRoute'. This is during a ** ** activity
I removed (maxed out) all possible throttling (binding, service, port sharing (both on custom binding and SMSvcHost.exe). Still a lot of random timeouts and socket aborted.
Also the 0000 activity is absolutely full (less than every second) of
"The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '10675199.02:48:05.4775807'."
"The I/O operation has been aborted because of either a thread exit or an application request"
Any help would be very much appreciate in identifying who is causing the dropping of connections.
I can also upload a sample svc trace if anyone is interested.
Stack trace of Socket Connection Abort
System.ServiceModel.Channels.SocketConnection.Abort()
System.ServiceModel.Channels.TracingConnection.Abort()
System.ServiceModel.Channels.InitialServerConnectionReader.Abort()
System.ServiceModel.Channels.ServerSessionPreambleConnectionReader.OnValidate()
......
System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame()
System.Runtime.AsyncResult.Complete()
System.ServiceModel.Channels.TransportDuplexSessionChannel.TryReceiveAsyncResult.OnReceive()
System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame()
System.Runtime.AsyncResult.Complete()
System.ServiceModel.Channels.SynchronizedMessageSource.ReceiveAsyncResult.OnReceiveComplete()
<customBinding>
<binding name="externalRoutingcustomBinding">
<binaryMessageEncoding>
</binaryMessageEncoding>
<security
authenticationMode="UserNameOverTransport"
allowInsecureTransport="true"
enableUnsecuredResponse="true"
>
</security><tcpTransport>
<connectionPoolSettings groupName = "default" maxOutboundConnectionsPerEndpoint = "1000"/>
</tcpTransport>
</binding>
<service name="ZPRoutingWorkflow.ZpRoutingService">
<endpoint address="Transactions" binding="customBinding" bindingConfiguration="externalRoutingcustomBinding"
name="Transactions" contract="TopUpInterface.ITransactionsService">
<identity>
<dns value="appserver.test.com" />
</identity>
</endpoint>
<endpoint address="Retry" binding="customBinding" bindingConfiguration="externalRoutingcustomBinding" name="Retry" contract="IRetryInterface.IRetryService">
<identity>
<dns value="appserver.test.com" />
</identity>
</endpoint>
Config summary:
Multiple net.tcp services over same port hosted in iis. One of the services is a routing service implementing IRequestReplyRouter. Basically all messages go through the router and the router connects internally to the services and passes them their messages

WCF Net.Pipe Endpoint

On our build server, we have a service that calls another service on the same box via net.pipe, but it is failing saying that there is no endpoint listening to net.pipe. IIS does have Net.pipe set for both the calling and called service.
<endpoint address="net.pipe://build.QQQQQ.com/QQQ/QQQ.svc"
binding="netNamedPipeBinding" bindingConfiguration="NetNamedPipeBinding_IMembershipService"
contract="QQQ.IMembershipService" name="NetNamedPipeBinding_IMembershipService">
<identity>
<servicePrincipalName value="host/ABCDF.XX.net" />
</identity>
</endpoint>
Note: build.QQQ.com is actually ABCDF.XX.net. is that the problem, do they need to match even though they are the same.
IMO - they should much.
I'd try to remove last "/QQQ.svc" from address.

How to use msmq between WCF Router and WCF Service hosted in a Windows Service

In my current system I have a router service and over a dozen (about half use msmq, rest use tcp) WCF services hosted via IIS. I've been tasked with moving all services except for the router to a windows service. This has been accomplished using the same configurations that were present using the IIS web.config file. Here is a snippet of the previous configs (public queue for service: myservices/wcfservice):
<!--Router Service web.config-->
<client>
<endpoint address="net.msmq://localhost/MyServices/WCFService.svc" binding="netMsmqBinding" contract="*" name="IWCFService_Msmq" />
</client>
<!--Services web.config-->
<service behaviorConfiguration="SomeServiceBehavior" name="WCFService">
<endpoint binding="netMsmqBinding" name="IWCFService_Msmq"
contract="IWCFService" />
<host>
<baseAddresses>
<add baseAddress="net.msmq://localhost/MyServices/WCFService" />
</baseAddresses>
</host>
</service>
I'm confused as to why this works, as the service has a net.tcp binding and the router has msmq, and when I asked around, I was told it was "magic." I tried to do the same thing with my setup (router to windows service) using a similar configuration but get an error message:
<!--Router Service web.config-->
<client>
<endpoint address="net.msmq://localhost/MyServices/WCFService" binding="netMsmqBinding" contract="*" name="IWCFService_Msmq" />
</client>
<!--One "other" Services hosted in Windows Service app.config-->
<service behaviorConfiguration="SomeServiceBehavior" name="WCFService">
<endpoint binding="netMsmqBinding" name="IWCFService_Msmq"
contract="IWCFService" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost/MyServices/WCFService" />
</baseAddresses>
</host>
</service>
This has worked fine with all my services that are just using tcp, but when I try this with msmq and attempt to start the windows service, I get the following error in the Event Viewer:
Service cannot be started. System.InvalidOperationException: Could not find a base address that matches scheme net.msmq for the endpoint with binding NetMsmqBinding. Registered base address schemes are [net.tcp].
I'm new to msmq, so any help with be appreciated. Thanks!
Updated:
I've updated the base address in the service app.config to match the address that is in the router web.config. I tried this previously and it didn't work. I later found out it was because I didn't make the msmq itself a "Transactional Queue" (which was needed for our setup). Once this was done, everything worked out!
<!--One "other" Services hosted in Windows Service app.config-->
<service behaviorConfiguration="SomeServiceBehavior" name="WCFService">
<endpoint binding="netMsmqBinding" name="IWCFService_Msmq"
contract="IWCFService" />
<host>
<baseAddresses>
<add baseAddress="net.msmq://localhost/MyServices/WCFService" />
</baseAddresses>
</host>
</service>
Judging by the error message of the InvalidOperationException, it looks like "net.tcp" is the only enabled protocol in the Advanced Settings of your application hosted in IIS.
Is "net.msmq" an enabled protocol?
Open IIS Manager
Select your application
Click Advanced Settings in the Actions list
Add "net.msmq" to Behavior - Enabled Protocols
Why not give all of your MSMQ services their own config and all the tcp services their own? The issue is obviously it looks for a base address when you choose the binding to be msmq, and it can't find an msmq binding because all you've provided is a tcp base address binding. You can also of course add another base address that uses net.msmq inside the baseaddresses node.

wcf endpoint relative address

I'm just learning wcf and can't understand one very basic thing.
I'm creating a WCF service which I want to be hosted in IIS just like web application with it's own path like http://myhost/myapp/ and everything.
I'm creating the WCF service project in VS, I've got an *.svc file describing it, then I define a simple endpoint to it like that:
<endpoint address=""
binding="basicHttpBinding"
contract="wcf_service_auth.IPshService" />
Then I publish this service like an IIS web application to a virtual directory, let's assume it's name psh_pub, so I can access the service via url http://localhost/psh_pub/pshservice.svc/. It shows me WCF greetings page and gives me a link to WSDL, which gives me correct wsdl description.
That's ok.
The next step - I want to add a MEX endpoint. I add to config:
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
That's ok too, the endpoint is accessible at address http://localhost/psh_pub/pshservice.svc/mex and WcfTestClient.exe gives me correct config from that url.
Here the problem comes.
I have a WCF service working under IIS and I want to add one more endpoint to it. For example let it be a net.tcp endpoint. The IIS is configured by default to accept net.tcp connections at port 808 and I'm adding net.tcp protocol to properties of my web app, and I want to add an endpoint to my service like that:
<endpoint address=""
binding="netTcpBinding"
contract="wcf_service_auth.IPshService" />
and now I assume that my service should be accessible via the url net.tcp://localhost:808/psh_pub/pshservice.svc. But it's not. And every "how-to" and manual on the web tells that I should specify full address in the config file like that:
<endpoint address="net.tcp://localhost:808/psh_pub/pshservice.svc"
binding="netTcpBinding"
contract="wcf_service_auth.IPshService" />
And if I do so, it works. But if host the service in another virtual directory, I'll need to change the config. If I host it on the other server, I'll need to change config. If I host it on multiple servers, I'll have to maintain as many configs as servers I have.
So the main questions is:
Is there any way in WCF to specify a net.tcp (or https) endpoint of a IIS-hosted WCF service without specifying absolute url for it?
You should be able to define a base address for your net.tcp service endpoints:
<service name="YourServiceName">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:808/psh_pub/" />
</baseAddresses>
</host>
Then you should be able to use relative addresses in your actual endpoints:
<endpoint name="Tcp01"
address="pshservice.svc"
binding="netTcpBinding"
contract="wcf_service_auth.IPshService" />
</service>
WCF file-less activation (.Net 4.0) will let you register under a relative virtual path using the relativeAddress attribute:
<system.serviceModel>
<serviceHostingEnvironment>
<serviceActivations>
<add relativeAddress="relative-virtual-path/yourservice.svc"
service="YourServiceImpl" />
</serviceActivations>
</serviceHostingEnvironment>
</system.serviceModel>
relative to the base address of the Web application
This link talks about it: http://msdn.microsoft.com/en-us/library/ee354381.aspx

Hosting WCF service in IIS 7 (WAS) with net.tcp binding on TWO tcp ports

By default IIS 7 Web site has net.tcp binding with "808:" binding information string. If i add another net.tcp binding with "xxx:" exception occurs:
This collection already contains an address with scheme net.tcp. There can be at most one address per scheme in this collection.
Parameter name: item
How can i solve this problem and listen my service at TWO ports?
Basically, in your service, you should be able to define any number of service endpoints on any number of ports.
There's two ways to do this:
define a base address and a relative address in your service endpoint
define the full address in each endpoint
If you do option #1, you'll have something like this:
<service name="YourService">
<host>
<baseAddresses>
<add baseAddress="net.tcp://YourServer:5151/Services" />
</baseAddresses>
</host>
<endpoint name="endpoint1"
address="Service1"
binding="netTcpBinding"
contract="IYourService" />
<endpoint name="endpoint2"
address="Service2"
binding="netTcpBinding"
contract="IYourService" />
</service>
So in this case, you have two service endpoints for the same contract, and they'll be listening on URLs
net.tcp://YourServer:5151/Services/Service1
and
net.tcp://YourServer:5151/Services/Service2
You can have mulitple service endpoints, but only one base address.
The other option is to specify no base addresses and specify your full service address in the endpoint directly:
<service name="YourService">
<endpoint name="endpoint1"
address="net.tcp://YourServer:5151/Services/Service1"
binding="netTcpBinding"
contract="IYourService" />
<endpoint name="endpoint2"
address="net.tcp://YourServer:6868/Services/Service2"
binding="netTcpBinding"
contract="IYourService" />
</service>
In this case, since you're defining the whole address in the endpoint, you can pick two different TCP ports, one for each endpoint. This should work with no problem at all. You have two separate endpoints on two separate ports, both listening and being serviced by the same service class in the background.
Marc
I was trying to deply a WCF service to one of my web servers the other day and ran into a problem. I kept getting the following error message:p>
This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.Parameter name: item
The problem didn't happen on my local machine but did on the web server making it a little difficult to figure out what was causing it. It happened on the server because my web server is in a shared hosting environment in which case the WCF service also needs to know the host header. To do this I navigated to in the web.config and added the following:
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix=http://MyHostHeader />
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
Its me again.
This works with self host
<baseAddresses>
<add baseAddress="net.tcp://localhost" />
<add baseAddress="net.tcp://localhost:12345" />
</baseAddresses>
but with IIS7+WAS cause exception
Could not connect to net.tcp://localhost:12345/game2.svc. The connection attempt lasted for a time span of 00:00:02.0936160. TCP error code 10061: No connection could be made because the target machine actively refused it 127.0.0.1:12345.
The question was about IIS hosting environment