Click here to Skip to main content
Click here to Skip to main content

Notification Client and Server Written in C#

By , 22 Oct 2007
 
Screenshot - notify1.jpg Screenshot - notify2.jpg

Introduction

This article is about two small programs that will allow you to send and receive messages across a normal socket and display the message inside a "balloon" notification.

Background

I was using several applications to communicate messages to various users, and found that the many different methods were becoming somewhat cumbersome. So I hastily slapped together some C# code and came up with the following programs. I had never done any real C# programming before, and it was definitely a learning experience.

Using the Code

The NotifyServer program is pretty simple. Pick a port number and hit the Start button to begin listening. Hit the Stop button to end the listener.

I created some enums to hold the values for my Icons:

private enum balloonIcons
{
    INFO = ToolTipIcon.Info,
    ERROR = ToolTipIcon.Error,
    WARN = ToolTipIcon.Warning,
    NONE = ToolTipIcon.None
}
private enum logIcons
{
    INFO = EventLogEntryType.Information,
    ERROR = EventLogEntryType.Error,
    WARN = EventLogEntryType.Warning,
    NONE = EventLogEntryType.Information,
}

I wanted my application to minimize to the notification area when the minimize button was pressed, so I added the following event handler to the form.Deactivate event:

this.Deactivate += new EventHandler(this.sendToTray);

void sendToTray(Object sender, EventArgs e)
        {
            if(this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
            }
        }

When the Start button is pressed, I create a TcpListener, start it and begin an asynchronous accept:

try
{
    //Create my listener and start it
    tcpListen = new TcpListener(new System.Net.IPEndPoint
        (System.Net.IPAddress.Any, Convert.ToInt16(this.txtPort.Text)));
    tcpListen.Start();
    //Being asynchronous callback using the processEvents routine
    tcpListen.BeginAcceptTcpClient(new AsyncCallback(this.processEvents), tcpListen);
    this.notifyIcon.ShowBalloonTip(0, "NotifyServer", 
        "Now listening on port " + txtPort.Text + ".", ToolTipIcon.Info);
}
catch(System.Exception error)
{
    this.notifyIcon.ShowBalloonTip(0, "NotifyServer", 
        "Listener could not be started!", ToolTipIcon.Error);
}

The processEvents routine looks like this:

try
{
    StringBuilder myMessage = new StringBuilder("");
    //I want to write the messages to the event log
    //If the event log source doesn't exists, create it.
    if(!EventLog.SourceExists("NotifyServer"))
    {
        EventLog.CreateEventSource("NotifyServer", "Application");
    }
    //Create a new event log object and set the source
    eLog = new EventLog();
    eLog.Source = "NotifyServer";
    //Safely get our listener object and a TcpClient from that listener
    TcpListener processListen = (TcpListener) asyn.AsyncState;
    TcpClient tcpClient = processListen.EndAcceptTcpClient(asyn);
    //Get our stream
    NetworkStream myStream = tcpClient.GetStream();
    myMessage.Length = 0;
    string[] messageArray;
    //If our stream is readable, put the data in our string, write to the log
    //and create a notify message
    if(myStream.CanRead)
    {
        StreamReader readerStream = new StreamReader(myStream);
        myMessage.Append(readerStream.ReadToEnd());
        messageArray = myMessage.ToString().Split("|".ToCharArray());
        this.notifyIcon.ShowBalloonTip(Convert.ToInt16(messageArray[0]), 
            messageArray[2], messageArray[3], 
            (ToolTipIcon) balloonIcons.Parse(typeof(balloonIcons), messageArray[1]));
        eLog.WriteEntry(messageArray[3], (EventLogEntryType)logIcons.Parse
            (typeof(logIcons), messageArray[1]));
        readerStream.Close();
    }
    //Close everything
    myMessage = null;
    messageArray = null;
    myStream.Close();
    tcpClient.Close();
    eLog.Close();
    //Re-register our callback
    tcpListen.BeginAcceptTcpClient(new AsyncCallback(this.processEvents), tcpListen);
}

The Client program is an easy to use console application as well. You can use any Client you want that can send messages across the socket. The calling format of the client program is:

c:\notifyclient hostname port timeout icon[INFO|WARN|NONE|ERROR] "Title"  "Message" 

The client simply creates a TcpClient, connects to the listener, creates a network stream, and writes to it:

StringBuilder myMessage = new System.Text.StringBuilder();
myMessage.AppendFormat("{0}|{1}|{2}|{3}",args[2],args[3],args[4],args[5]);
try
{
    //Create a new TcpClient
    TcpClient client = new TcpClient();
    //Create an encoder so we can convert String to Bytes
    ASCIIEncoding encoder = new ASCIIEncoding();
    //Do the conversion
    byte[] buffer = encoder.GetBytes(myMessage.ToString());
    //Connect to the host using the command line argument provided
    client.Connect(args[0], Convert.ToInt16(args[1]));
    //Get our network stream
    NetworkStream stream = client.GetStream();
    //Write to our stream
    stream.Write(buffer, 0, buffer.Length);
    //Close everything
    stream.Close();
    client.Close();
    Console.WriteLine("Message was sent to host " + args[0] + " on port " + args[1]);
}
catch(System.Exception e)
{
    Console.WriteLine("Message was not sent");
} 

The message is sent to the server in the following format:

Timeout|Icon|Title|Message 

Points of Interest

This was one of the first C# projects I ever did, so I'm sure it's quite messy. I'm still learning about thread safety, delegates, and all the other interesting little "gotchas" that come along with the .NET Framework. I'm sure that there are a lot of things done wrong in this program.

Apparently, there is a min and max value for balloon timeouts. The timeout is somewhere between 10 and 30 seconds. You can specify a timeout in between those values and it will be obeyed. However, anything over or under those timeouts is ignored and a default timeout is used instead. The timeout counter doesn't seem to tick when the user is idle.

You can use any type of client that can send information over a socket.

History

  • October 22, 2007 - Posted

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Helbrax
Web Developer
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generali can't get any notifire to workmemberNoteNv1 Nov '07 - 0:29 
Cry | :(( I can't get any bubble messages to work.

 
Noted

GeneralRe: i can't get any notifire to workmemberHelbrax1 Nov '07 - 1:50 
Does the included program not work at all?
 
If not, make sure balloon tips are enabled. There is a registry setting that can turn them on/off
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\EnableBalloonTips
GeneralI can't get any bubble notifier to workmemberleajohnston23 Oct '07 - 6:51 
I hope this is just me, but I can't get any bubble messages to work.
I must be designing the form differently, can you include the form in the code?
 
Thanks
GeneralRe: I can't get any bubble notifier to workmemberHelbrax23 Oct '07 - 7:18 
Does the included program work?
GeneralRe: I can't get any bubble notifier to workmemberleajohnston24 Oct '07 - 8:06 
the attached zip contains the .cs code, and the complied .exe. - The executables work great and show what you are doing, but to recreate the project to work/change etc you need to have the forms created in the correct way.
Can you include your .Designer.cs files (or just the whole project with icons etc)?
Cheers!
GeneralRe: I can't get any bubble notifier to workmemberHelbrax24 Oct '07 - 8:57 
I've included the designer file and the icon. I can't include the entire project since it's part of a larger project.
GeneralRe: I can't get any bubble notifier to workmemberwilpeck30 Oct '07 - 5:46 
If you're running XP check to verify that balloon tips are enabled on your system by checking the following registry DWORD value exists and is set to 1.
 
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\EnableBalloonTips
 
HTH
QuestionPlease Help!!memberBaba Deep22 Oct '07 - 16:27 
Hi,
I want my c# .Net desktop application (running in one of client machine in same network as server) to receive a notification instantly from web server(LAMP) when some client logs into website.
 
I guess it must be possible, isn't it?....But How Frown | :(
 
Any hint, help would be greatly appreciated.
 
Thanks,
Deep.
AnswerRe: Please Help!!memberHelbrax23 Oct '07 - 3:01 
It should be pretty easy. You can see from my example how to set up a listener(or you can do a search for tcplistener and pull up the msdn documentation[it has examples]).
 
So in your C# application, set up a listener. Pick a port you want to listen to, and if you only want to receive alerts from that one server, put in that servers IP address. If you want to receive multiple IP addresses, you will want to use System.Net.IPAddress.Any. Only use this if you are on a private network as it opens that port up to possible unwanted traffic.
 
From your LAMP, I'm not sure if you are using perl, php or python. Either way, I'm sure all of them have the ability to write to sockets. For instance, in perl:

use IO::Socket;
 
$socket = IO::Socket::INET->new(PeerAddr => 'ip address of our listening machine',
PeerPort => port of your listening machine,
Proto => 'tcp',
) or die "$!";
$message = "This is my message";
$socket->send($message) or die "$!";
close($socket);

 
So in you LAMP app, whenever the user logs in, have that script run(or an equivilent script written in php/python/etc).
GeneralRe: Please Help!!memberBaba Deep24 Oct '07 - 15:19 
Thank you,
Really appreciated.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 22 Oct 2007
Article Copyright 2007 by Helbrax
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid