What I am trying to do with SignalR:
1- Setting the hidden field from a session UserID on page load and send this ID back to server's SignalR Hub to start the polling thread for given user.
2- Terminate the thread when user leaves the site.
Right now I am doing AJAX requests to server every 30 secs per user to check for new user messages.I Just want to replace it with SignalR. I am able to create the user level thread in a HUB when the users session is created by setting the hidden field on page load and then setting the session variable via ajax request so the new thread is not created for the same user again and again e.g page refresh. The thread is periodically checks after (15 sec) for newly arrived messages. The main issue is how do I terminate the thread created for a specific user when its session ends. Is this the right way to use SignalR ?
This doesn't sound like good design - polling is never good, not for this kind of problems anyway. It would be better if you could deliver the message instantly. Are you using multiple webservers? If not, then deliver the messages locally inside the application. If you are using multiple webservers, consider using something like RabbitMQ, Redis or similar to send messages between the servers.
Related
I'm making an MVC app with the .NET Framework and in one of my controllers I call an async task that sends an e-mail to the signed in user.
This task is called upon when the user clicks a specific checkbox and the e-mail is meant to work as sort of reminder.
The entire task works as intended (the user gets an e-mail when the checkbox is checked), but I need it to wait 24 hours before actually sending the e-mail, as it is a reminder.
Currently the e-mail is sent right away, how can I delay the completion of my "e-mail task", while the code continues?
Use a library like Hangfire which lets you schedule background jobs and backs them with persistent storage.
You can then easily schedule a job like:
BackgroundJob.Schedule(
() => SendEmail("user#domain"),
TimeSpan.FromDays(1));
This is a classic X Y Problem. While it may be possible to make your system wait 24 hours you are creating a very fragile system that can be affected by app pool resets and server reboots.
Putting aside the possibility of an unexpected reboot, what happens when your maintenance cycle comes around and a scheduled reboot is going to happen? How many queued email reminders will you have that you can't do anything with?
The best approach for systems that don't immediately use their data is to buffer it through some form of storage scheme. It could be as simple as writing queued emails to files on the system, or something more robust like a database with a dedicated email sending service.
I have used a LOT of email sending systems over the years, and even for immediate sends we have used a database intermediary, with one dedicated email sending Windows service to produce and send the actual email. By centralizing the email production you not only get one place to maintain your email sending code, but you can also increase the durability of the whole system.
Bonus points if your database is part of a high availability cluster, as in this kind of system the database becomes the critical point. If it is then you're protected from any form of downtime other than a total network outage.
Let the Task wait for 24 hours before sending the mail.
await Task.delay(TimeSpan.FromHours(24));
Add this line in your async function bfore sending the email
I'm building a chat app.But on logout button I can change bit value in database from 1 if user login to 0. But if user close the app or exit the browser without hitting logout, how can I change the bit value to 0?
Need answer programmatically.
When you close your browser, your webserver won't receive any feedback. Most browsers also do not allow you to implement javascript that does this. The only way to track this is by using something that polls your server periodically. (As #scgough put in the comments, SignalR is one of these technologies that you can use to do this.)
The downside of these techniques is that web browsers will generate web traffic to your webserver periodically to send 'heartbeat' signals, which in turn keeps the session alive for as long as the browser is open. This means this will consume a bit more web traffic and server resources.
I want to have single user login in my web site, i.e a user can't logi n with one userid and password from different places at same time.
It can be done simply by maintaining a flag in database and altering it on user logout and login, but what about if the user doesn't press logout button and:
closes the browser(here I can alter database flag through window.unload event)
network crash (real problem is here).
Can anyone suggest how to deal with system/network related problems? I don't want to use session.end() because sometimes it fires after a default timeout (~20 min).
Can I use signalR to create a server timer to monitor if user is alive or not?
SignalR will suffer from server crashes. SignalR does its best to ensure that events are triggered prior to shut down but there are cases when a server dies that will result in you having invalid entries in your db.
An approach that is used by https://jabbr.net/ is it logs every user off on server start. Therefore whenever your SignalR server starts: run cleanup on your database. In all other situations you can rely on SignalR to track your users appropriately.
To address your #1: SignalR will actually send an abort command to the server on unload, however if that command doesn't get sent for whatever reason the server will still timeout the connection and will eventually trigger OnDisconnected on the hub.
I wrote a window service that performs some task using the threads.Now i am writing an application which controls the window service using the window service controller.There are also some threads which i want to control from this third party application.I tried to start/stop the threads using the database but it does not seems a proper solution.I think there must be some thing that would support the controlling threads like window service controller from third application.
Any help would be greatly appreciated.
Thanks
You can override OnCustomCommand in your service to allow communication from your service controller trough ExecuteCommand.
You will only be able to send numbers between 128 and 256, but if you wrap that in an enum it should be pretty workable. If you need to send more data you could still fetch that trough the database after you send a command.
http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.oncustomcommand.aspx
What's worked well for me is to have a supervisor thread in my service that polls a database table for commands and in turn controls worker threads. The supervisor also writes status back to another table in the database.
The UI controller app polls the status table and writes commands to the command table. When the service responds to commands it echos the results back to the status table, giving positive feedback to the user.
I also use a third table as an activity queue that the worker threads write to and is displayed by the controller so the user can see what's happening. Limit how big the activity table can grow so that the controller doesn't have to always be running.
Guard the tables with transactions and this can run for a long time unattended.
I have the following code which send out SMS to the subscribers. However, some SMS were rejected from the SMSGateway because I'm sending too many SMS at one time. So I'm thinking to make a delay in between.
Sending out the SMS like this -
foreach (DataRow row in dt.Rows)
{
//Gets Subscriber number
smsSender.destinationNum = Convert.ToInt64(row["callerID"]);
foreach (DataRow articleRow in dtArticle.Rows)
{
//Gets SMS content
smsSender.smsMessage = articleRow["news"].ToString();
//Then send out the SMS
smsSendder.sendSMS();
}
}
Please advice because I have no experience with the threads and timers
It would depend on the architecture of the application.
Assuming this is a service-style app, with no user interface, that simply gets data out of the database and sends it to SMS, then Thread.Sleep(...) is fine.
If this app has a user interface, and you're running this SMS sending code on the UI thread, then Thread.Sleep(...) will block your UI. Actually, smsSender.sendSMS is probably already blocking your UI in this case!
Refactoring so that this code is off the UI thread is the answer. And you can do that simply by using a timer, although you will have to refactor the code so that the result set is cached in a local object and the timer iterates through the set sending one SMS out at a time.
In either case, I hope you don't have a lock on the database while you're sending SMSes.
Your question is tagged [asp.net] so I assume that you have a webpage that when requested will send a number of SMS messages (e.g. when a user presses a "submit" button or something similar in a HTML form).
In that case you can have multiple users requesting the webpage simultaneously. Also, you don't want to sleep in the thread serving the web page to the user. If you do that then there will be a delay where the user waits for the web page to respond while the SMS messages are sent.
I would suggest something like this:
When you need to send SMS messages you store the messages in a table in your database.
After storing new messages in the database you start a task (Task.Factory.StartNew) to process the SMS messages in the database.
You need to make sure that no more than one task is running in the ASP.NET application. Storing new messages in the database involves checking if the task is running and if not starting it.
The task will process all remaining messages in the database and send them using the appropriate delay (done by Thread.Sleeep).
When the task has sent an SMS message it is removed from the database.
This solution offloads the sending of messages to a background task that can be as slow as required and introduces persistence using the database to avoid loosing messages even if say the application pool is recycled.
Thread.Sleep is more appropriate, because it models better the waiting aspect.
Thread.Sleep() should be a good choice to delay calling to SMS gateway to prevent server reject your request.
I don't think it's Thread.Sleep() that's tying up the CPU.
Thread.Sleep seems bad design. Please refer http://blogs.msmvps.com/peterritchie/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program/ about why Thread.sleep is a bad.
Timer are more accurate, Thread.Sleep is only guaranteed to wait at LEAST as long as the amount of time you specify (the OS may put it to sleep for much longer). .