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

MSN Messenger Activities with simulated asynchronous webservice calls

By , 22 Dec 2005
Rate this:
Please Sign up or sign in to vote.

Peers communicating with each other and a Web Server

Introduction

Microsoft has made it possible for developers to write their own MSN Messenger Activities. These activities are peer to peer since each user is connected through the MSN Messenger network. They can also be client to server at the same time since the activity web page is hosted on your own server. In this article, I will discuss some of the code that is specific to MSN Messenger peer to peer communication as well as a trick or two I used in my own activity (CodeTalk) to overcome some of the restrictions that Microsoft set on these web pages by default, i.e. no ActiveX.

Background

Peer to peer software is where an application allows people on the Internet to communicate with each other (usually in real time) rather than simply communicating with a server. Examples of these types of applications would include chat, file sharing, and white boarding. The MSN Messenger system is a peer to peer application that offers all of these abilities and a lot more. To enable the peer to peer capability to activity authors, MSN Messenger provides some objects that can be called to gather information about the session as well as send/receive data between the peers.

Using the code

MSN Messenger is an Internet Explorer host. As such, it can expose an additional object model to any code (JavaScript) running inside a web page within MSN Messenger. At present, the objects exposed are...

  • Channel object - Contains properties, methods, and events for sending and receiving data and for interacting with the MSN® Messenger Chat History window.
  • Error object - Contains properties for presenting error information to the user.
  • FileInfo object - Contains properties for determining the status of a file transfer.
  • Messenger object - Contains methods for launching MSN Messenger client dialog pages.
  • User object - Contains properties for ascertaining the user name, e-mail address, and the Microsoft® .NET Passport Unique ID (PUID) of conversants.
  • Users collection - The top-level collection of User objects.

Sending information to a peer is as simple as the following code snippet ...

window.external.Channel.SendData("Some data");

and receiving data requires implementing an event handler like this...

function Channel_OnDataReceived()
{
    var myData;
    
    myData=window.external.Channel.Data;
}

That is really the meat of communicating back and forth between peers. You can get as complex as you want in deciding what data to send and how to parse it out on the other end of the connection, then taking an action based on the data received. There are a lot of possibilities here. Games and various kinds of collaboration tools such as shared searching or web browsing come quickly to mind. Microsoft puts a limit on how much data you can send over their network within a specific period of time. Currently, this is 1,664 bytes per packet and a maximum bandwidth of 120 packets per minute (two per second). This may not sound like a lot of data, however, it actually is quite a bit of data, and with a little creativity, you can find ways to enhance your performance using techniques such as caching or look up tables.

In the case of my activity, CodeTalk, I wanted to incorporate the MSN Search Webservice to do on-the-fly searching based on what text the user currently had highlighted. My first attempt used the webservice.htc behavior. This behavior allows a web page to make asynchronous web service calls over the Internet instead of refreshing a web page to get new results. Now, there are two issues with this. One is that you cannot call Microsoft's webservices from your own web page because you are not allowed to call outside of your own domain (www.YourDomain.com) for security reasons. Second is that this webservice.htc behavior uses an ActiveX object built into IE, and MSN Messenger, by default, does not give this permission. However, the feature I was building just was not professional without being executed asynchronously. So to get around these issues, I came up with a little trick I show you here.

Simulated WebMethod call.

This trick implements an asynchronous web service call without using any ActiveX and without any real web service! Here are the main points...

  • Add an iFrame to your web page that is hidden (style=display:none).
  • To make a "web service" call, set the iFrame's src property to point at an ASPX page on your web server. Be sure to pass any method parameters as query string variables (http://domain.com/somepage.aspx?Param1=123&Param2=456).
  • The ASPX page calls the MSN Search web service from your server.
  • The ASPX page formats the results to return to the iFrame and wraps the results in some HTML + JavaScript that fires an event as soon as the iFrame is finished loading.
  • The event that fires upon iFrame load takes the contents of the iFrame and inserts them into the body of a TextArea in the parent page (since iFrames can talk to their parent page, but the parent cannot access the contents of an iFrame for security reasons).
  • Hook to the OnPropertyChanged event on the TextArea in the parent page so that you are notified when the results are returned in the iFrame.
  • Treat the innerText property of the TextArea just like you would the results of a web method call.

This is the HTML + JavaScript that your ASPX page wraps your web method results with before sending it up to the iFrame:

<HTML><body id=bdy 
  onload=window.parent.document.all.myTextArea.innerText=bdy.innerHTML;>
  YOUR_RESULTS</body></HTML>

When the iFrame is finished loading the results returned from your ASPX page, the OnLoad event will fire which makes the innerHTML of the iFrame body get put into the innerText of the TextArea in your parent page.

Your TextArea tag in the parent page should look something like this...

<TEXTAREA id="myTextArea" 
   onpropertychange="AfterWebMethod();" style=display:none;></TEXTAREA>

And your AfterWebMethod() handler function should check to see if the myTextArea innerText length is greater than zero. If it is then your AfterWebMethod() handler function was called not because of some random property change, but because you have received data back. Also, remember to set the innerText back to an empty string "" so that you can tell when you get more data back from future web method calls.

function AfterWebMethod()
{
    if(myTextArea.innerText.length>0)
    {
        //Do something with the innerText contents
        
        //Be sure to reset the innerText for next time
        myTextArea.innerText = "";
    }    
}

More tips

Another useful trick when making MSN Messenger Activities can be the ability to simulate a mouse pointer on the other user's screen. The technology used to do this is built right into Internet Explorer. This technology is called VML (Vector Markup Language). The following code will show how to create a function that will draw what looks like a mouse pointer on screen at any point you want.

In the OnLoad event of your web page, use the following code to hook to the body tag's OnMouseMove event...

document.body.onmousemove = MouseMoved;

Now, you will get alerted each time the mouse moves over the body of your page. If you prefer, you can limit this event to a smaller part of your page such as a DIV by hooking to the DIV's OnMouseMove event instead.

The MouseMoved JavaScript function looks like this...

function MouseMoved()
{
    //Get the X and Y with a small adjustment 
    //to get the actual tip of the pointer    
    var mLeft = event.clientX-2;    
    var mTop = event.clientY-7;    
    
    //Create a pipe (|) delimited string that 
    //will hold all the data needed to recreate 
    //the mouse pointer on the other peers
    var data = "";
    data += mLeft + "|" + mTop;
    data += "|" + document.body.clientWidth + "|" + 
                  document.body.clientHeight;    
    
    //Send this data to other peers
    window.external.Channel.SendData(data);
}

Now, you need to capture this data on the peers and parse out the data.

function Channel_OnDataReceived()
{
    var myData;
    
    myData=window.external.Channel.Data;
    
    //Split on the pipe (|) delimiter into an array
    var mouseData = myData.split("|");    
    
    //Call MoveMouse to draw the mouse in the correct location
    MoveMouse(parseInt(mouseData[0]), parseInt(mouseData[1]), 
              parseInt(mouseData[2]), parseInt(mouseData[3]));
}

Finally, let's take a look at the MoveMouse function. This code takes the difference between the BODY on the sender peer with the BODY of the receiver peer and gets a ratio-ed equivalent on the receiver peer. This may not exactly fit your needs but with some small tweaks, you should get good results.

function MoveMouse(x, y, clientWidth, clientHeight)
{    
    var xRatio = 0;
    var yRatio = 0;    
    var prevX = 0;
    var prevY = 0;
    
    var myWidth = parseInt(document.body.clientWidth);
    var myHeight = parseInt(document.body.clientHeight);
    
    //Reposition the pointer to take into account 
    //different screen sizes between peers
    
    //find the ratio between the incoming peers 
    //client area and my client area
    xRatio = myWidth/clientWidth;
    yRatio = myHeight/clientHeight;
    
    //Move the incoming X and Y
    x = (x + ((myWidth)-(clientWidth*xRatio))*xRatio);
    y = (y + ((myHeight)-(clientHeight*yRatio))*yRatio);
        
        
    //Arrange the VML lines into a mouse pointer 
    //and move to the x,y
    line1.from = x + "," + y;
    line1.to = x + 12 + "," + (y + 11);
    prevX = x + 15;
    prevY = y + 12;
    line2.from = line1.to;
    prevX -= 8;
    prevY -= 1;
    line2.to = prevX + "," + prevY;
    line3.from = line2.to;
    prevX += 4;
    prevY += 8;
    line3.to = prevX + "," + prevY;
    line4.from = line3.to;
    prevX -= 3;
    prevY += 1;
    line4.to = prevX + "," + prevY;
    line5.from = line4.to;
    prevX -= 4;
    prevY -= 8;
    line5.to = prevX + "," + prevY;
    line6.from = line5.to;
    prevX -= 4;
    prevY += 5;
    line6.to = prevX + "," + prevY;
    line7.from = line6.to;
    line7.to = line1.from;
}

Don't forget to include the VML tags for the lines that make up the pointer...

<!--[if !mso]>
<STYLE>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</STYLE>
<![endif]-->

<v:line id="line1" from="7500pt,7500pt" to="7500pt,7500pt"></v:line>
<v:line id="line2" from="7500pt,7500pt" to="7500pt,7500pt"></v:line>
<v:line id="line3" from="7500pt,7500pt" to="7500pt,7500pt"></v:line>
<v:line id="line4" from="7500pt,7500pt" to="7500pt,7500pt"></v:line>
<v:line id="line5" from="7500pt,7500pt" to="7500pt,7500pt"></v:line>
<v:line id="line6" from="7500pt,7500pt" to="7500pt,7500pt"></v:line>
<v:line id="line7" from="7500pt,7500pt" to="7500pt,7500pt"></v:line>

And put this at the top of your page instead of a regular <html> tag...

<html xmlns:v="urn:schemas-microsoft-com:vml" 
           xmlns:o="urn:schemas-microsoft-com:office:office">

Points of Interest

  • Easy peer to peer programming API from Microsoft via their MSN Messenger.
  • A simple example of the power of the future of the web SOA (Service Oriented Architecture) where applications call web services which turn around and call other web services (server-to-server) such as the MSN Search web service.
  • A technique for performing asynchronous web method calls that do not require using the webservice.htc behavior nor the XMLHTTP object.
  • A technique for simulating a mouse pointer on a peer that matches the mouse movements from a source peer.

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

About the Author

Gerald Gibson Jr
Web Developer
United States United States
I have been coding since 4th grade in elementary school back in 1981. I concentrate mainly on Microsoft technologies from the old MSDOS/MSBASIC to coding in VC++ then Visual Basic and now .Net. I try to stay on top of the trends coming from Microsoft such as the Millennium Project, Windows DNA, and my new favorite Windows clustering servers.
 
I have dabbled in making games in my initial VC++ days, but spent most of the past 10 years working on business apps in VB, C++, and the past 7 years in C#.
 
I eventually hope to get my own company supporting me so I can concentrate on my real dream of creating clusters of automated robots for use in various hazardous industries.

Comments and Discussions

 
Questionhow to send an activity request with dotMSN in C# PinmemberLisa_qiao2-Nov-08 14:48 
QuestionCan we implement window.external.Channel.SendData with MFC ? PinmemberEureka Jim19-Dec-07 15:50 
QuestionHow Do I Connect This To MSN Messenger PinmemberRStern20-Mar-07 12:40 
AnswerRe: How Do I Connect This To MSN Messenger PinmemberGerald Gibson Jr20-Mar-07 15:48 
GeneralRe: How Do I Connect This To MSN Messenger PinmemberAchou!!!5-Mar-08 4:55 
GeneralVery useful Pinmemberrajantawate1(www.jhatak.com)8-Oct-06 15:08 
GeneralExcellent article Gerald -- one question PinmemberDonovan_Dillon19-Feb-06 11:26 
I just reviewed the MSN Messenger Activities documentation on MSDN and noticed that there was a size limit (500x500 px I believe) on the messenger web page. Does this technique get around this limitation?
 
Donovan.
GeneralRe: Excellent article Gerald -- one question PinmemberGerald Gibson Jr19-Feb-06 13:32 
GeneralRe: Excellent article Gerald -- one question PinmemberDonovan_Dillon19-Feb-06 13:48 
GeneralRe: Excellent article Gerald -- one question PinmemberGerald Gibson Jr19-Feb-06 13:59 
GeneralRe: Excellent article Gerald -- one question PinmemberDonovan_Dillon19-Feb-06 15:04 
GeneralAwsome application and a quick question PinmemberGreenMask1-Feb-06 5:44 
GeneralRe: Awsome application and a quick question PinmemberGerald Gibson Jr1-Feb-06 5:47 
GeneralVOIP recorder Pinmembertriplebit4-Jan-06 7:58 
GeneralRe: VOIP recorder PinmemberGerald Gibson Jr4-Jan-06 8:02 
GeneralRe: VOIP recorder Pinmembertriplebit4-Jan-06 8:49 
GeneralRe: VOIP recorder PinmemberGerald Gibson Jr4-Jan-06 8:51 
QuestionSource? Pinmemberbhughes1022-Dec-05 9:00 
AnswerRe: Source? PinmemberGerald Gibson Jr22-Dec-05 9:03 
GeneralGood Topic Pinmembercraso18-Dec-05 5:18 
GeneralRe: Good Topic PinmemberGerald Gibson Jr18-Dec-05 5:23 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140421.2 | Last Updated 22 Dec 2005
Article Copyright 2005 by Gerald Gibson Jr
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid