We have applications that need to send out email notifications from time to time. We have been using the .net mail classes but recently we are running into the problem of some virus checkers blocking port 25. To me the correct solution is to set up the correct exclusion rules to allow our app to keep working. However, some are afraid that this may become a huge hassle in the future, especially as new organizations come on line, and would prefer to use SQL dbmail instead. I don't particularly like this choice, I would much rather have the application handle this aspect but I'm not sure if it's worth the fight. Are there any real advantages of using .net mail over the SQL mail?
You can set up dedicated mail server, isolate it from network except for certain IPs and only for inbound connections on port 25. I think it is safe enough. Even if you move to SQL server, you will open port 25 and become vulnerable. You (your coulegues) can manage risks instead of hiding them.
You should ask yourself the following question
Do I really want to use the database server to send out email?
It all depends on how many emails you'll be sending and how busy the SQL server is.
If you'll not be sending many emails and you've got a pretty quiet SQL server; go right ahead.
If (like most of us) you're not that lucky, then look elsewhere.
They are both SMTP solutions using port 25.
You'll have the same issue most likely, it depends on where the scanner is checking/blocking
My thoughts would be to redesign this aspect of the system so that email requests are queued in a database table, and a single machine processes them.
Benefits:
you don't have to tie up resources on your SQL Server processing volumes of email
you don't have to go through the paperwork / exclusion sets for all client machines, just the one that's actually going to do the work.
Downsides:
more work for your developers!
Related
I am in the need of creating a C# program that will run on couple of our local Windows client machines. These 'client' programs will have to take commands from a 'admin' program run on another machine.
The commands could be to reboot the client computers, return some local information about IP address etc back to the 'admin' program.
But how to accomplish this? I know a little about WCF but is that the right way to go?
If I go with WCF I will then have to make the client programs run a service method, like every second, to check for new commands. With sockets I establish a 'direct' connection and the client just waits for a command to receive - isn't that correct understood?
Which way would be the right way for me to go?
We are talking about ~10 clients and I want a maximum delay (send command - receive info back) of 1 second.
Any hints would also be appreciated.
Best regards
Duplex WCF server. Basically, the clients all connect into the server (so only 1 server), and the server uses its duplex channel to call back to the clients whenever it needs to. No polling, scales well, etc. The most headache you'll need to deal with is to set a long timeout in case that you don't send anything for a while so that the channels time out.
WCF will end up being much simpler in the end.
A couple of links:
http://msdn.microsoft.com/en-us/library/ms731064.aspx
and
http://www.codeproject.com/Articles/491844/A-Beginners-Guide-to-Duplex-WCF
I hope those help.
You can make WCF clients act as servers and with command & control program connect to them that is no problem. Go for WCF if you don't want to mess with ugly stuff that sockets can bring. WCF can be configured nicely in app.config, and you can make it really self hosted command line application even so no need for IIS server. Configuration will be then resuable and easier to maintain.
You could use .NET Remoting which can provide a "push" backchannel from the server to the client (using "callbacks"). It does not need a 2nd TCP connection in the other direction so you don't need to mess with client's firewalls and routers.
Remoting is considered kind of obsolete but it has its places.
In any case I would not use a WCF polling technique. That leads to bad latency and a DDOS situation for the server.
If you can make the clients open a port then hosting a WCF service there is probably the best idea.
I would recommend a socket implementation as in the long run it probably gives you greater flexibility. You could create this from scratch yourself using the socket namespace. As an alternative you could use an off the shelf network library solution. Checkout lidgren and NetworkComms.Net.
Disclaimer: I'm a developer for NetworkComms.Net.
With the small number of machines and modest performance requirements you mentioned, I think WCF would end up being easier than sockets.
You might look into Duplex WCF. I've never used it, and WCF has given me headaches in the past any time I've needed anything unusual, but it's for the sort of problem you're talking about.
If all the machines are on one network, here's one creative alternative loosely inspired by message queues: you could use a database table as a place where messages appear and get read by clients at their leisure. The clients could just query it and say: get me all messages where MessageID > LastReceivedMessageID.
The downsides of that last approach is that (a) you're still doing polling although your database server should be able to handle it and (b) if you might ever need this outside of your network, you would need a VPN or a new solution.
you could use MSMQ... couldn't be easier to implement
http://msdn.microsoft.com/en-us/library/windows/desktop/ms711472(v=vs.85).aspx
I use MSMQ for a number of similar applications. Works perfectly.
I have a client who would like a system developed which handles sending out alert emails to opted-in registered users. The alerts are based on geographic travel-related incidents and these are provided via a third party web service. The registered userbase is expected to be around 500,000 users and each user can subscribe to multiple alert categories.
I'm just trying to scope out what would be required technically to create this alerting functionality. In my mind we would create something like the following:
Poll the alert service once hourly
Store a "queue" of alerts in a temporary database table
Process the queue table as a scheduled task and send out the emails to the opted-in users
The part that I'm really not sure about is the physical sending of the emails. I was wondering if anyone could recommend any good options here. I guess we're looking to either create a custom component to send out the emails or use a dedicated third party service (like dotMailer maybe? Or a custom mass mail server?). I've read that rolling out your own solution runs the risk of having IP's blacklisted if you're not careful, and obviously we want to keep this all completely legitimate.
I should also mention that we will be looking to create the solution using .NET (C#) and we're limited to SQL Server Express 2008 edition.
Any thoughts much appreciated
Many thanks in advance
For the Poll , Queue and Send operations I'd create a windows service that calls the external service , operates on the data and then gathers the results to send out the emails updating the database as necessary with sent flags etc.
I handled a similar project recently and we found many ISPs or Hosting Providers got really twitchy when we mentioned mass emails. You should defintly check out the http://en.wikipedia.org/wiki/CAN-SPAM_Act_of_2003 CAN SPAM guidelines (or similar in your territory).
As long as you play by the rules and follow the guidelines you should be OK sending out from a local mail server however its important that you ensure that DNS Lookups or Reverse DNS lookups on the MX records all point back and forth to each other properly. Indeed this would be easier to out source to a third party mail provider or ISV but when we tried we were unable to find a good fit and ended up doing it ourselves.
Additionally you may want to glance at SPF records and other means to increase mass email delivery! For what its worth this can be a very tricky task to implement as SMTP (my least favourite protocol) is painful to try to debug and people get very upset if they receive multiples or unsolicited emails so ensure you have an Opt-in policy and appropriate checks to prevent duplicate delivery.
I am looking for a way to detect if a SQL Server fails to respond (timeout/exceptions etc) so that if our C#/.net program trying to access the server asks a server that is down for maintenance, it will jump and try another automatically.
I would like a solution where we do the SQL connection and THEN get the timeout. We could build a WCF service and ask that one, but that is a bit of an overkill in my opinion.
The sync between multiple server locations is not the issue here.
Our development platform at the moment is SQL2008express as its plenty at the moment, but later on we might switch to real SQL2008 servers (or whatever is latest when the time comes).
Clients will connect to "first known" in a "last known dynamic list" asking a "rootserver" or hardcoded configs for first lookup.
When clients loses connections, they will automatically have to try to reconnect to other nodes in the clusters and use whatever returns a reply first. The nodes will individualle connect and share data through other services which we also distribute in the cloud.
We know that mirroring and clustering might be available through large licenses, but our setup demands a more dynamically "linking" and we believe this approach suits our needs better.
So... to be specific:
we need to detect when a SQL-server goes offline, when its not available anymore. Eg. in the middle of a transaction or when we try to connect.
Is the best approach to do a "try-catch" exception handling or is there better tricks when looking over WAN's and using C#/.net =
EDIT
I've received a lot of good ideas to use failover servers, but I would like a more programatical approach, so whats the best way to query the server if its available?
Situation:
4 different SQL servers running on seperate WAN/IP's, each will maintain a list of "where the others are" (peer-to-peer). They will automatically be moving data from each other (much like a RAID-setup where data is spread out on multiple drives)
A client retries the list from an entry-point-server and asks the first available.
If the client asks a server that is "down for maintance" or the data has moved to one of the other servers, it must automatically ask the next in the list.
What we are looking for..
is the best way from within C#/.net to detect that the server is currently unavailble.
We could have a service we connect to and when we loose this, the server is off
We could make a "dbConnectionSqlServer3.open()" and wait for the time out.
We could invest in "real cluster servers", and pay a lot + bind ourselfs to 1 SQL-server type (The SQL platform might change in future, so this is not a real option)
So whats your vote here: 1 or 2?
or can you come up with a number 4 that beats the h**k out of ideas? :o)
I would probably take a different approach.
I'd designate a server (with a failover partner) to be the holder of the server list. It should monitor all of the other servers for availability.
When the client initially wants to connect, it should contact the list server and ask it what to use. From that point forward the client should stick with it, unless a failure is detected. At which point it should contact the list server to get a new one.
The list server would be able to implement any type of load balancing you wanted just by telling the clients which one to connect to. Further, deploying new servers would be easy as the only "list" would be maintained by this primary server.
This completely ignores any sort of server synchronization issues you might have.
One major benefit is that by having a central server doing the monitoring your clients won't have to fall through 3, 5, or 10 servers just to find one that's up. which would increase responsiveness.
UPDATE
#BerggreenDK: The best, and probably only assured way, to detect if a server has failed is to connect to it and run a simple query. All other mechanisms such as pinging, a simple check if the port is open, etc. might give a false positive. Even having a process running on that server itself may give a false reading if the server itself is up but SQL Server is down (e.g: the database is offline).
Ultimately it sounds like your client will have to connect to one of the gateway servers and get a short list of sql servers to attempt to connect to. On failure, it will have to rotate through that short list. If all are down it will have to go back to the gateway and ask for a new list to start the process over.
In the ConnectionString you can specify a failover partner like
Data Source=<MySQLServer>;Failover Partner=<MyAlternateSQLServer>;Initial Catalog=<MyDB>;Integrated Security=True
On http://www.connectionstrings.com there is a section talking of DataBase mirroring.
Can anyone recommend a simple and reliable method of sending email notifications and possibly log files attachments from a C# program without requiring the installer or the user to configure the program by specifying server details and email addresses etc.
(Mainly because they won't know the details, but also because they could change)
The program will normally be run as a service of a Windows Server, but can be run on a client.
I tried connecting to our own mail server and sending a email to myself, but some ISP's are blocking Port 25 on all servers but their own, so that method isn't working reliably.
Tried sending email through gmail but that was less successful as the port they used was blocked by firewalls. Ditto webservices connecting on weird ports.
Trying to use the local smptservice but did not work either.
It would be nice, but not essential if it was not dependant on my own Internet connection/Servers. (Don't mind them being delayed, but prefer them not to get lost).
Are there any webservices on http/https that allow you to do this sort of thing?
TIA
try using cdosys
http://support.microsoft.com/kb/310212
http://www.eggheadcafe.com/articles/20030316.asp
May have discovered the solution.
Was catching up on my blog reading over the weekend and came across a recent entry on Coding Horror and the very first comment mentions PostMarkApp which seems to do everything I need (and almost everything I want, apart from attachments which they are considering).
I hope someone can guide me as I'm stuck... I need to write an emergency broadcast system that notifies workstations of an emergency and pops up a little message at the bottom of the user's screen. This seems simple enough but there are about 4000 workstations over multiple subnets. The system needs to be almost realtime, lightweight and easy to deploy as a windows service.
The problem started when I discovered that the routers do not forward UDP broadcast packets x.x.x.255. Later I made a simple test hook in VB6 to catch net send messages but even those didn't pass the routers. I also wrote a simple packet sniffer to filter packets only to find that the network packets never reached the intended destination.
Then I took a look and explored using MSMQ over HTTP, but this required IIS to be installed on the target workstation. Since there are so many workstations it would be a major security concern.
Right now I've finished a web service with asynchronous callback that sends an event to subscribers. It works perfectly on a small scale but once there are more than 15 subscribers performance degrades considerably. Polling a server isn't really an option because of the load it will generate on the server (plus I've tried it too)
I need your help to guide me as to what technology to use. has anyone used the comet way with so many clients or should I look at WCF?
I'm using Visual C# 2005. Please help me out of this predicament.
Thanks
Consider using WCF callbacks mechanism and events. There is good introduction by Juval Lowy.
Another pattern is to implement blocking web-service calls. This is how GMail chat works, for example. However, you will have to deal with sessions and timeouts here. It works when clients are behind NATs and Firewalls and not reachable directly. But it may be too complicated for simple alert within intranet.
This is exactly what Multicast was designed for.
A normal network broadcast (by definition) stays on the local subnet, and will not be forwarded through routers.
Multicast transmissions on the other hand can have various scopes, ranging from subnet local, through site local, even to global. All you need is for the various routers connecting your subnets together to be multicast aware.
This problem i think is best solved with socket.
Open a connection to the server, and keep it open.
Could you have a slave server in each subnet that was responsible for distributing the messages to all the clients in the subnet?
Then you could have just the slaves attached to the central server where the messages are initiated.
I think some of you are vastly overthinking this. There is already a service built into every version of Windows that provides this exact functionality! It is called the Messenger service. All you have to do is ensure that this service is enabled and running on all clients.
(Although you didn't specify in the question, I'm assuming from your choices of technology that the client population of this network is all Windows).
You can send messages using this facility from the command line using something like this:
NET SEND computername "This is a test message"
The NET SEND command also has options to send by Windows domain, or to specific users by name regardless of where they are logged in, or to every system that is connected to a particular Windows server. Those options should let you easily avoid the subnet issue, particularly if you use domain-based security on your network. (You may need the "Alerter" service enabled on certain servers if you are sending messages through the server and not directly to the clients).
The programmatic version of this is an API called NetMessageBufferSend() which is pretty straightforward. A quick scan of P/Invoke.net finds a page for this API that supplies not only the definitions you need to call out to the API, but also a C# sample program!
You shouldn't need to write any client-side code at all. Probably the most involved thing will be figuring out the best set of calls to this API that will get complete coverage of the network in your configuration.
ETA: I just noticed that the Messenger service and this API are completely gone in Windows Vista. Very odd of Microsoft to completely remove functionality like this. It appears that this vendor has a compatible replacement for Vista.