I have the following code (the important bits):
while(true){
BrokeredMessage message = subscriptionClient.Receive();
if (message.Properties.ContainsKey("MessageType"))
{
try
{
SmsService.Instance.SendSms("lenio", user.PhoneNumber, SomeString);
}
catch (Exception ex)
{
throw;
}
}
}
The code runs continuously and the message I receive is handled and SomeString is just some string.
The SmsService class looks like this:
public class SmsService
{
private const string Username = "******";
private const string Password = "******";
private static SmsService _instance = null;
private static readonly Lazy<SmsService> lazy =
new Lazy<SmsService>(() => new SmsService());
private SmsService() { }
public static SmsService Instance
{
get
{
return lazy.Value;
}
}
public bool SendSms(string from, string receiver, string message)
{
string url = UrlBuilder(from, receiver, message);
HttpWebRequest newRequest = (HttpWebRequest)WebRequest.Create(url);
HttpStatusCode statusCode = new HttpStatusCode();
try
{
HttpWebResponse response = (HttpWebResponse)newRequest.GetResponse();
statusCode = response.StatusCode;
}
catch (WebException we)
{
statusCode = ((HttpWebResponse)we.Response).StatusCode;
}
if (statusCode == HttpStatusCode.OK)
{
Logger.Instance.AddToLog(0, "SMS", "Sms Send to: +" + receiver);
return true;
}
else
{
Logger.Instance.AddToLog(0, "SMS", "Failed to send sms to: +" + receiver);
return false;
}
}
public string NewLine()
{
return "%0a";
}
private static string UrlBuilder(string from, string to, string message)
{
string newTo = "45" + to;
string encodedMessage = message.Replace(" ", "+");
string encodedfrom = from.Replace(" ", "+");
return "http://sms.sms1290.dk/?username=" + Username + "&password=" + Password + "&to=" + newTo + "&from=" + encodedfrom + "&message=" + encodedMessage;
}
}
I have a problem that sometimes, if I receive a lot of messages I get a "Object reference not set to an instance of an object." exception on SmsService. I sometimes also get an "operation timed out" on:
HttpWebResponse response = (HttpWebResponse)newRequest.GetResponse();
I have made a gist with more code if needed: https://gist.github.com/Niclassg/54b908fbf5cc9b3e11a7
Stacktrace on "operation timed out":
> lenioServiceBus.exe!lenioServiceBus.SmsService.SendSms(string from, string receiver, string message) Line 44 C#
lenioServiceBus.exe!lenioServiceBus.Program.AlarmDeactivated(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 489 C#
lenioServiceBus.exe!lenioServiceBus.Program.msgHandler(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 109 C#
lenioServiceBus.exe!lenioServiceBus.Program.Main(string[] args) Line 59 C#
[External Code]
Line 44:
catch (WebException we)
{
statusCode = ((HttpWebResponse)we.Response).StatusCode; //<-- Line 44
}
Line 489:
if (user.NotifyBySms)
{
Console.WriteLine("Notify user : " + user.Name + " by phone on number: " +
user.PhoneNumber);
string msg = "Alarmen i dit hus er nu deaktiveret. ";
SmsService.Instance.SendSms("lenio", user.PhoneNumber, msg); //<-- Line 489
//Notify user! (alarm now deactive)
}
else
{
Console.WriteLine("Notify user: " + user.Name + "on smartphone");
//Notify user! (alarm now deactive)
}
Line 59:
if (msgHandler(message)) //<-- Line 59
{
Logger.Instance.SaveLog();
try
{
message.Complete();
}
catch (Exception ex)
{
//We might have lost the lock on the message and were too slow to handle it! (Use RenewLock)
}
}
else
{
Logger.Instance.SaveLog();
message.Abandon();
}
The operation timed out exception always follows with nullexception that has this stacktrace:
> lenioServiceBus.exe!lenioServiceBus.Program.AlarmDeactivated(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 507 C#
lenioServiceBus.exe!lenioServiceBus.Program.msgHandler(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 109 C#
lenioServiceBus.exe!lenioServiceBus.Program.Main(string[] args) Line 59 C#
[External Code]
Line 507:
catch (Exception ex) //the ex contains the "{"Object reference not set to an instance of an object."} exception
{
Logger.Instance.AddToLog(2, "AlarmDeactivate", "Failed to deactivate alarm on communicationdevice: " + message.Properties["cdId"] + " with exception: " + ex.Message); //<--Line 507
return false;
}
I found out I get this error if I send a message before the other message has completed. I need a solution for this.
If the remote host did not return a response, then the we.Response on line 44 is null, so the attempt to read the StatusCode property will fail (with "object ref not set").
You will need to change your exception handling (line 44) to not always assume that the WebException has a Response.
Perhaps something like:
statusCode = HttpStatusCode.ServiceUnavailable; // set a default
...
try
{
...
}
catch (WebException we)
{
if (we.Response != null)
{
statusCode = ((HttpWebResponse)we.Response).StatusCode;
}
}
You say: "The operation timed out exception always follows with nullexception that has this stacktrace"
The service you are communicating with is limited to processing one request at a time. Whether intentional or not, you probably cannot do anything to "fix" that. My best thought at this time would be a simple lock around the communication in the SendSms() method, so that you only allow one request to communicate at a time. This will probably introduce scalability issues, but would certainly be better than simply failing.
Related
I've created a Arduino + windows 10 app. The microcontroller connects with a Wi-Fi module (ESP8266-ESP01), tcp/ip protocol. The module is the server and app is the client. The module works fine and I tested it on another program ("SocketTest v3.0"). It sends and receives data. But my app can only write data, the socket.InputStream doesn't work. When I read data, it throws an error.
What am I doing wrong?
Maybe there is an example like this program:
.
public sealed partial class MainPage : Page
{
StreamSocket _socket;
HostName _hostName;
DataWriter writer;
public MainPage()
{
this.InitializeComponent();
_socket = new StreamSocket();
}
private async void connectButton_Click(object sender, RoutedEventArgs e)
{
#region _check_parameters
if (String.IsNullOrEmpty(hostName_Box.Text))
{
_statusBar.Text += "[ERROR] Set the Host Name !!!\n";
return;
}
if (String.IsNullOrEmpty(serviceName_Box.Text))
{
_statusBar.Text += "[ERROR] Set the Service Name !!!\n";
return;
}
try
{
_hostName = new HostName(hostName_Box.Text);
}
catch (Exception)
{
_statusBar.Text += "[ERROR] Invalid Host Name !!!\n";
return;
}
#endregion
// If necessary, tweak the socket's control options before carrying out the connect operation.
// Refer to the StreamSocketControl class' MSDN documentation for the full list of control options.
_socket.Control.KeepAlive = false;
try
{
_statusBar.Text += "Connecting...\n";
await _socket.ConnectAsync(_hostName, serviceName_Box.Text);
_statusBar.Text += "Connected\n";
// go to send mode
connectButton.Content = "Send";
connectButton.Click -= connectButton_Click;
connectButton.Click += send_Data;
hostName_Box.PlaceholderText = "data to send";
hostName_Box.Text = "";
writer = new DataWriter(_socket.OutputStream);
}
catch(Exception exception)
{
// If this is an unknown status it means that the error is fatal and retry will likely fail.
if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
_statusBar.Text += "[ERROR] Connect failed with error:\n" + exception.Message + "\n";
}
}
private async void read_data()
{
DataReader dataReader = new DataReader(_socket.InputStream);
dataReader.InputStreamOptions = InputStreamOptions.Partial;
try
{
await dataReader.LoadAsync(dataReader.UnconsumedBufferLength);
string s;
uint length;
length = dataReader.ReadUInt32();
s = dataReader.ReadString(length);
_statusBar.Text += "Read successful\n" + s + "\n";
}
catch (Exception exception)
{
_statusBar.Text += "[ERROR] Fail to load dada !!!\n" +
exception.Message + "\n";
}
}
private async void send_Data(object sender, RoutedEventArgs e)
{
if (String.IsNullOrEmpty(hostName_Box.Text))
{
_statusBar.Text += "Write anything\n";
return;
}
if(hostName_Box.Text == "read")
{
try
{
hostName_Box.Text = "";
read_data();
return;
}
catch (Exception ex)
{
_statusBar.Text += "[ERROR] Reading data failed:\n" + ex.Message + "\n";
}
}
writer.WriteUInt32(writer.MeasureString(hostName_Box.Text));
writer.WriteString(hostName_Box.Text);
try
{
await writer.StoreAsync();
_statusBar.Text += "\"" + hostName_Box.Text + "\" sent successfully\n";
hostName_Box.Text = "";
}
catch(Exception ex)
{
if (SocketError.GetStatus(ex.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
_statusBar.Text += "[ERROR] Send failed with error:\n" + ex.Message + "\n";
}
}
}
Maybe my reading function is not so good, but the error is that in every situation
dataReader.UnconsumedBufferLength == 0;
and when I use:
int length = dataReader.ReadInt32();
it throws an exception.
The first error is that the dataReader.UnconsumedBufferLength == 0. And the function .LoadAsync(...) throws the error.
DataReader.UnconsumedBufferLength is used to get the size of the buffer that has not been read. You haven't loaded any data from the input stream to the intermediate buffer before you called dataReader.UnconsumedBufferLength, so the value is 0. And the parameter of DataReader.LoadAsync cannot be zero, so you got a System.ArgumentException: The parameter is incorrect.
If I send a string "qwerty" and do dataReader.LoadAsync(6) it throws --> "The operation attempted to acces data outside the valid range"
This exception is thrown by the code s = dataReader.ReadString(length);, you need to call await dataReader.LoadAsync(length); to load the string data into the buffer before you can read it.
Following is the sample code I have verified:
private async void read_data()
{
DataReader dataReader = new DataReader(_socket.InputStream);
dataReader.InputStreamOptions = InputStreamOptions.Partial;
try
{
//load some data to the buffer first
await dataReader.LoadAsync(4);
//read int data
uint length = dataReader.ReadUInt32();
//load data to the buffer before reading it.
uint acturalStringLength = await dataReader.LoadAsync(length);
//read string data
string s = dataReader.ReadString(acturalStringLength);
_statusBar.Text += "Read successful\n" + s + "\n";
}
catch (Exception exception)
{
_statusBar.Text += "[ERROR] Fail to load dada !!!\n" +
exception.Message + "\n";
}
}
I want to create a service for Wifi Direct. If I try to add Reference, I don't see core->windows option in VS2013. I have updated the winSDK.
How do I add the Windows.Devices.WifiDirect api ?
you can use
public sealed class WiFiDirectDevice : IDisposable
this is a sample code to handle connections
Windows.Devices.WiFiDirect.WiFiDirectDevice wfdDevice;
private async System.Threading.Tasks.Task<String> Connect(string deviceId)
{
string result = "";
try
{
// No device Id specified.
if (String.IsNullOrEmpty(deviceId)) { return "Please specify a Wi- Fi Direct device Id."; }
// Connect to the selected Wi-Fi Direct device.
wfdDevice = await Windows.Devices.WiFiDirect.WiFiDirectDevice.FromIdAsync(deviceId);
if (wfdDevice == null)
{
result = "Connection to " + deviceId + " failed.";
}
// Register for connection status change notification.
wfdDevice.ConnectionStatusChanged += new TypedEventHandler<Windows.Devices.WiFiDirect.WiFiDirectDevice, object>(OnConnectionChanged);
// Get the EndpointPair information.
var EndpointPairCollection = wfdDevice.GetConnectionEndpointPairs();
if (EndpointPairCollection.Count > 0)
{
var endpointPair = EndpointPairCollection[0];
result = "Local IP address " + endpointPair.LocalHostName.ToString() +
" connected to remote IP address " + endpointPair.RemoteHostName.ToString();
}
else
{
result = "Connection to " + deviceId + " failed.";
}
}
catch (Exception err)
{
// Handle error.
result = "Error occurred: " + err.Message;
}
return result;
}
private void OnConnectionChanged(object sender, object arg)
{
Windows.Devices.WiFiDirect.WiFiDirectConnectionStatus status =
(Windows.Devices.WiFiDirect.WiFiDirectConnectionStatus)arg;
if (status == Windows.Devices.WiFiDirect.WiFiDirectConnectionStatus.Connected)
{
// Connection successful.
}
else
{
// Disconnected.
Disconnect();
}
}
private void Disconnect()
{
if (wfdDevice != null)
{
wfdDevice.Dispose();
}
}
So I am making a bot that connects to a twitch irc chat. Here is the code:
Console.WriteLine("Joining Room");
IrcClient irc = new IrcClient("irc.twitch.tv", 6667, "ScottBots", "oauth:asdasd");
irc.joinRoom("ScottBots");
Console.WriteLine("Joined Room");
int i = 0;
while (true)
{
string message = irc.readMessage();
if(message.Contains("!helps"))
{
irc.sendChatMessage("Welcome to ScottBots! Currently in development.");
}
Console.WriteLine("loop: " + i);
i++;
}
Look the the while true loop... Everything good?
Now look at what this console application gives me:
Joining Room
Joined Room
loop: 0
loop: 1
loop: 2
loop: 3
loop: 4
loop: 5
loop: 6
loop: 7
loop: 8
loop: 9
It just stops at 9?
Many of ya'll have been asking for my ircClient Code:
private string username;
private string channel;
private TcpClient tcpClient;
private StreamReader inputStream;
private StreamWriter outputSteam;
public IrcClient(string ip, int port, string username, string password)
{
this.username = username;
tcpClient = new TcpClient(ip, port);
inputStream = new StreamReader(tcpClient.GetStream());
outputSteam = new StreamWriter(tcpClient.GetStream());
try
{
outputSteam.WriteLine("PASS " + password);
outputSteam.WriteLine("NICK " + username);
outputSteam.WriteLine("USER " + username + " 8 * :" + username);
outputSteam.Flush();
} catch (Exception e)
{
}
}
public void joinRoom(string channel)
{
try
{
this.channel = channel;
outputSteam.WriteLine("JOIN #" + channel);
outputSteam.Flush();
}
catch (Exception e)
{
Console.WriteLine("Failed to join room");
}
}
public void sendIrcMessage(string message)
{
try
{
outputSteam.WriteLine(message);
outputSteam.Flush();
}
catch (Exception e)
{
Console.WriteLine("failed to run sendIrcMessage() method");
}
}
public void sendChatMessage(string message)
{
sendIrcMessage(":" + username + "!" + username + "#" + username + ".tmi.twitch.tv PRIVNSG #" + channel + " : " + message);
}
public string readMessage()
{
string message = inputStream.ReadLine();
return message;
}
It looks like one of irc.SendChatMessage() or irc.ReadMessage() is blocking, perhaps when it runs out of buffered input/output and needs to wait on the socket.
EDIT: Almost certainly the irc.ReadMessage() call is blocking. It's calling ReadLine() against a Stream which is in turn linked to a TcpClient. You probably want to look into either threading and/or asynchronous callbacks if you want to build an IRC bot and test rig. Here's an example (not IRC-related): http://sunildube.blogspot.ca/2011/12/asynchronous-tcp-client-easy-example.html
I am working on a project in which I have to send and recieve SMS via GSM modem in C# using AT commands. I am done with the sending part but having trouble reading sms from the sim card.
I have tried the following code and get the following response:
OK
OK
ERROR.
The code for reading the SMS is :-`
public bool ReadSms()
{
//string buffer = string.Empty;
if (this.serialPort.IsOpen == true)
{
try
{
this.serialPort.WriteLine("AT");
Thread.Sleep(2000);
this.serialPort.WriteLine("AT+CMGF=1" + (char)(13));
Thread.Sleep(3000);
this.serialPort.WriteLine("AT + CMGL = ALL" + (char)(26));
Thread.Sleep(5000);
string a = this.serialPort.ReadExisting();
MessageBox.Show(a);
}
catch (Exception ex)
{
MessageBox.Show(ex.Source);
}
return true;
}
else
return false;
}
public void Opens()
{
if(this.serialPort.IsOpen == false)
{
this.serialPort.Open();
}
}
public void Closes()
{
if (this.serialPort.IsOpen == true)
{
this.serialPort.Close();
}
}
`
replace your this line "this.serialPort.WriteLine("AT + CMGL = ALL" + (char)(26));"
with this one this.serialPort.WriteLine("AT+CMGL=\"ALL\"" + (char)(13));
i hope you will not get the error.
replace the line
this.serialPort.WriteLine("AT");
with
this.serialPort.WriteLine("AT" + (char)(13));
and change 26 to 13
Is it possible to return a bool and also rethrow an exception within the same method? Ive tried with the following code and it keeps saying that unreachable code is detected or that i cant exit the finally block.
public bool AccessToFile(string filePath)
{
FileStream source = null;
try
{
source = File.OpenRead(filePath);
source.Close();
return true;
}
catch (UnauthorizedAccessException e)
{
string unAuthorizedStatus = "User does not have sufficient access privileges to open the file: \n\r" + filePath;
unAuthorizedStatus += e.Message;
MessageBox.Show(unAuthorizedStatus, "Error Message:");
throw;
}
catch (Exception e)
{
string generalStatus = null;
if (filePath == null)
{
generalStatus = "General error: \n\r";
}
else
{
generalStatus = filePath + " failed. \n\r";
generalStatus += e.Message;
}
MessageBox.Show(generalStatus, "Error Message:");
throw;
}
finally
{
if (source != null)
{
source.Dispose();
}
}
}
Once you throw an exception, processing in your current method finishes and the exception works up the call stack. Either handle your exceptions locally and then return your boolean, or throw them and let them bubble up and handle them at the front end.