WCF Service Timeout - Service Takes Minutes to respond to simple request - performance

We have a simple service configured as such:
<configuration>
<connectionStrings>
<add name="CONN" connectionString="Server=MYSERVER,1433;Database=mydb;User Id=user;Password=pass;"/>
</connectionStrings>
<system.web>
<customErrors mode="Off"/>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<services>
<service name="MyNamespace.MyService">
<host>
<baseAddresses>
<add baseAddress="https://mywebsite.com/TestService/"/>
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" contract="MyNameSpace.IMyService" bindingConfiguration="defaultBinding" bindingNamespace="MyNameSpace"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="defaultBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferPoolSize="2147483647"
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
The service was timing out before I added the additional arguments to binding name="defaultBinding" (closeTimeout, openTimeout, receiveTimeout, sendTimeout, maxbuffersize, maxreceivedmessagesize).
Our server has only TLS1.2 enabled.
The service is hosted in IIS and certificates seem to be okay - browsing the WSDL in the web looks okay.
Using SOAPUI on the same machine machine as the service is hosted times out (I assume this would be really quick?)
Is there a web config setting I am not aware of or does this come down to the server machine or possibly IIS?
Requests can take minutes to complete - even simple ones like a GetVersion() call that just returns a string. We even rebooted the machines, IIS, etc. and tried new requests - same issue.

Turns out my GetVersion() call actually had a LogActivity() call that would log to the database. The connection string in web.config was incorrect causing the database connection to spin until the database connection times out. The database connection timeout is set higher than the timeout for the service/client so the client would timeout before the database timeout occurred. The database connection timeout happens silently as there is no need to log a failed logging attempt for us.
Fixing the connection string has the service responding quickly.
Moral of the story: Double check your functions - even if they seem simple they might be doing some other stuff under the hood :)

Related

WCF Test Service cannot add service

I'm using Visual Studio for a school project and I'm to create a simple WCF Service Application web service that I need to test using WCF Test Client.
I developed the service, but then when I run the debugger, it opens a web browser, I copy the link to the IService1.svc file, and try to add that to the test client, and it fails complaining it cannot get meta data.
I tried this on a fresh solution with a new project, and same thing.
My Web.config file:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.8.1" />
<httpRuntime targetFramework="4.8.1"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Am I missing any steps in testing the web services?
Depending on your wcf configuration file, you can see the parts without endpoints and service contracts. You may have missed the <service.model> section:
<services>
<service name="Namespace.Service1">
<endpoint address="" binding="basicHttpBinding" contract="Namespace.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>

WCF service And Linq

I am using LINQ in a WCF service. I am trying to list all my movies in a grid but my query wont work.
any of you know why?
this is the query:
public List<MovieInfo> GetAllMovies()
{
var queryResult = (from x in db.MovieInfos
select x);
return queryResult.ToList();
}
This is the webconfig:
<configuration>
<connectionStrings>
<add
name="dmaa0913Sem3_1ConnectionString"
connectionString="Data Source=dbname;Initial Catalog=dataname;Persist Security Info=True;User ID=username;Password=password"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
here is the error i get:
Failed to invoke the service. Possible causes: The service is offline
or inaccessible; the client-side configuration does not match the
proxy; the existing proxy is invalid. Refer to the stack trace for
more detail. You can try to recover by starting a new proxy, restoring
to default configuration, or refreshing the service.
The service is online, because i use WCF test client.
I have solved the problem. The query that i use for extracting data from the database i somthing called lazyloading. And WCF have trouble working with this kind of query if the data that need's to be extracted is to complex. It is somthing about how WCF service serialize the service. So what i did to make it work was to go in the Linq datacontex and set the. Serialization Mode to Unidirectional. This worked for me.

Slow invoking of WCF service

So my issue is kinda simple but can't figure out how to deal with it.
I am using a wcf service which is accessing database through ADO.NET Entity Framework and after that I use this service to get the data in windows phone 7 application. The problem is when I call a simple select * from table the data gets populated in my WP7 for like 6-7 seconds which seems to me kinda long. I can post the web.config if needed but I havent changed much from what was generated from VS.
Anyone had the same issue or know how to deal with that?
I put my web.config, I thik problem should be there maybe.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings />
<client />
<services>
<service name="WcfServiceForWinMobile.Service1" behaviorConfiguration="serviceBehavior">
<endpoint address="" binding="basicHttpBinding" contract="WcfServiceForWinMobile.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://89.215.65.163/WcfServiceForWinMobile/Win7MobileService.svc" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled="true" />
</system.webServer>
<system.web>
<compilation debug="true">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
</system.web>
<connectionStrings><add name="CompanyEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=xetyccwqk6.database.windows.net;initial catalog=Company;persist security info=True;user id=company;password=Plovdiv12345;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" /></connectionStrings></configuration>

wcf service - test with url to call method does not work and remotely

I created a WCF service that returns a line of text and using a client application tested it and was able to retrieve the line of text. I thought that if I put the entire url in a browser that includes the method that returns the line of text it would work but instead I get a 400 not found error.
For example the main url is :
http://localhost/DataAdmin/GService.svc?wsdl
So when I try to past the following in a browser it does not work:
http://localhost/DataAdmin/GService.svc/RetrieveData?inputText=test
Oh, the reason for this is that I am trying to test it remotely. I want an app to be able to call the service from another server/domain.
I'm thinking it has something perhaps to do with the config files. Here is the config file of my service project.
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
It is not as simple as that. WCF works with the SOAP protocol, you can't 'just' pass the method name and the value in the Url.
You can use a Restfull-API, I am referring you to this awsome post that tells all about it in a simple and concise manner.

WCF Hosted as Service

I have a VB.NET WCF service hosted as a Window Service. I was able to create an install package, install the service to my machine, and start the service manually from Services in Administrative Tools.
Now when I try to reference the service in my test console application (Address: http://localhost:8080/), I get the following error:
There was an error downloading 'http://localhost:8080'.`
Unable to connect to the remote
server No connection could be made
because the target machine actively
refused it 127.0.0.1:8080`
Metadata contains a reference that
cannot be resolved:
'http://localhost:8080/'. Could not
connect to http://localhost:8080/. TCP
error code 10061: No connection could
be made because the target machine
actively refused it 127.0.0.1:8080.
Unable to connect to the remote server
No connection could be made because
the target machine actively refused it
127.0.0.1:8080 If the service is defined in the current solution, try
building the solution and adding the
service reference again.
Not sure what I can do about this. Any ideas???
Thanks,
Jason.
Here's the code from app.config inside my service:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<sources>
<!-- This section defines the logging configuration for My.Application.Log -->
<source name="DefaultSource" switchName="DefaultSwitch">
<listeners>
<add name="FileLog"/>
<!-- Uncomment the below section to write to the Application Event Log -->
<!--<add name="EventLog"/>-->
</listeners>
</source>
</sources>
<switches>
<add name="DefaultSwitch" value="Information" />
</switches>
<sharedListeners>
<add name="FileLog"
type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
initializeData="FileLogWriter"/>
</sharedListeners>
</system.diagnostics>
<system.serviceModel>
<services>
<service name="ExStreamWCF.Service1"
behaviorConfiguration="ExStreamWCF.Service1Behavior">
<!-- Service Endpoints -->
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8080/Design_Time_Addresses/JasonsService/Service/" />
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="ExStreamWCF.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ExStreamWCF.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
If anyone needs more from me please let me know!
Not sure if it's really an issue - but on a production server, I would never use localhost as my base address.
So can you try to change:
<service name="ExStreamWCF.Service1"
behaviorConfiguration="ExStreamWCF.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8080/Design_Time_Addresses/JasonsService/Service/" />
</baseAddresses>
</host>
to
<service name="ExStreamWCF.Service1"
behaviorConfiguration="ExStreamWCF.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress = "http://YourServerName:8080/Design_Time_Addresses/JasonsService/Service/" />
</baseAddresses>
</host>
Does that make any difference when calling into the service??

Resources