Connect to a single WCF service with two different endpoint bindings - wcf

I am new to WCF and (I hope) I'm having a "noob" problem. I searched the site and did not find the answer I'm looking for. I apologize if this has already been answered and I missed it.
I am programmaticly connecting to my service using a ChannelFactory. The problem I'm having is that the client cannot connect to my first service endpoint, unless I comment out the second one (the MSMQ one). Hopefully that helps.
The contracts are different, and I'm specifying the correct bindings (WSDualHttpBinding and NetMsmqBinding, respectively) on the client-side.
Please let me know if there is a way to fix this, or if more information is required.
I appreciate the help.
Tyler
<services>
<service behaviorConfiguration="DefaultBehavior" name="[intentionally removed]">
<endpoint
address="[intentionally removed]"
behaviorConfiguration="DefaultEndpointBehavior"
binding="wsDualHttpBinding"
bindingConfiguration="DualBinding"
name="WrapperEndpoint"
contract="[intentionally removed]"
/>
<endpoint
address="[intentionally removed]"
behaviorConfiguration="DefaultEndpointBehavior"
binding="netMsmqBinding"
bindingConfiguration="MsmqBinding"
name="MsmqEndpoint"
contract="[intentionally removed]"
/>
</service>
</services>

This topic might be related: http://social.msdn.microsoft.com/Forums/is/wcf/thread/643371b4-00a7-472b-8bea-3055f2eb90ed
I don't think you can have a single service with 2 different contracts. I think when you have both endpoints, WCF is just failing to start up properly, but when you comment out 1 endpoint, then it works fine because all endpoints share the same contract.
WCF is also going to try to define a WSDL for the service (not per endpoint) based off the contract, but if the service has more than 1 contract, it won't know what to do.
The proper thing to do would be to split this into 2 services.
Edit:
On the other hand, this article indicates that having a service with multiple endpoints with different contracts works just fine, so perhaps I am wrong.
Hmmm....

Related

WCF / WebService to act as Listener for MQ Message?

Perhaps I am barking up the wrong tree - but I have a set of services (WebAPI and WCF) that use WebSphere MQ to interact with other systems.
This works without issue - until I now need to find a way of listening for messages on one of the queues.
Is this even possible, or do I need to go down the windows Service route?
You could write a Windows service that is continually calling MQ Get on the queue, and invokes a WCF service to process the message. Or you could write a trigger program (a console application) that MQ will launch for you when a message arrives, that invokes the WCF service.
I might be just better at googling than you are, but I seem to have found the answer here.
Seems you want to load the IBM binding configuration in you app.config
<extensions>
<bindingElementExtensions>
<add name="IBM.XMS.WCF.SoapJmsIbmTransportChannel"
type="IBM.XMS.WCF.SoapJmsIbmTransportBindingElementConfig, IBM.XMS.WCF, Version=7.5.0.0, Culture=neutral, PublicKeyToken=8c7c0be90afcd8ba"/>
</bindingElementExtensions>
</extensions>
Then you can add a WebSphere WCF binding config.
<bindings>
<customBinding>
<binding name="CustomBinding_WMQ">
<textMessageEncoding messageVersion="Soap11" />
<IBM.XMS.WCF.SoapJmsIbmTransportChannel />
</binding>
</customBinding>
</bindings>
Your problem can be broken down into two distinct elements:
How to integrate MQ with a WCF-supported transport
How to expose a WCF endpoint over this transport
To address the first issue, you should look at the MQ-MSMQ bridge which ships with Host Integration Server up to version 2009 (not R2), which allows you to have messages delivered to MQSeries queues forwarded to local MSMQs in windows. Although this feature is deprecated it's probably the easiest way if you have a MSDN license.
Another way of addressing this issue is to use BizTalk server which ships with a MQSeries adapter, though unless you're using BizTalk currently in your enterprise I would avoid.
The last way you could do this is to program directly against the MQSeries .NET client libraries or via the XMS client.
If you manage to solve the first issue then solving the second one is easy enough. You can expose one way WCF service operations over msmq transport by using the netMsmqBinding (for WCF on both ends), or msmqIntegrationBinding for clients using System.Messaging or native msmq COM libraries.
This in-effect acts as a listener service, with messages being handled by the service operation.
how to get connect with ibm websphere mq by using c#.net
Perhaps you could use the above answer and within that queue consumer app create a "Service Reference" to your WCF service.

getting Contract requires TwoWay (either request-reply or duplex) error

I am having WCF subscriber for MSMQ which is installed as windows service.I have attached a IErrorhandler as well.So i needed to make it OneWay= false in service contract.Now when I am starting the windows service I am getting bellow errro:-
Service cannot be started. System.InvalidOperationException: Contract requires TwoWay (either request-reply or duplex), but Binding 'MsmqIntegrationBinding' doesn't support it or isn't configured properly to support it.
at System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff, ServiceHostBase serviceHost, Uri listenUri, ListenUriMode listenUriMode, Boolean supportContextSession, IChannelListener& result)
I am new to WCF..
please help me.how to configure MsmqIntegrationBinding for duplex.
my app.config section is below:-
<msmqIntegrationBinding>
<binding name="OrderProcessorBinding" maxRetryCycles="0" receiveErrorHandling="Move"
receiveRetryCount="3" retryCycleDelay="00:00:59">
<security mode="None" />
</binding>
</msmqIntegrationBinding>
The fact that you are using queueing means that conceptually your client and server are disconnected. If you want to report exceptions back to the client you may want to re-visit your architecture to make sure you really want to use queueing.
This question on Stack Overflow discusses the options available for dealing with exceptions if you do decide to go down the MSMQ route: How do I handle message failure in MSMQ bindings for WCF
There are advanced workarounds for a request-reply type behaviour over MSMQ, one is given in Lowy's excellent "Programming WCF Services book".

Problem adding service reference to a WCF service hosted in a windows service

I am building a WCF service interface for an existing Windows service process. The purpose of the WCF interface is to provide an "Command Channel" to implement an administrative capability for the Windows Service. There are several OperationContract methods defined that are intended to extract information from and control the behaviour of the Windows service far beyond the Start/Stop/Pause capability of the Services applet.
This WCF service is intended to be part of the existing process. As such, running the WCF service in IIS or ServiceHost is not an option.
My problem is that although the ServiceHost does not throw an error on Open(), I cannot get "WCF Test Client" (or anyting else) to find the service.
This is my first WCF Service, and have had trouble finding examples or patterns that fit what I am trying to do. So I have no illusions and would not be suprised if I did many things wrong. Also, not that I have 'portSharingBinding=false'. I did have that on but it was throwing an error that pointed to another service that I do not wish to run.
Is port sharing required?
Config information:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="PortBinding" portSharingEnabled="false" />
</netTcpBinding>
</bindings>
<services>
<service name="NameChanged.ServiceManager.CommandService">
<endpoint address="net.tcp://localhost"
binding="netTcpBinding"
bindingConfiguration="PortBinding"
name="ServiceManagerCommandChannel"
contract="NameChanged.ServiceManager.ICommandService" />
</service>
</services>
</system.serviceModel>
I also tried the no config route using the following code:
ServiceHost host = new ServiceHost(typeof(CommandService)))
host.AddServiceEndpoint(typeof(ICommandService),
new NetTcpBinding(), "net.tcp://localhost:8000");
host.Open();
Also, no error on the Open(). But, no success connecting to the service.
Thanks for your time,
Jim
I can only speak to the WCF Test Client, but it is looking for the metadata for your service so it can generate a proxy for it. From the above configuration, it does not appear that you are exposing a metadata exchange endpoint. Take a look at this link for more info:
http://weblogs.asp.net/fabio/archive/2009/02/28/net-tcp-mex-endpoints-and-portsharing-in-wcf.aspx
You can access your service without using exposed metatdata to generate a proxy, but it will require you to manually create channels to do so:
http://msdn.microsoft.com/en-us/library/ms734681.aspx

Determine wsHttpBinding at runtime with WCF

I have a web application that exposes web services using WCF and wsHttpBindings. It is possible to have the application on different machines and different urls. This would mean the WCF service location would be different for each.
I am building a Windows Service that will reference each application and perform a task. Each task needs to call a service on the web application. I understand that the bindings are all setup in the app.config, but is there a simpler way to call the service dynamically, or how would I structure the app.config?
<webApplication WebServiceUrl="http://location1.com/LunarChartRestService.svc" />
<webApplication WebServiceUrl="http://location2.com/LunarChartRestService.svc"/>
Your client's config file could look something like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint name="Endpoint1"
address="http://location1.com/LunarChartRestService.svc"
binding="wsHttpBinding"
contract="(whatever-your-contract-is)" />
<endpoint name="Endpoint2"
address="http://location2.com/LunarChartRestService.svc"
binding="wsHttpBinding"
contract="(whatever-your-contract-is)" />
<endpoint name="Endpoint3"
address="http://location3.com/LunarChartRestService.svc"
binding="wsHttpBinding"
contract="(whatever-your-contract-is)" />
</client>
</system.serviceModel>
</configuration>
Then in code, you can create such an endpoint (client proxy) based on its name and thus you can pick whichever location you need. There's nothing stopping you from creating multiple client proxies, either! So you can connect to multiple server endpoints using multiple client proxies, no problem.
Alternatively, you can of course also create an instance of "WsHttpBinding" and "EndpointAddress" in code, and set the necessary properties (if any), and then call the constructor for the client proxy with this ready made objects, thus overriding the whole app.config circus and creating whatever you feel is needed:
EndpointAddress epa =
new EndpointAddress(new Uri("http://location1.com/LunarChartRestService.svc"));
WSHttpBinding binding = new WSHttpBinding();
Marc
From your description, it sounds as if all servers are exposing the same service contract. If so, you could very well just declare multiple endpoints in your web.config and choose one at runtime based on the endpoint name.
Of course, it may be that you prefer not to deal with that part of the WCF configuration and would rather just have a simpler list of URLs and be done with it. That's perfectly possible as well; you just need to do a little bit more work on the code side to instantiate the client side proxies / channel objects.

I want to log the Poison message that my wcf service is dropping using MSMQ 3.0 and windows 2003

I want to log the Poison message that my wcf service is dropping using MSMQ 3.0 and windows 2003
You can implement a custom IErrorHandler and associate it with your service using a custom behavior. In your implementation, check if the exception raised is of type MsmqPoisonMessageException, and if so, go out and grab the message from the queue using System.Messaging,MessageQueue and log it.
There's a sample that shows how most of this stuff is done: it moves the message to another queue, but should be trivial to modify it so that it just logs the message somewhere instead.
There is a perfect example for this on MSDN.
http://msdn.microsoft.com/en-us/library/ms751472.aspx
You could probably add a service like the following that reads messages from your poison queue and logs them.
<service name="YourPosionMessageHandler"
<endpoint
address="net.msq://localhost/private/YourServiceQueue;poison"
binding="netMsmqBinding"
/>
</service>