How to notify user of new message? - c#

I need to update the user's messages when a new one was sent to him.
I know that I can create a SQL Trigger and get it using CLR Triggers.
But how do I notify the user without having some method polling to see if something's changed?
How do I know that I have new messages without check the database every time?
It's 100% similar to an email system or the facebook message system.
One user will send a message to another, how to get that new message without having a method checking the database for changes from time to time?
I'm using SQL Server 2008 and ASP.NET MVC3.
Thanks.

Please take a look at the SignalR (https://github.com/SignalR). You'd have to perform tests on how it behaves in your environment.

Related

How to: ask server about updates

My question is about a search of appropriate way of implementation.
I have an application and I need to make it to check for updates. Actually we shouldn't pay attention for the reason of sending the message. It may not be a message about updates but something else. What is the best way to implement it?
Now it asks my REST service while starting but what if the application is working a long time and I need to inform the user about updates? Maybe message bus can help or there is any best practice?
Thanks!
UPDATE
Just to clarify:
My client application asks service (REST) to check if there is any updates but I want to make the service to inform my client. So the question is what is the best way to send a message from the service to my client to inform about new application update.
For your szenario I'd use a REST server and send a request every few hours. If you want your server to notify your client, SignalR should be a good choice.
https://learn.microsoft.com/en-us/aspnet/signalr/

Notify for database change

I have 2 systems and it is lan based. I just want the other system to be notified when there's a change in the database. I am using C# and ms-access for the database. Can you please give me some ideas on how to do it? Thanks in advance!
If you are using access, you can't write triggers as you could in MS SQL for example. There are different approachs. Some of them are:
On system 1, develop small web api with a method which will return true or false if system was changed. From system 2 ping system 1 API method on some interval.
Use SignalR, Microsoft technology for real time programming. Create SignalR client on system 2, and send message from system 1 to system 2 when change on database occures.
If you change your database only from client (C# application) then it would be more appropriate to send the notification from your client (when changing data) rather than using a push model (e.g. trigger callback from database).
See the StackExchange question.

What should I use to be sure that a block of code is executed together in C#?

I have a 3 layer web app in C#.
I have a simple method in the business layer that calls another one in the database layer to insert info in the database.
When the control return to the business layer, I checked the result variable, and if it's positive it means that the info was inserted in the database. Then, if positive, I called another method to send an email.
I was wondering, that would happen if the server goes offline just in the middle of this? For example just after the info was inserted but before the mail was dispatched.
How can I solve this situation and make this block of code run in an atomic way? Using a transaction? (not sure how to use one through different methods in different class libraries).
Many thanks.
Separate these issues. Have your business layer write the values, with a new field "MailSent" or something set to False. Have another service poll the results table for unsent mails, and work through those.
You can run all of your database operations within a transaction, but you truly can't ensure that the mail is being sent out in the middle of the transaction. Even thought you can dispatch an email to a smtp server for delivery, the mail DELIVERY IS NOT GUARANTEED ANYHOW!!!
The mail server may be unable to connect outward toward the internet or wherever it has to relay mail to.
It may be able to connect out, but weird stuff happens and the message may be delayed (as in the case where it connects right away, but connection is dropped)
Don't drive yourself crazy. It's a short drive.
Sending an email via relay sometimes takes time, so you do not want to wait whether email is fail or successful.
However, there is not right or wrong answer. Here is my two cents.
As you said, second code of block is sending email. In our sites, we use separate process to send out emails. Here is how it works –
Use transaction to enter information to Info table and EmailQueue table in database
Background process picks up emails from EmailQueue (let say every 5 minutes) and send out email
If email is successful, mark the email as sent
If email is fail, increase the attempt counter until it reach some limits (let say 3 times)
If server goes offline like you said and come backup again, the background process will pick up emails from EmailQueue (which haven't been send and less than attempt limits).
Inspite of returning a boolean result. Maintain a table called Outbox and insert a row in it if condition satisfies.
And when control comes back to your business layer as mentioned in your question. Process all the outbox mails i.e., sent all the mails present in outbox and delete the entry from outbox or update a column in Outbox table which will represent email status.

Which is better to send e-mail using .net or trigger in the SQL table

We have this module where user can register and they need to confirm their e-mail address.
Currently I used .NET to send e-mail. So after adding the record I will now call my email method. But what I noticed is there are times that the e-mail functionality does receive a timeout error and since I catch all the exception this error is presented to the user.
What I wanted is to send the e-mail on the background. If there are any mail connection timeout, the e-mail method will just retry sending the e-mail for probably a minute or two.
And I'm thinking of using the SQL mail to achieve this. But I'm not sure if its the best solution.
You have a few options:
Use SQL Server Database Mail to perform the heavy lifting around the email queuing and sending. The application would still be responsible for constructing the message and sending it to the database. Relay through a separate SMTP server (installing SMTP services directly on a SQL machine is probably not a good idea).
Use async email methods from your web application, e.g. SmtpMail.SendAsync(). This will allow you to handle errors without holding up the user (or interacting with the user), but it's not durable. If your web process restarts, the operation is lost.
Use a Windows service. This will be a simple, separate application which simply monitors the database for new email tasks and/or is sent a message from the web application that a task needs to be performed.
Option #2 using SendAsync() will be the quickest to implement. Depending on your needs, that may be sufficient.
Option #1 shouldn't require much more effort. Option #3 really shines when you need to implement complex business logic around the recipient list and the email contents. It's also possible to combine options #1 and #3 (see the conversation between #RemusRusanu and me in the comments).
With both option #1 and #3, if the environment goes down, a service restarts, or an error occurs, you won't have lost any data or failed to send an email.
Rather manage the time-out in the .net application. If there is an issue or a time out in the trigger your data may not be committed. Rather allow the DB to complete the data transaction, and check the state from your .net App.
I dont think there is a definitive answer to this, but this would be my preference.

LAN Application

I have a LAN composed of 3 PC. Installed in PC1 is the MS SQL database. This computer will act as the server.
The PC2 and PC3 will each have a desktop application that will display the data from PC1.
My problem here is how to make each PC (PC2 and PC3) have the same copy of data.
Suppose in PC2 employee 0001 first name is updated from John to Peter and commit save. Without refreshing the application in PC3, employee 0001 will still have John for the first name.
What would be the best approach for this? My level in programming is not that good, but I'm open to all suggestions/concepts/example/etc..
Thanks.
If you want immediate update on all clients right after data changes then you need some sort of notification system either in a polled or pushed manner.
You can implement push mechanism using for example WCF with callback contract. Your client PCs would need to implement relevant callback interface and be constantly connected to server PC's WCF service. Callback call could actually carry the new data. Each client needs to filter out notifications which resulted from that client's own changes. Push mechanism is quick and efficient way.
Check this stackoverflow answer for example of WCF callback.
Pull mechanism would require a background thread on all client applications checking the server for changes. You can use a separate database table with a version counter that would get incremented each time anything changes on the server. Client applications would poll that counter, compare with latest version they have and update the data when new version is discovered. It is much less effective mechanism though as you need to do the polling frequently and get all the data each time there is a new version. You can make versioning more sophisticated and detect what exactly changed but that can get complicated quickly with multiple clients. Overall it does not scale very well. It is generally simpler than push though and for simple applications with not too much data it would be enough.
You need to tell the other machines when to update. This could be accomplished by simple messages sent over the network using UDP broadcast. Then the other PC could execute its refresh method.
well utivich...this is the same thing as a web application really. it's a common problem. usually the other clients will have stale data until the record is reloaded, or when they save maybe the server will throw an exception on stale data based on sql timestamp. however, with a desktop application you can setup a system with event notification just like a chat application where the server pushes events to subscribers and the clients will be able to update the record or whatever you need to do.

Categories