I'm loading an host with a service called Service which implement the contract IService.
The binding is WSDualHttpBinding.
var host = new ServiceHost(typeof(Service));
host.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
host.AddServiceEndpoint(typeof(IService),new WSDualHttpBinding()
,endPointAddress);
In the client side i am trying to discover the endpoint.
EndpointAddress address = new EndpointAddress(new Uri(string.Format("http://{0}:{1}/Service/Client/Discovery", Environment.MachineName, "1111")));Environment.MachineName, 1111);
DiscoveryClient client =
new DiscoveryClient(new DiscoveryEndpoint(new WSDualHttpBinding(), address));
FindResponse find = client.Find(new FindCriteria(typeof(IService))
{ Duration = TimeSpan.FromSeconds(3) });
It is not working... I get a timeout exception after a minute without any reason.
i am running the host and the client on the same machine.
does anyone can detect what the problem is?
thanks
Related
I coded a WCF Service using HttpTransportBindingElement in conjunction with IIS on port 80.
The code works fine as long as no proxy is used. But if a customer has a http-proxy the communication between WCF-Client and Server does not work in this case by occuring following error:
'There was no endpoint listening at ... that could accept the message. This is often caused by an incorrect address or SOAP action.'
It is essential to use settings by code ONLY!
here is my code approach for that issue but i stuck on it:
bool SendClientRequest(Action<ICustomerService> channel)
{
string proxy ="my.proxy.domain:8080";
string user = "user1";
string password="secret";
// maybe i do not need this 3 lines!
WebProxy webproxy = new WebProxy(proxy, true);
webproxy.Credentials = new NetworkCredential(user, password);
WebRequest.DefaultWebProxy = webproxy;
CustomBinding customBinding = new CustomBinding();
customBinding.Elements.Add(new HttpTransportBindingElement()
{
AuthenticationSchemes.None : AuthenticationSchemes.Basic,
ProxyAddress = string.IsNullOrEmpty(proxy) ? null : new Uri(proxy),
UseDefaultWebProxy = false,
BypassProxyOnLocal = true,
TransferMode = TransferMode.Streamed,
MaxReceivedMessageSize = 84087406592,
MaxBufferPoolSize = 0x1000000,
MaxBufferSize = 0x1000000
});
using (ChannelFactory<ICustomerService> factory = new
ChannelFactory<ICustomerService>(customBinding ))
{
IClientChannel contextChannel = null;
string url = "http://my.domain.de/Distribution/eService.svc",
EndpointAddress ep = new EndpointAddress(url);
ICustomerService clientChannel = factory.CreateChannel(ep);
contextChannel = clientChannel as IClientChannel;
contextChannel.OperationTimeout = TimeSpan.FromMinutes(rcvTimeout );
channel(clientChannel); // <- here i get the exception!
return true;
}
}
I tried several solution approaches but nothing seems to be specific like mine.
I think you have a few options, some of which I'll detail below.
First you could set UseDefaultWebProxy to true. This would then mean that proxy information is retrieved automatically from system proxy settings, configurable in Internet Explorer (Internet Options > Connections > LAN settings > Proxy server). This may be appropriate if you don't need to specify credentials for proxy use.
Another approach that's worked for me is to use the ProxyAuthenticationScheme property within your HttpTransportBindingElement() object. This property is only available on the CustomBinding class and allows an authentication scheme to be specified that will be used to authenticate against a proxy. In conjunction with this, the proxy server must be set against property ProxyAddress. Last but not least, the credentials to use against the proxy should be set according to the authentication scheme used, so for example, using AuthenticationSchemes.Ntlm would mean setting the UserName and Password properties on ChannelFactory.ClientCredentials.Windows.ClientCredential or perhaps ChannelFactory.ClientCredentials.HttpDigest.ClientCredential
With the second approach, be sure to note the difference between holding credentials in the ChannelFactory for use with the remote service versus credentials used for the proxy server. I've highlighted these in the code example below for clarity:
// Example service call using a CustomBinding that is configured for client
// authentication based on a user name and password sent as part of the message.
var binding = new CustomBinding();
TransportSecurityBindingElement securityBindingElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
var secureTransport = new HttpsTransportBindingElement();
secureTransport.UseDefaultWebProxy = false;
secureTransport.ProxyAddress = new Uri("http://some-proxy");
secureTransport.ProxyAuthenticationScheme = AuthenticationSchemes.Ntlm;
binding.Elements.Add(securityBindingElement);
binding.Elements.Add(secureTransport);
var endpointAddress = new EndpointAddress("https://some-service");
var factory = new ChannelFactory<IService>(binding, endpointAddress);
// Credentials for authentication against the remote service
factory.Credentials.UserName.UserName = "serviceUser";
factory.Credentials.UserName.Password = "abc";
// Credentials for authentication against the proxy server
factory.Credentials.Windows.ClientCredential.UserName = "domain\user";
factory.Credentials.Windows.ClientCredential.Password = "xyz";
var client = factory.CreateChannel();
client.CallMethod();
I am trying to call a web service on my server over https from my mvc3 app. I have web services located at this address:
https:localhost/web_services/web_services.asmx
And in my code i try to connect like this:
var binding = new BasicHttpsBinding();
binding.maxbuffersize = 10000;
binding.maxbufferPoolsize = 10000;
binding.maxreceivedmessageSize= 10000;
binding.Security.Mode = System.ServiceModel.BasicHttpsSecurityMode.Transport;
binding.Security.Transport.ClientCredentialsType = HttpClientCredentialType.Certificate
var endpointAddress = new EndpointAddress("https:/localhost/web_services/web_services.asmx");
new ChannelFactory<ws_name_webreqSoap>(basicHttpsBinding, endpointAddress).CreateChannel();
var webServices = new ws_name_webreqSoapClient(basicHttpsBinding, endpointAddress);
However, when this runs on the server, i get the following message:
"The client certificate is Not provided. Specify a client certificate in client credentials"
My knowledge of HTTPS and certificates is limited. Does anyone know a solution to this?
Thanks,
You can specify the client certificate on the ChannelFactory:
var channelFactory = new ChannelFactory<ws_name_webreqSoap>(basicHttpsBinding, endpointAddress);
channelFactory.Credentials.ClientCertificate.SetCertificate("CN=client.com", StoreLocation.CurrentUser, StoreName.My);
var channel = channelFactory.CreateChannel();
// ...
I need to develop a WCF Hosted in a console app WebService.
I made it work using the Mutual Certificate (service and client) method using SecurityMode.Message.
But now i need to change the Security Mode to SecurityMode.Transport and use the wsHttpBinding with SSL. I made this code to host the service but i cannot get the wsdl with the browser, or execute some webmethod in the console app client.
static void Main()
{
var httpsUri = new Uri("https://localhost:8089/HelloServer");
var binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var host = new ServiceHost(typeof(WcfFederationServer.HelloWorld), httpsUri);
host.AddServiceEndpoint(typeof(WcfFederationServer.IHelloWorld), binding, "", httpsUri);
var mex = new ServiceMetadataBehavior();
mex.HttpsGetEnabled = true;
host.Description.Behaviors.Add(mex);
// Open the service.
host.Open();
Console.WriteLine("Listening on {0}...", httpsUri);
Console.ReadLine();
// Close the service.
host.Close();
}
The service is up, but i cannot get nothing on the https://localhost:8089/HelloServer.
On fiddler the get request via browser shows me this message:
fiddler.network.https> HTTPS handshake to localhost failed. System.IO.IOException
What im missing here?
Thanks
EDIT:
The Console Application Client Code
static void Main()
{
try
{
var client = new HelloWorldHttps.HelloWorldClient();
client.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.TrustedPeople,
X509FindType.FindBySubjectName,
"www.client.com");
Console.WriteLine(client.GetData());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
Getting this error:
Could not establish trust relationship for the SSL/TLS secure channel
When it comes to the service, you need to map the certificate to the specific port as described here
http://msdn.microsoft.com/en-us/library/ms733791(v=vs.110).aspx
As for the client, you need to skip the verification of certificate properties like valid date, the domain by relaxing the certificate acceptance policy. An easiest way would be to accept any certiticate
ServicePointManager.ServerCertificateValidationCallback = (a,b,c,d) => true
You can finetune the acceptance callback according to the docs to best fit your needs.
My WCF servers work like this: You subscribe to them by calling a service method, say Subscribe(). They send you results back on a callback channel, say MessageReceived(string message).
My issue right now is that I am only getting callback messages from one service endpoint, not both. In fact, just by debugging I see that my second service doesn't even get requests. Does anyone know what the problem is? Here is my code (note that I have two net.tcp addresses in the serviceAddresses string):
private void StartAggregatorHost(List<string> serviceAddresses)
{
// Create a new service host for the routing service (note that RoutingService is a pre-defined Microsoft service model type which routes SOAP messages).
aggregatorHost = new ServiceHost(typeof(RoutingService));
// Set up the router address. A logger client will now connect to this address to get logged messages.
string fqdn = System.Net.Dns.GetHostEntry("localhost").HostName;
string routerAddress = string.Format("net.tcp://{0}:2099/LogAggregator", fqdn);
// Set up our router binding.
NetTcpBinding routerBinding = new NetTcpBinding(SecurityMode.None, true);
routerBinding.SendTimeout = new TimeSpan(0, 1, 0);
routerBinding.ReceiveTimeout = new TimeSpan(25, 0, 0);
routerBinding.MaxReceivedMessageSize = int.MaxValue;
routerBinding.MaxConnections = int.MaxValue;
routerBinding.ListenBacklog = int.MaxValue;
routerBinding.ReliableSession.Enabled = true;
routerBinding.ReliableSession.Ordered = true;
routerBinding.ReliableSession.InactivityTimeout = new TimeSpan(15, 0, 0, 0);
// Define the type of router in use. For duplex sessions like in our case, we want to use the IDuplexSessionRouter.
Type contractType = typeof(IDuplexSessionRouter);
// Add the endpoint that the router will use to recieve and relay messages. Note the use of System.ServiceModel.Routing.IDuplexSessionRouter.
aggregatorHost.AddServiceEndpoint(contractType, routerBinding, routerAddress);
// Create the endpoint list that contains the service endpoints we want to route to.
List<ServiceEndpoint> endpointList = new List<ServiceEndpoint>();
foreach (string serverAddress in serviceAddresses)
{
// Set up our server binding(s) for each server.
NetTcpBinding serverBinding = new NetTcpBinding(SecurityMode.None, true);
serverBinding.SendTimeout = new TimeSpan(0, 1, 0);
serverBinding.ReceiveTimeout = new TimeSpan(25, 0, 0);
serverBinding.MaxReceivedMessageSize = int.MaxValue;
serverBinding.MaxConnections = 1;
serverBinding.ListenBacklog = int.MaxValue;
serverBinding.ReliableSession.Enabled = true;
serverBinding.ReliableSession.Ordered = true;
serverBinding.ReliableSession.InactivityTimeout = new TimeSpan(15, 0, 0, 0);
// Create the server endpoint the router will route messages to and from.
ContractDescription contract = ContractDescription.GetContract(contractType);
ServiceEndpoint server = new ServiceEndpoint(contract, serverBinding, new EndpointAddress(serverAddress));
// Add the server to the list of endpoints.
endpointList.Add(server);
}
// Create a new routing configuration object.
RoutingConfiguration routingConfiguration = new RoutingConfiguration();
// Add a MatchAll filter to the Router's filter table. Map it to the endpoint list defined earlier. When a message matches this filter, it will be sent to the endpoint contained in the list.
routingConfiguration.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
// Attach the behavior to the service host.
aggregatorHost.Description.Behaviors.Add(new RoutingBehavior(routingConfiguration));
// Open the service host.
aggregatorHost.Open();
m_eventLog.WriteEntry(string.Format("Log aggregator service hosted at {0}.", routerAddress), EventLogEntryType.Information);
}
So once again...this is what I want:
CLIENT ---REQ---> ROUTER ---REQ---> SVC1
---REQ---> SVC2
CLIENT <---CALLBACK1--- ROUTER <---CALLBACK1--- SVC1
<---CALLBACK2--- <---CALLBACK2--- SVC2
This is what I'm getting (even though I added the second service to my router it seems it doesn't even call its service methods):
CLIENT ---REQ---> ROUTER ---REQ---> SVC1
CLIENT <---CALLBACK--- ROUTER <---CALLBACK--- SVC1
You should set a specific priority adding SVC1 & SVC2 to the FilterTable.
routingConfiguration.FilterTable.Add(new MatchAllMessageFilter(), new List<YourServiceType> { yourService }, 1);
Further info here.
i had created dynamic endpoint in server side and that endpoint used by client side.
Server side Code:
for (int i = 1; i <= 3; i++)
{
host.AddServiceEndpoint(typeof(PokerService.IPlayerService),
new NetTcpBinding(),
#"net.tcp://localhost:5054/player" + i);
}
Client side:
NetTcpBinding binding = new NetTcpBinding(SecurityMode.Message);
binding.Name = "NetTcpBinding_IPlayerService";
binding.Security.Message.ClientCredentialType = MessageCredentialType.IssuedToken;
EndpointAddress myEndpointAdd = new EndpointAddress(new Uri("net.tcp://localhost:5054/player1"),
EndpointIdentity.CreateDnsIdentity("pident.cloudapp.net"));
var PlayerChannelFactory = new DuplexChannelFactory<ClientApplication.PlayerService.IPlayerService>(new PlayerHandler(handler, this), binding, myEndpointAdd);
but it give error in this following line :
Player loggedIn = PlayerServiceProxy.Login("testuser" + Guid.NewGuid().ToString());
The error is:
"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 '00:00:59.9870000'."
have anyone idea?
It seems like timeout. Review your client and service timeouts configuration.
Also, try to use svcTraceViewer.exe to review wcf trace