Ensure download was completed - c#

I am using a for loop in which Webclient class Downloadstring() method is used to load a external url .
The Url has been provided by SMS service provider in which Mobile number and the message to be transmitted is added.
But message is not being submitted to SMS gateway for all mobile numbers specified in phNos[] array ie downloading Url is skipped for some numbers . This occurs mostly for mobile numbers at end of array.
How can I ensure that program waits until url is loaded for particular number and then the program progresses forward.
WebClient cli = new WebClient();
for (i=0;i<phNos.Length;i++)
{
string url = #"http://example.com?DestNo=" + phNos[i] + "&msg=" + message;
cli.DownloadString(url);
}
Alternately I have also used System.Net.HttpWebRequest but the problem persist.
for (i=0;i<phNos.Length;i++)
{
string url = #"http://example.com?DestNo=" + phNos[i] + "&msg=" + message;
Uri targetUri = new Uri(url);
HttpWebRequest hwb = (HttpWebRequest)HttpWebRequest.Create(targetUri);
System.Net.HttpWebResponse response = hwb1.GetResponse();
int status = (int)response.StatusCode;
if (status == 200)
{
Response.Write("Successfully transmitted" + status);
}
}
Is there any other alternative method to ensure message is submitted 100 %.

Your code looks fine. DownloadString is blocking and if an error occurs it should raise an exception. How does the SMS gateway respond to your request? You should have a look at their documentation, because probably you can write a function that tests whether everything worked fine or not.
const int MAX_RETRY = 10;
WebClient cli= new WebClient();
for(i=0;i<phNos.Length;i++)
{
url = #"http://aaa.bbb.ccc.ddd?DestNo=" + phNos[i] + "&msg=" + message;
int cntRetry = 0;
while (!TestResult(cli.DownloadString(url)) && cntRetry < MAX_RETRY)
++cntRetry;
}
The problem could be that you are submitting too many requests to the gateway in a very short time. You could try to put some Thread.Sleep(1000) calls somewhere and see if things get any better.
WebClient cli= new WebClient();
for(i=0;i<phNos.Length;i++)
{
Thread.Sleep(1000);
url = #"http://aaa.bbb.ccc.ddd?DestNo=" + phNos[i] + "&msg=" + message;
cli.DownloadString(url);
}
You could also combine the two above examples, using maybe lower values for MAX_RETRY and Thread.Sleep.
const int MAX_RETRY = 5;
WebClient cli= new WebClient();
for(i=0;i<phNos.Length;i++)
{
url = #"http://aaa.bbb.ccc.ddd?DestNo=" + phNos[i] + "&msg=" + message;
int cntRetry = 0;
while (!TestResult(cli.DownloadString(url)) && cntRetry < MAX_RETRY) {
Thread.Sleep(500);
++cntRetry;
}
}

I would instantiate a webclient for every call and dispose it after downloadstring is called, like so
foreach(var phone in phNos)
{
using(WebClient cli= new WebClient())
{
url = String.Format(#"http://aaa.bbb.ccc.ddd?DestNo={0}&msg={1}", phone, message);
string result = cli.DownloadString(url);
// check if result has somekind of errorreport maybe?
Trace.WriteLine(result); // optionally write it to a trace file
}
}
Getting it disposed explicitely might help in also closing underlying networkconnections more quickly because I suspect the sheer number of connections are causing the issue. Throttling might also be an option (send less calls to the gateway per minute)
If this are 10000 or 100000 calls the network components between you and the sms gateway can be the culprit. Think off adsl modems/vpn software/routing issues or even the sms-gateway itself.
If that still doesn't resolve the issue: try Fiddler and or Wireshark to deeply inspect http traffic or even tcp/ip traffic.

Related

authorization error using linqtotwitter for streaming api

i'm trying to get a stream of tweets using LinqToTwitter library and the below c# code, but i get this error:
Error 401 Unauthorized
public static SingleUserAuthorizer auth;
static void Main(string[] args)
{
Task task = new Task(getStreamOfTweets);
task.Start();
task.Wait();
Console.ReadLine();
}
static async void getStreamOfTweets()
{
auth = new SingleUserAuthorizer
{
CredentialStore = new SingleUserInMemoryCredentialStore
{
ConsumerKey = CUSTOMER_KEY,
ConsumerSecret = CUSTOMER_SECRET,
AccessToken = ACCESS_TOKEN,
AccessTokenSecret = ACCESS_TOKEN_SECRET
}
};
var context = new TwitterContext(auth);
int count = 0;
await (from strm in context.Streaming
where strm.Type == StreamingType.Filter
&& strm.Track == "federer"
select strm)
.StartAsync(async strm =>
{
string message =
string.IsNullOrEmpty(strm.Content) ?
"Keep-Alive" : strm.Content;
Console.WriteLine(
(count + 1).ToString() +
". " + DateTime.Now +
": " + message + "\n");
if (count++ == 5)
strm.CloseStream();
});
}
notes:
the permission in twitter app is "Read, Write and Access direct messages"
i can get tweet by REST API correctly
Please review the LINQ to Twitter FAQ, which has an extensive section on resolving 401 errors. That said, if it's working for the REST API, but not Streaming, that might narrow the options to try. Here are a couple things to try first:
Double check the keys to make sure you didn't accidentally add a space or lose a character on the ends.
Give a little time before trying again because sometimes too many accesses or failed attempts might cause them to deny your connection for a certain period of time.
Re: #2, try another stream, like Sample.
There are a lot of moving parts in play for using OAuth, so work through that list in case you might have missed something.
this issue happens because the time of windows was wrong.
If you copied & pasted from the Linq"Twitter sample code, make sure you have set properly all the keys:
ConsumerKey
ConsumerSecret
AccessToken
AccessTokenSecret
Then dont use "Application only" auth, use "user auth" instead for streaming which uses all of the above keys.
the issue was because the timing in PC was wrong

IP data lookup - C#

Okay, so I've googled on several occasions regarding this, but each one suggests respectfully decent choices like : "Selenium" which works fine, but isn't use-able without firefox (or even within an API to my knowledge?).
I have this code :
public byte[] GetFileViaHttp(string url)
{
using (WebClient client = new WebClient())
{
return client.DownloadData(url);
}
}
Then I also have this code :
byte[] result = GetFileViaHttp(#"http://ip-lookup.net/");
string str = Encoding.UTF8.GetString(result);
richTextBox1.Text = str;
Works fine, returns my IP's information, but I want to automate this with other IP addresses, rather than return my own.
How would this be done ?
By this I mean, I want the API to take txtBox1.Text (IP) & print the details into richTextBox1.Text (Host/Country) ..
How could this be done ?
I looked around the site and found a help document that details exactly what you want.
Simply pass the IP value as an unnamed query string parameter:
http://ip-lookup.net/?127.0.0.1
In your code:
byte[] result = GetFileViaHttp(string.Format("http://ip-lookup.net?{0}", ipAddress));
where you are injecting a string ip address as ipAddress.
You can find their help page here. I looked for a legal agreement but I wasn't able to find one, so please use at your own risk and discretion.
UPDATE:
If you are getting 403s, you need to pass along a user agent header. Your WebClient instance can be modified to include a header in the request.
public byte[] GetFileViaHttp(string url)
{
using (WebClient client = new WebClient())
{
client.Headers.Add("User-Agent: Other");
return client.DownloadData(url);
}
}

C# AWS SQS Read all messages without deleting

I want to read all messages from queue in AWS SQS without deleting them , using C# , but I am only getting the single last message.
Here is the code
ReceiveMessageRequest rmr = new ReceiveMessageRequest();
rmr.QueueUrl = url;
rmr.MaxNumberOfMessages = 10;
AmazonSQSClient sq = new AmazonSQSClient("xx", "yy");
ReceiveMessageResponse rmrep = sq.ReceiveMessage(rmr);
ReceiveMessageResult rmres = rmrep.ReceiveMessageResult;
//DeleteMessageRequest dmr = new DeleteMessageRequest();
string msgid = "";
string rephandle = "";
XmlDocument xl = new XmlDocument();
for (int i = 0; i < rmres.Message.Count;i++ )
{
rmrep = sq.ReceiveMessage(rmr);
rmres = rmrep.ReceiveMessageResult;
object y = JsonConvert.DeserializeObject<object>(rmres.Message[0].Body);
int z= y.add();
MessageBox.Show(z.ToString());
}
A queue is not a database table; you can't just 'read all the messages'. You tell SQS you want some messages, it picks some and sends them to you; you can't ask it, or expect it, to iterate thru a unique list of messages in the queue and present them to you, it is not intended for that purpose.
If you read 1 or messages, and delete them (or put them in another queue), then eventually you can 'read all the messages', but as long as you don't delete any, its likely that you will keep getting served back some messages multiple times.
You are calling receive message multiple times and thus are not seeing some of your messages. Change your code to something like this:
AmazonSQSClient sq = new AmazonSQSClient("xx", "yy");
while (true)
{
ReceiveMessageRequest rmr = new ReceiveMessageRequest();
rmr.QueueUrl = url;
rmr.MaxNumberOfMessages = 10;
ReceiveMessageResponse response= sq.ReceiveMessage(rmr);
foreach (Message message in response.ReceiveMessageResult.Message)
{
MessageBox.Show(message.ReceiptHandle + ": " + message.Body);
}
}
NOTE: If there are enough messages in the queue (the number depends on the queue and is not documented), you will not be able to receive any more because you will reach your maximum number of in-flight messages.
Another NOTE: If this runs longer than your visibility timeout you will start receiving the same messages again.

Load URL in for loop in C#

I am sending a message to multiple phone numbers .
Mobile numbers are stored in an array .
string phNums = "91999999999,9199999998....";.
string[] phNos = phNums.Split(',');
But message doesn't reach all of the recipients , mostly to the numbers that are present near end of array.
The message are sent via a URL provided by SMS service provider in which the phone number and the message is embedded.
for (int i = 0; i < phNos.Length; i++)
{
url = #"http://aaa.bbb.ccc.dd/HTTPMTAPI?User=abc&Password=pqr&FromAddr=xyzSMS&DestNo=" + phNos[i] + "&msg=" + message;
Uri targetUri1 = new Uri(url);
System.Net.HttpWebRequest hwb1;
hwb1 = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(targetUri1);
hwb1.GetResponse();
}
As an alternate , I also used Webclient() but still successful message delivery is not guaranteed.
for (int i = 0; i < phNos.Length; i++)
{
WebClient cli= new WebClient();
url = #"http://aaa.bbb.ccc.dd/HTTPMTAPI?User=abc&Password=pqr&FromAddr=xyzSMS&DestNo=" + phNos[i] + "&msg=" + message;
cli.DownloadString(url);
}
How to ensure that message delivery is not skipped .
Like only if successful response is received on downloading the URL , the loop should progress to next mobile number and so on.
If there is any other possible mechanism , please do suggest. Thanks
I think this is what you want to do:
for (int i = 0; i < phNos.Length; i++)
{
url = #"http://aaa.bbb.ccc.dd/HTTPMTAPI?User=abc&Password=pqr&FromAddr=xyzSMS&DestNo=" + phNos[i] + "&msg=" + message;
Uri targetUri1 = new Uri(url);
System.Net.HttpWebRequest hwb1;
hwb1 = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(targetUri1);
System.Net.HttpWebResponse response = hwb1.GetResponse();
if (response != null)
{
int status = (int)response.StatusCode; // this changes the status
// from text response to the
// number, like 404
if (status == 404//or anything else you want to test//)
{
// put your retry logic here, make sure you add a way to break
// so you dont infinitely loop if the service is down or something
}
}
}
URLs have a length constraint. Your are likely hitting this limit and your are losing the trailing phone numbers as a result. Your best bet would be to break your requests into multiple requests of a certain size.
According to the following SO, it may be good practice to limit your request so that the url does not surpass 2000 characters.
What is the maximum length of a URL in different browsers?

Weird Error when using SOAP Web Service

For a school project, I have to create a Java Server that is able to service a .NET client that has a Service Reference to a WSDL. I have the .NET Client code:
using (var client = new MathServiceWSDLClient())
{
Console.WriteLine("Multiplying " + Num1 + " and " + Num2 + ": " + client.Multiply(Num1, Num2));
Console.WriteLine("Adding" + Num1 + " and " + Num2 + ": " + client.Add(Num1, Num2));
}
I have also written the Java Server:
Scanner sc = new Scanner(socket.getInputStream());
boolean clientExpectContinue = false;
int contentLength = -1;
String line;
while (!(line = sc.nextLine()).isEmpty()) {
System.out.println(line);
if (line.startsWith("Content-Length")) {
String[] elements = line.split(": ");
contentLength = Integer.parseInt(elements[1]);
} else if (line.startsWith("Expect")) {
clientExpectContinue = true;
}
}
int notEmpties = 0;
byte[] soapEnvelopeData = new byte[contentLength];
char[] soapChars = new char[contentLength];
for (int i = 0; i < contentLength; i++) {
soapChars[i] = (char) socket.getInputStream().read();
if (i == 0)
System.out.println("DFSDFSDf");
}
// System.out.println(socket.getInputStream().read(soapEnvelopeData));
System.out.println(soapEnvelopeData.length);
File file = new File("tempEnvelope.txt");
FileOutputStream fileOut = new FileOutputStream(file);
// fileOut.write(soapEnvelopeData);
System.out.println("Content!");
System.out.println(new String(soapChars));
fileOut.write(new String(soapChars).getBytes());
fileOut.flush();
fileOut.close();
/* Some fancy SOAP and Reflection stuff that works */
The gist of the server is as follows:
It gets the incomming request, reads through the headers and finds the content length. It parses and saves this. From here there are two versions. The first constructs a byte array the same size as the content length, and passes the array as a parameter into the socket.getInputStream().read() method. The second constructs a char array the same length of the content and then reads individual bytes from the stream and casts them to chars.
The issue comes into play when, as shown, I attempt to run the .NET client with multiple requests in one execution. The first request goes off without any sort of discernible issue. When the second one comes in, the server reads the headers, gets the content length and constructs the array. When it comes time to read from the socket, however, the program just waits. Using the char array method, I was able to learn that it waits when reading the first value. Once one minute has expired, .NET times out, and the rest of the program breaks.
If, however, I leave the server running, and only have one request per execution of the .NET client, everything is just fine; the response comes back just as it should.
I have tried some solutions already:
Creating a new MathServiceWSDLClient for every request
Putting every request in its own using() block.
Doing two of the same request at once: two Multiply() or Add() requests.
Any help is appreciated. Thank you all in advance.
~Ryno Janse van Rensburg
.net is probably keeping the socket open for subsequent requests. There may be a bug in your server-like java code related to this.
Are you able to use a framework instead for the Java server code? I would strongly recommend this, and recommend rmbedded Jetty without hesitation. This would mean you wouldn't have to work at the socket level in Java - you can let Jetty handle all of that complication.

Categories