Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#
Article

An MSN Messenger Log Listener

Rate me:
Please Sign up or sign in to vote.
4.66/5 (19 votes)
6 Feb 20066 min read 130.9K   1.5K   71   16
A custom log listener for the Microsoft Enterprise Library Logging framework.

The code download has been updated for the final release of the Enterprise Library, including design support for the EntLibConfig application.

Introduction

A group of programmers, far smarter than I, have been laboring from some time to create a library of utilities to help developers like myself to create better applications. The fruits of that labor is the Enterprise Library from the Patterns & Practices group at Microsoft. The Enterprise Library encompasses Exception Handling, Logging, Caching, Security, Cryptography, and Database Access. The latest incarnation of the Enterprise Library for the .NET 2.0 Framework also includes an ObjectBuilder which allows object creation with dependency injection. I'd be lying to you if I told you I understand exactly what the ObjectBuilder does. Brian Button has released the most complete information I have found so far on the ObjectBuilder. Documentation is scarce at this point since the Enterprise Library has not been officially released. The code covered in this article is based on the December Community Technology Preview of the new Enterprise Library for the .NET Framework 2.0.

The focus of this article is the Logging bits from the Enterprise Library. For an overview of the Logging framework, check this MSDN documentation. One of the functions of the Logging framework is to send log messages to one or more listeners like a flat file, an email message, a database, or a Microsoft Message Queue. The Logging framework was constructed in such a way to allow developers like myself to create custom listeners for log messages. If you haven't already guessed, I made a custom log listener that sends log messages to an MSN Messenger account.

The good stuff

I used the FormattedDatabaseTraceListener as a reference for creating my listener. The custom listener is actually composed of three classes:

  • The actual listener class, responsible for sending log messages as MSN Messenger messages.
  • A data configuration class, responsible for reading configuration data from a CONFIG file (app.config/web.config).
  • An assembler class, responsible for creating a listener object based on a configuration class (I think this is the ObjectBuilder magic).

Our listener class is the FormattedMsnMessengerTraceListener which I will cover in depth. FormattedMsnMessengerTraceListenerData and FormattedMsnMessengerTraceListenerAssembler handle the configuration and assembly of the custom listener. These two classes are largely self-explanatory but if you have any questions, please post them and I will answer as best as I can.

FormattedMsnMessengerTraceListener

To send MSN Messenger messages, I searched the internet for existing solutions, and found a sweet library created by XIH Solutions called DotMSN. DotMSN provides a managed code library for creating custom MSN Messenger clients. My custom log listener acts as a stripped down client that only sends messages.

Image 1

Image 2

ctor

The constructor initializes all of the data used by our listener and starts the process for connecting to the MSN Messenger server. The configuration values for the listener are outlined below:

senderAccountthe MSN Messenger account to use for sending log messages.
senderPasswordthe password for the account specified above.
receiverAccountsa semi-colon (;) delimited list of MSN Messenger accounts that will receive log messages.
connectionRetryInterval(optional) the time in minutes between connection attempts. Default value = 5 minutes.
invitationRetryInterval(optional) the time in minutes between invitation attempts. Default value = 5 minutes.
maxMessageQueue(optional) the maximum number of messages to queue for delivery. If this value is exceeded, the oldest message is removed from the queue before adding the latest message. Default value = 5 messages.

public override void Write( string sMessage )

The Write method is called by the Logging framework whenever a developer wishes to log information. Our implementation first queues the message:

C#
if (String.Empty != sMessage)
{
  if (_iMaxMessageQueue <= _messageQueue.Count)
  {
    _messageQueue.Dequeue();
  }
  _messageQueue.Enqueue(sMessage);
}

Messages are queued because it takes time to connect to the MSN Messenger (usually 3-4 seconds depending on the connection speed). Messages are also queued in the event that all of the message receivers are offline. For this reason, you should not rely on the MSN Messenger log listener as your primary log listener. If all recipients are offline, then the log messages will be lost. The sample console application included in the code download uses both a flat file listener and an MSN Messenger listener.

The DotMSN library uses multiple threads and delegates to notify developers of the various Messenger related events. I make no claims of being a multithreaded developer so there may be better ways to synchronize events between the DotMSN library and my custom listener. The next bit of code synchronizes any exceptions thrown by the DotMSN library, propagating them to the Enterprise Library Logging framework:

C#
if (null != _thrownException)
{
  lock (_oExceptionLock)
  {
    if (null != _thrownException)
    {
      try
      {
        throw _thrownException;
      }
      finally
      {
        _thrownException = null;
      }
    }
  }
}

The last step before logging the message is to ensure we have a valid connection to the MSN Messenger server and a valid MSN conversation with at least one recipient connected. These two conditions are validated by two helper methods covered later. If all is well, any queued messages are sent to the recipients:

C#
if (true == _EnsureConnection() && true == _EnsureConversation())
{
  while (0 < _messageQueue.Count)
  {
    TextMessage message = 
              new TextMessage(_messageQueue.Dequeue());
    _conversation.Switchboard.SendTextMessage(message);
  }
}

bool _EnsureConnection()

I developed my custom listener with the understanding that an application that takes advantage of the Enterprise Library Logging framework may be running 24/7 but log message recipients might not be connected to the MSN Messenger network 24/7. With that in mind, the _EnsureConnection() method checks to see if it is currently connected to the MSN Messenger network. If it is, it returns true:

C#
if (true == _messenger.Connected && 
    true == _messenger.Nameserver.IsSignedIn )
{
  return true;
}

If there is no connection to the network, first we check to see if we are in the process of connecting. If we are not connecting, we initiate a connection. The final check is to cover the eventuality of a network outage or dropped connection. If we are in the process of connecting but it has been more than five minutes (by default) since we started connecting, then start the connection process over again:

C#
if (false == _bConnecting)
{
  lock (_oConnectingLock)
  {
    if (false == _bConnecting)
    {
      _messenger.Disconnect();
      _bConnecting = true;
      _dtLastConnectionAttempt = DateTime.Now;
      _messenger.Connect();
    }
  }
}
else if( _tsConnectionRetryInterval <= 
         (DateTime.Now - _dtLastConnectionAttempt) )
{
  lock (_oConnectingLock)
  {
    _bConnecting = false;
  }
}

bool _EnsureConversation()

This method performs much the same operation as _EnsureConnection(), only rather than checking for a connection, we check for an existing conversation with participants. If one does not exist, we initiate the process to create a Conversation:

C#
if (null != _conversation && 
    0 < _conversation.Switchboard.Contacts.Count)
{
  return true;
}

if (false == _bInviting)
{
  lock (_oInvitingLock)
  {
    if (false == _bInviting)
    {
      _bInviting = true;
      _dtLastInvitationAttempt = DateTime.Now;
      foreach (string receiver in _sReceiverAccounts)
      {
        _conversation.Invite(receiver);
      }
    }
  }
}
else if ( _tsInvitationRetryInterval <= 
          (DateTime.Now - _dtLastInvitationAttempt) )
{
  lock (_oInvitingLock)
  {
    _bInviting = false;
  }
}

DotMSN events

The last portions of the custom listener are handlers for DotMSN events, including raised exceptions, successfully signing into the MSN Messenger network, and signals for when a recipient joins a conversation.

Testing

Testing the listener is a little tricky because you cannot sign-in to MSN Messenger twice using the same account. I had to have my wife log into MSN Messenger using her account, then configured the listener to use my account as the Sender account. So, long story short, you will need two MSN accounts to test the listener.

Image 3

EntLibConfig

I added a new project to the code to support the EntLibConfig application that comes with the Enterprise Library. You can now use the graphical configuration editor to add/modify an MSN Messenger Trace Listener to your application. To use EntLibConfig, you need to copy WCPierce.Practices.EnterpriseLibrary.Logging.MsnMessenger.Configuration.Design.dll, WCPierce.Practices.EnterpriseLibrary.Logging.MsnMessenger.dll, and XihSolutions.DotMSN.dll to the same directory as EntLibConfig.exe. You should then be able to add an MSN Messenger Trace Listener. See the graphic below for an example:

Image 4

Conclusion

The FormattedMsnMessengerTraceListener was a fun exercise in creating a custom log listener for the Enterprise Library Logging framework. As I stated above, please don't rely on this listener for anything critical. It is most useful when coupled with the Exception Handling framework for instant notification of any critical errors that crop up in your applications (that never happens right?). I encourage you to download the code and checkout the listener, and I would love to hear from anyone who finds it useful enough to use it in their applications.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionupdates ? Pin
kiquenet.com30-Mar-11 21:40
professionalkiquenet.com30-Mar-11 21:40 
Generalbad word filter to protect my kids. Pin
ZUPERKOOL7-Feb-10 6:38
ZUPERKOOL7-Feb-10 6:38 
a warm hello to all msn gurus Smile | :)

hi i am trying to develop a badword filter for msn/messenger to help protect my kids from bad words... "yes those words ...that later i we have to make up a fake definition when they ask dad what is the meaning of f**k :x"

anyways, i started using winpcap to capture the incoming socket but later found out that since sp2 xp will not allowed this"

the big question:

while reading this article it came to my attention that maybe i could filter at the application level....

do you think if taking this/your aproche would eventually end up in a simple badword_filter.dll.

thanks


Ivo Gomez
http://ivogomez.com




QuestionGreat article - couple of questions... [modified] Pin
Stuart Roberts11-Aug-08 19:25
Stuart Roberts11-Aug-08 19:25 
AnswerRe: Great article - couple of questions... Pin
kiquenet.com30-Mar-11 21:40
professionalkiquenet.com30-Mar-11 21:40 
GeneralMyHAL: Jabber bot Pin
jcmag4-Jun-07 3:09
jcmag4-Jun-07 3:09 
Generalshared hosting Pin
Lim2210220-Jan-07 20:26
Lim2210220-Jan-07 20:26 
GeneralHint for using Pin
ender++28-Jan-06 17:43
ender++28-Jan-06 17:43 
GeneralRe: Hint for using Pin
Bill Pierce4-Feb-06 12:26
Bill Pierce4-Feb-06 12:26 
GeneralFramework 1.1 Pin
Benkat27-Jan-06 1:15
Benkat27-Jan-06 1:15 
Question[Message Deleted] Pin
zero157819-Jan-06 10:12
zero157819-Jan-06 10:12 
AnswerRe: Can this be used with Enterprise Windows Messenger instead? Pin
Bill Pierce20-Jan-06 3:27
Bill Pierce20-Jan-06 3:27 
GeneralNot Good cause... Pin
Trance Junkie13-Jan-06 0:01
Trance Junkie13-Jan-06 0:01 
GeneralRe: Not Good cause... Pin
Bill Pierce13-Jan-06 3:09
Bill Pierce13-Jan-06 3:09 
GeneralNice idea..... But... Pin
Ian Powell12-Jan-06 22:41
Ian Powell12-Jan-06 22:41 
GeneralRe: Nice idea..... But... Pin
Bill Pierce13-Jan-06 3:06
Bill Pierce13-Jan-06 3:06 
GeneralRe: Nice idea..... But... Pin
Preky14-Feb-06 20:53
Preky14-Feb-06 20:53 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.