I want to refresh a label on a page without reloading the page.
The page is used to send SMSs. Because I am using a GSM modem connected to a COM port, it is quite a slow process taking about 3 seconds per text. (There's a lengthy reason why I'm using a serial GSM modem, not an online service or USB connection.)
Multiple numbers can be specified, delimited by ";". I want to update the page as soon as each text is sent; but at the moment it just updates the label all in one go at the end. What's the simplest way to achieve this? Thoughts were maybe AJAX, JavaScript or Threading. (As I say, simple is good!)
Current code:
SerialPort sp = new SerialPort("COM1", 115200, Parity.None, 8, StopBits.One);
try
{
String[] numbers = tbNo.Text.Split(';');
foreach (string n in numbers)
{
sp.Open();
sp.Write("AT+CMGF=1" + (char)(13));
Thread.Sleep(200);
sp.Write("AT+CMGS=" + n.Replace(" ", string.Empty) + (char)(13));
Thread.Sleep(200);
sp.Write(tbMsg.Text + (char)(13) + (char)(26));
Thread.Sleep(3000);
sp.Close();
Label1.Text = Label1.Text + "Message sent to " + n + "<br />";
}
} catch (Exception error) {
Label1.Text = error.Message;
};
The best way is to create a service on server side if you have ASP.net, it can be a WCF Rest service, send a post request to server as ajax call and upon receiving the result change the label text in javascript.
You definitely want to use some AJAX for this. One way that's actually quite easy to implement is to use SignalR.
SignalR is a framework that supports a realtime connection between the client and the server. This makes your code a lot easier. If you don't use SignalR you would have to manually implement something like polling (where the client browser asks the server every X seconds what the status of your task is) or some variation on this.
SignalR hides the underlying mechanism used and creates a connection between the server and client.
Your code on the server would look something like this:
public class SmsHub : Hub
{
public Task SendMessages(string input)
{
// ... send sms message
Caller.updateStatus('Message send!');
}
}
And on your client you would use the javascript hub to send and receive messages. The updateStatus function can append a HTML message to some information div.
This is a nice blog post by Scott Hanselman that can also help you getting started.
Related
using System;
using Limilabs.Mail;
using Limilabs.Client.POP3;
class Program
{
static void Main(string[] args)
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Users\*******\Desktop\WriteLines.txt", true)){
using (Pop3 pop3 = new Pop3())
{
Console.WriteLine("Connecting...");
pop3.ConnectSSL("pop3.live.com"); // or ConnectSSL for SSL
pop3.Login("****#live.com", "****");
// Receive all messages and display the subject
MailBuilder builder = new MailBuilder();
foreach (string uid in pop3.GetAll())
{
IMail email = builder.CreateFromEml(
pop3.GetMessageByUID(uid));
file.WriteLine("Header: " + email.Subject);
file.WriteLine("Message: " + email.Text);
}
pop3.Close();
}
}
}
}
So I have this problem where I want to have this program running 24/7; it is still incomplete but this is just to show basic C# retrieving emails and such. How can I have a loop in C# that only gets halted or forced to anything only when a new email arrives in the inbox? I would like the program only to actually do something upon getting an email sent to in in realtime. I know I can go and print out my emails one by one all at once but I want it to be running and only when a new message is received do I want i to do anything. For example idk, if I was to send a message like clean desktop, it would stop and be parsed and if a valid command sequence specified by another program I am going to make, then it will carry out that command and then keep on looping endlessly waiting for another new message. It'll basically be a server running 24/7 that only responds to new emails. That is what I am going for. All help is greatly appreciated.
Pop3 is a polling protocol. It does not allow to inform you that a new mail has arrived. You would have to e.g. the Exchange protocol that supports this afaik. Thus, for POP3 mailboxes, mail programs usually poll for new emails every e.g. 15min. I'd suspect that your POP3-library does not support this directly. Thus, you would have to use a Timer class and poll for new emails.
Documentation for the Timer class can be found in the MSDN library:
http://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx
You would probably want to use a windows service that polls your email inbox.
A similar question was asked about how to do this here. One of the answers provides a good layout in how to do this.
In addition, if you are trying have your website perform this functionality (because you don't have access to install a windows service) you could use Quartz.net highlighted in this question.
I have to send query to remote program and recieve data. Then put them in my DB.
This is possible to call controller's action every 60 seconds for example?
Thanks.
PS. I think it's must be done on server side. Not JS solution.
UPDATE:
First, I have MS SQL Server DB.
Second, There is remote program that listen specific TCP port and waiting a query. I want to send a query every 60 seconds and parse response, then put parsed data in my MS SQL Server DB.
Using Ajax you could create a timer to send data to the controller every x seconds .
A spellchecker plugin in my web application does this , to do spell checking as you type .
I think you would be better off using a standalone service (windows, wcf, msmq, etc) that runs in the background and "sends the query" and saves to your DB.
Web Applications are not designed to be utilized as time-based "always alive" mechanisms. "Timing" needs state, and HTTP is a stateless protocol.
Don't try to shoehorn functionality into something that isn't designed to handle it.
Then again i could be completely misunderstanding your question. Quite possible.
Confusing statements:
This is possible to call controller's action
If it's external, how do you know it's a controller? Is this an external API?
There is remote program that listen specific TCP port and waiting a query
That doesn't sound like a web application/controller.
You could use cron on *nix base system. Or your program could trigger events every hours
0 * * * * lynx url-of-your-program-address.com/action/to/call
Your question is confusing. But since we are only here to guess at what you are on about here's a solution that might come close.
(P.S. I haven't compiled or tested this...because why should I care)
class ConsoleApplication
{
public static void Main()
{
Timer myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler( DoAction );
myTimer.Interval = 1000;
myTimer.Start();
while ( Console.Read() != 'q' )
{
; // do nothing...
}
}
public static void DoAction( object source, ElapsedEventArgs e )
{
Console.WriteLine("Made request at {0}", DateTime.Now);
using (WebClient client = new WebClient())
{
using (Stream stream = client.OpenRead("http://whereever"))
using (StreamReader reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
}
}
Depending on how flexible your solution should be I would play around with Windows Service solution with Timer in it either with Quartz.Net.
You can find more details using the link below http://quartznet.sourceforge.net/
I'm trying to get my Windows Phone 7 Mango app to listen to incoming UDP packets but having a heck of a time. I have the new Beta 2 refresh of the Windows Phone 7.1 SDK and dev tools installed. Any deviation I try from this MSDN sample results in a SocketException 10022, "An invalid argument was supplied".
My code is pasted below. I have been trying to adapt the code I found on this stackoverflow post but to no avail. This line generates the exception when its reached:
synchronous = m_udpSock.ReceiveFromAsync(udpRecvArg);
I'm hoping someone here can help identify what's going wrong. I'm calling "StartUnicastListen()" when the user presses a button. m_udpSock is previously defined as a class variable and set to null. Per the "Remarks" section of the ReceiveFromAsync() MSDN page, I've set all of the required properties and events.
private void StartUnicastListen()
{
m_udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
SocketAsyncEventArgs udpRecvArg = new SocketAsyncEventArgs();
udpRecvLoopStart(udpRecvArg);
}
private void udpRecvLoopStart(SocketAsyncEventArgs udpRecvArg)
{
byte[] udpRecvBuffer = new byte[2048];
udpRecvArg.SetBuffer(udpRecvBuffer, 0, udpRecvBuffer.Length);
udpRecvArg.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 11100);
udpRecvArg.Completed += new EventHandler<SocketAsyncEventArgs>(udpRecvArg_Completed);
udpRecv(udpRecvArg);
}
private void udpRecv(SocketAsyncEventArgs udpRecvArg)
{
bool synchronous = false;
try {
synchronous = m_udpSock.ReceiveFromAsync(udpRecvArg);
} catch (SocketException e) {
Log("recvUdp()\n" + e.SocketErrorCode + "\n" + e.ToString(), false);
return;
} if (synchronous)
udpRecvArg_Completed(this, udpRecvArg);
}
void udpRecvArg_Completed(object sender, SocketAsyncEventArgs udpRecvArg) {
EndPoint udpEp = udpRecvArg.RemoteEndPoint;
string msg = Encoding.UTF8.GetString(udpRecvArg.Buffer, udpRecvArg.Offset, udpRecvArg.BytesTransferred);
Log(udpEp + " " + msg,false);
udpRecv(udpRecvArg);
}
There's such limited documentation the proper usage of ReceiveFromAsync()--which seems to be the only option for this on WP7--and on System.Net.Sockets in Windows Phone 7 in general right now.
Thanks in advance for any help you can provide.
I had this same problem, but here is the solution that I came up with. As wilbur4321 said, you have to send something to the socket first. Also, not only do you need to just call SendToAsync and forget about it, you must wait for it (max of 1 second seems to work for me).
I do not know why you are required to do this, but sending something (I just send 1 byte: 0xFF) seems to do the trick.
Have you seen the sample at http://msdn.microsoft.com/en-us/library/hh202864(v=VS.92).aspx#Y4537?
Given that TCP sockets are client-only in Mango, I wonder is UDP sockets might only work after something has been sent? I would suggest trying that. If that doesn't work, could you post your entire project on dropbox or the like, and I'll look at it.
Thanks,
--randy
I found that a strange thing in that "Win7 UDP server" sample
that is the server-side UDP socket doesn't "Bind"
in my experiment, call "ReceiveFromAsync" on a socket which doesn't bind, "invalid argument" exception is throw. After binding before "ReceiveFromAsync", at least "ReceiveFromAsync" won't throw "invalid argument" exception.
My codes is similar to yours, but there is still some problems. it seems that, I call "ReceiveFromAsync" once, but the OS fire the event callbacks twice, which cause very serious race condition.
There is so few sample, documents about "UDP + SocketAsyncEventArgs". Maybe I have to revert back to using "BeginReceiveFrom".
You need to call ReceiveFormAsync() from the Completed event of SendTAsync()..Otherwise, you will get this exception..
Previously I posted a question regarding multithreading. Actually my intension is to send SMS for 1000 (or more) people at a same point of time (Ex: 12:00 AM sharp) by using c# and asp.net application. Is it ok to choose multithreading concept to achieve this?
That concept do not need Multi Threading ...
That concept is more of a Task Manager / Cron Job
Create an ASPX Script that sees the time and executes the method you need
Set up Task Manager to run this script every xx minutes
Create a method, that fetches the list of persons and send the SMS through an SMS API, and call it, for ex. SendSMSFromList( List usersList, string message ) {}
Now set everything up and you will run this anytime you need (just set it in the ASPX Script)
please, fell free to tell me, if you need any code for this.
edited for having all steps
If you have a hosted solution, in your hosting control panel you have something as Task Schedule that you can set up to run your script page every n minutes, if so please by pass the next steps. If, by other hand, you are running your own server (IIS) then do this first.
Install cUrl for windows from this location and add curl.exe to C:\WINDOWS
Open Task Manager (Control Panel > Administrative Tools > Task Scheduler on win7)
Create a new task like this
Run the command
curl http://localhost/yourApp/taskManager.aspx
with this you just configured your system to run a file, just like if you execute that link in a browser, that will run every 15 minutes.
Now we need to create that taskManager.aspx file
public partial class taskManager : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DateTime dt = DateTime.Now;
// Run after midnight
if (dt.Hour == 0 && dt.Minute <= 15)
{
Write2Log("Schedule Job Started", LogType.INFO);
SendSMSFromList(
GetUsersList(),
GetSMSMessage());
Write2Log("Schedule Job Finished", LogType.INFO);
}
}
private string GetSMSMessage()
{
// Fetch the text from DB...
return "This is the message content that I will send as SMS";
}
private List<string> GetUsersList()
{
// fetch the list form DB...
return new List<string>();
}
private void SendSMSFromList(List<string> usersList, string message)
{
// send SMS's
foreach (string phoneNr in usersList)
{
// send message
mySMSAPI.Send(phoneNr, message);
}
}
private void Write2Log(string text, LogType type)
{
// Log to a file what's going on...
try
{
string filename = HttpContext.Current.Server.MapPath("") + "\\status.log";
using (StreamWriter sw = new StreamWriter(filename, true)) // open to append
{
// example: 2008-12-17 13:53:10,462 INFO - Schedule Job Finished
string write = String.Format("{0} {1} - {2}",
DateTime.Now,
type.ToString(),
text);
sw.WriteLine(write);
}
}
catch (Exception)
{ }
}
private enum LogType
{ INFO, WARNING, ERROR }
}
Done...
I made everything in just one file for the sake of the example, you should divide things ... but what I was after was to show you the principle of it.
I don't know how you send them sms. But almost all big sms service providers will allow you to send 1000 within 1 seconds.
So Unless you REALLY REALLY REALLY REALLY REALLY REALLY need to be send them all at once, I suggest you just make a loop and send the information to the service provider one at the time.
Depends on how the SMS are actually sent. If you have let's say a web service that sends the SMS you'll end up in querying it 1000 times at one point which won't solve your problem.
To achieve this you need to make sure that the task of sending can be done simultaniously.
EDIT:
Furthermore I agree to astander that that amount of threads won't be healthy for your system at all.
Edit2:
How sharp does this needs to be? Assumeing that hh:mm is enough you'd have 60s to send
your about 1000 sms. This means that you need to send aprox 17 SMS per second. If you share
this to lets say 4 threads then you'd only need to make sure that your sending process /
device can send 4 SMS / s. this should be achievable I guess.
HTH
I dont think that is going to work for you, and creating such a large number of threads is not advised.
Also, see this link
maximum-number-of-threads-in-a-net-app
Does the SMS application allow for send-to-many? Or maybe use different services on various boxes to send these subset of sms. But i think sending such a volume at once will be difficult.
I suspect you'll have some transport issues getting that much data to your SMS provider at exactly that time presuming it is a realtime process.
I'd find a provider capable of doing scheduled sends and then queue up the messages to send at 12AM at my leisure.
I'm trying to write a notification service (for completely legit non-spam purposes) in .NET using SmtpClient. Initially I just looped through each message and sent it, however this is slow and I would like to improve the speed. So, I switched to using 'SendAsync', but now get the following error on the second call:
An asynchronous call is already in progress.
I read this to mean that MS crippled System.Net.Mail to prevent mass-mailers. Is this correct? If so, is there a better way to do this in .NET, and still be able to log the results of each email(which is important to our client). If not, why can SendAsync only be called once?
According to the documentation:
After calling SendAsync, you must wait
for the e-mail transmission to
complete before attempting to send
another e-mail message using Send or
SendAsync.
So to send multiple mails at the same time you need multiple SmtpClient instances.
You might be able to use the following:
ThreadPool.QueueUserWorkItem(state => client.Send(msg));
This should allow your messages to be queued and sent as threads become available.
Obviously, this is not an attempt to stop mass mailers.
The reason is that the SmtpClient class is not thread safe. If you want to send multiple emails simultaneously, you have to spawn a few worker threads (there are a few ways to do that in the .NET Framework) and create separate instances of SmtpClient in each of them.
I think you misunderstand the XXXAsync class of methods. The purpose of these asynchronous calls is to allow the program to continue running, without the need of the method to finish processing and return first. You can then proceed with the result later by subscribe to something like XXXReceived event of the object.
To send more than one mail simultaneously, you may consider using more Threads.
You may only send one at a time per SMTP client. If you wish to make more than one send call, create more than one SMTP client.
HTH,
Colby Africa
As noticed by everyone else here, you can only send one email at a time, but the way to send another once the first has been sent is to handle the .SendCompleted event of the SmtpClient class, and then move on to the next email and send that.
If you want to send many emails simultaneously, then as the others have said, use multiple SmtpClient objects.
There is a reason to reuse the SmtpClient, it limits the # of connections to the SMTP server. I cannot instantiate a new class SmtpClient class for each thread the reports are building on or the SMTP server will balk with too many connections error. This is the solution I came up with when I couldn't find an answer here.
I ended up using an AutoResetEvent for keeping everything in sync. That way, I can keep calling my SendAsync in each thread, but wait for it to process the email and use the SendComplete event to reset it so the next one can continue.
I setup the Auto Reset Event.
AutoResetEvent _autoResetEvent = new AutoResetEvent(true);
I setup the shared SMTP Client when my class is instantiated.
_smtpServer = new SmtpClient(_mailServer);
_smtpServer.Port = Convert.ToInt32(_mailPort);
_smtpServer.UseDefaultCredentials = false;
_smtpServer.Credentials = new System.Net.NetworkCredential(_mailUser, _mailPassword);
_smtpServer.EnableSsl = true;
_smtpServer.SendCompleted += SmtpServer_SendCompleted;
Then when I call the send async, I wait for the event to clear, then send the next one.
_autoResetEvent.WaitOne();
_smtpServer.SendAsync(mail, mail);
mailWaiting++;
I use the SMTPClient SendComplete event to reset the AutoResetEvent so the next email will send.
private static void SmtpServer_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
MailMessage thisMesage = (MailMessage) e.UserState;
if (e.Error != null)
{
if (e.Error.InnerException != null)
{
writeMessage("ERROR: Sending Mail: " + thisMesage.Subject + " Msg: "
+ e.Error.Message + e.Error.InnerException.Message);
}
else
{
writeMessage("ERROR: Sending Mail: " + thisMesage.Subject + " Msg: " + e.Error.Message);
}
}
else
{
writeMessage("Success:" + thisMesage.Subject + " sent.");
}
if (_messagesPerConnection > 20)
{ /*Limit # of messages per connection,
After send then reset the SmtpClient before next thread release*/
_smtpServer = new SmtpClient(_mailServer);
_smtpServer.SendCompleted += SmtpServer_SendCompleted;
_smtpServer.Port = Convert.ToInt32(_mailPort);
_smtpServer.UseDefaultCredentials = false;
_smtpServer.Credentials = new NetworkCredential(_mailUser, _mailPassword);
_smtpServer.EnableSsl = true;
_messagesPerConnection = 0;
}
_autoResetEvent.Set();//Here is the event reset
mailWaiting--;
}