WCF Client Performance - wcf

I used WCF to call a Java based web service and constantly get 1.4 second or 1.5 second response time. I used exactly same SOAP request in SoapUI to call the same web service and constantly get 0.9 second to 1 second response time.
Both requests are initiated from my local computer, both requets hit same target.
It is very hard for me to believe it will take 0.5 second to serialize and deserialize, but other than this what else can impact the performance?
Update 1 - included sample code
Stopwatch sw = new Stopwatch();
//Trust all certificates, non-production uses self-signed certificate
System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
MyServiceClient.MyService.Spml2ServicePortTypeClient client = new MyServiceClient.MyService.Spml2ServicePortTypeClient();
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password";
for (int i = 0; i < 5; i++)
{
MyServiceClient.MyService.SuggestUserIDRequestType webRequest = new MyServiceClient.MyService.SuggestUserIDRequestType();
webRequest.requestID = "MyId";
webRequest.givenName = "Hardy";
webRequest.sn = "Wang";
webRequest.uid = "some value";
sw.Start();
MyServiceClient.MyService.SuggestUserIDResponseType response = client.suggestUserID(webRequest);
sw.Stop();
Console.WriteLine("Elapsed time {0} ms.", sw.ElapsedMilliseconds);
sw.Reset();
}

Related

PKCE flow Error code: 500 code challenge required

I'm trying to get the PKCE example to work, but I keep hitting
Error code: 500
Error: invalid_request : code challenge required
Here's a sample url, it does include a code_challenge param generated with the example code.
https://login.xero.com/identity/connect/authorize
?client_id=XXX
&response_type=code
&scope=openid%20profile%20email%20offline_access%20files%20accounting.transactions%20accounting.contacts&redirect_uri=https%3A%2F%2Flocalhost%3A5001%2F
&code_challenge=tj6n3SLd6FZ8g6jjSJYvfC--4r2PHGnpbSGTwIreNqQ
&code_challenge_method=S256
The registered app is a PKCE flow, kind of out of options what it could be.
Here's the code I use, the only changes are the last 2 lines where I launch the browser a I'm connecting from a desktop app. Tried pasting the generated url into the browser directly but that also didn't work.
XeroConfiguration xconfig = new XeroConfiguration();
xconfig.ClientId = "XXX";
xconfig.CallbackUri = new Uri("https://localhost:5001"); //default for standard webapi template
xconfig.Scope = "openid profile email offline_access files accounting.transactions accounting.contacts";
//xconfig.State = "YOUR_STATE"
var client = new XeroClient(xconfig);
// generate a random codeVerifier
var validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~";
Random random = new Random();
int charsLength = random.Next(43, 128);
char[] randomChars = new char[charsLength];
for (int i = 0; i < charsLength; i++) {
randomChars[i] = validChars[random.Next(0, validChars.Length)];
}
string codeVerifier = new String(randomChars);
var uri = client.BuildLoginUriPkce(codeVerifier);
Clipboard.SetText(uri);
System.Diagnostics.Process.Start("explorer.exe", $"\"{uri}\"");

How to make an API Call every second using ESP8266?

I tried making a HTTP request to my localhost that is running Laravel Api.
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(url + "update"); //request destination
http.addHeader("Content-Type", "application/x-www-form-urlencoded"); //content-type header
String stringData = "payload=" + data;
int httpCode = http.POST(stringData);
String payload = http.getString();
Serial.print(httpCode);
http.end();
}
delay(2000);
}
When I reduce delay value <= 2000, nodeMCU is not performing as expected.
While testing getting 429 error.
Please suggest an alternative that can update every second.
429 Too Many Requests "indicates the user has sent too many requests in a given amount of time". The server could be slow, or rate limited.
The server may send a Retry-After header; if it does, it tells you how long you have to wait before a new request is made.
I suspect you would have to change things on the server side to make it as fast as you want; I doubt the ESP8266 is to blame.
Note that if handling a request takes longer than 1s, you're out of luck anyway.
BTW could you try the code below and see if it works? Just to rule out some other potential problems. It removes the inefficient delay() and only does HTTPClient http; once.
HTTPClient http;
unsigned long int lastPost = 0;
int postInterval = 1000; // Post every second
void setup() {
// Setup stuffs
}
void loop() {
if (WiFi.status() == WL_CONNECTED && (millis() - lastPost) >= postInterval) {
http.begin(url + "update"); //request destination
http.addHeader("Content-Type", "application/x-www-form-urlencoded"); //content-type header
String stringData = "payload=" + data;
int httpCode = http.POST(stringData);
String payload = http.getString();
Serial.print(httpCode);
http.end();
lastPost = millis();
}
}
Untested, just typed it in, but you get the idea.

.Net Core 2.0 timeout for WCF web service in c#

I am doing a .NET Core 2.0 App. I am calling a webService. I added a Reference to a local Service and call it from my Application.
ServiceReference1.QueryCalendarClient servicio = null;
ServiceReference1.ListCalendarDayTypeRequest request = new ServiceReference1.ListCalendarDayTypeRequest();
ServiceReference1.ListCalendarDayTypeResponse response = null;
var binding = new BasicHttpBinding();
binding.ReceiveTimeout = new TimeSpan(0, 25, 0);
binding.SendTimeout = new TimeSpan(0, 25, 0);
binding.MaxBufferSize = 2147483647;
binding.MaxReceivedMessageSize = 2147483647;
binding.Security = new BasicHttpSecurity
{
Mode = BasicHttpSecurityMode.TransportCredentialOnly,
Transport = new HttpTransportSecurity()
{
ClientCredentialType = HttpClientCredentialType.Basic
}
};
servicio = new ServiceReference1.QueryCalendarClient(binding, new EndpointAddress("http://WebBasica?wsdl"));
servicio.ClientCredentials.UserName.Password = "123456789";
servicio.ClientCredentials.UserName.UserName = "user";
response = new ServiceReference1.ListCalendarDayTypeResponse();
response = servicio.Method(request.CalendarInquireRequest_MT).Result;
I have an time Out Exception.
The request channel timed out while waiting for a reply after
00:24:58.3211575. Increase the timeout value passed to the call to
Request or increase the SendTimeout value on the Binding. The time
allotted to this operation may have been a portion of a longer
timeout.
Any timeOut I set, gave me a TimeOut error...
Where can I set the time out?
What I am missing?
Thank

C# "The request was aborted: Could not create SSL/TLS secure channel." - happening occasionally

This is a request to GoCardless test API from a Dynamics CRM plugin. I receive "The request was aborted: Could not create SSL/TLS secure channel." error. It only happens on the first request after some time without sending one. If I send it again, it will be OK. I would appreciate a lot your help.
Here is my code:
//I have tried all the following lines in comment without success
//ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
//ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
//ServicePointManager.Expect100Continue = true;
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
// Create a new WebClient instance.
string baseURL = "https://api-sandbox.gocardless.com/";
WebClient client = new WebClient();
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("Authorization", "Bearer " + t);
client.Headers.Add("GoCardless-Version", "2015-07-06");
client.Headers.Add("Accept", "application/json");
Customers model = new Customers();
customer.country_code = "GB";
model.customers = customer;
MemoryStream stream1 = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Customers));
ser.WriteObject(stream1, model);
stream1.Position = 0;
StreamReader sr = new StreamReader(stream1);
// Apply ASCII Encoding to obtain the string as a byte array.
byte[] byteArray = Encoding.ASCII.GetBytes(sr.ReadToEnd());
ReturnedCustomers result = new ReturnedCustomers();
//Upload the input string using the HTTP 1.0 POST method.
try
{
byte[] responseArray = client.UploadData(baseURL + "customers", "POST", byteArray);
string responseText = Encoding.ASCII.GetString(responseArray);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ReturnedCustomers));
using (Stream s = GenerateStreamFromString(responseText))
{
result = (ReturnedCustomers)serializer.ReadObject(s);
}
}
catch (WebException exception)
{
}
From the Microsoft documentation (https://msdn.microsoft.com/en-us/library/gg334752.aspx) are the following limitations:
Only the HTTP and HTTPS protocols are allowed.
Access to localhost (loopback) is not permitted.
IP addresses cannot be used. You must use a named web address that requires DNS name resolution.
Anonymous authentication is supported and recommended.
5.There is no provision for prompting the logged on user for credentials or saving those credentials.
The error may be due to seguneti things:
The certificate is invalid
The certification authority is not public
Could you check what is the value of ServicePointManager.Expect100Continue and ServicePointManager.SecurityProtocol attributes in your environment?

Why isn't Opc.Ua.UserIdentity sending the password cleanly to the OPC server?

I have a problem with the UserIdentity(user, password) constructor.
My password is 4 characters long. When the password arrives at the server it is 36 characters long. The first 4 characters are my password - the rest is random garbage.
The Opc.Ua.Client.dll & Opc.Ua.Core.dll have version 1.0.238.1.
What is causing this and what can I do to send the password correctly?
UPDATE
ApplicationConfiguration configuration = Helpers.CreateClientConfiguration();
X509Certificate2 clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find();
configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
EndpointDescription endpointDescription = Helpers.CreateEndpointDescription(Url);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);
endpointConfiguration.OperationTimeout = 300000;
endpointConfiguration.UseBinaryEncoding = true;
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
BindingFactory bindingFactory = BindingFactory.Create(configuration);
if (endpoint.UpdateBeforeConnect)
{
endpoint.UpdateFromServer(bindingFactory);
endpointDescription = endpoint.Description;
endpointConfiguration = endpoint.Configuration;
}
SessionChannel channel = SessionChannel.Create(
configuration,
endpointDescription,
endpointConfiguration,
bindingFactory,
clientCertificate,
null);
m_Session = new Session(channel, configuration, endpoint);
m_Session.ReturnDiagnostics = DiagnosticsMasks.All;
m_Session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);
m_Session.Notification += new NotificationEventHandler(m_Session_Notification);
UserIdentity identity;
if (userName == null || userName.Length == 0)
{
identity = new UserIdentity();
}
else
{
identity = new UserIdentity(userName, password);
}
m_Session.Open("ATF UA client", identity);
log.Debug("Connect ok");
The rest is not garbage at all. It shall be the same ServerNonce you sent to the OPC UA Client in the CreateSessionResponse.
According to OPC UA specification the UserIdentityToken encrypted format is :
Length - Byte[4] => The length of your password
TokenData - Byte[*] => Your password
ServerNonce - Byte[*]
The password is 36 bytes long because OPC UA Server mainly use 32bytes ServerNonce and your password is 4 bytes long...
You should also verify that the ServerNonce sent with that UserIdentityToken is the same as the one you provide in your CreateSessionResponse.