Click here to Skip to main content
6,630,586 members and growing! (16,290 online)
Email Password   helpLost your password?
Web Development » Client side scripting » General     Intermediate

MSN Messenger Activities with simulated asynchronous webservice calls

By Gerald Gibson Jr

How to write peer-to-peer + client server applications using the MSN Messenger.
Javascript, HTML, Windows, Visual Studio, Dev
Posted:16 Dec 2005
Updated:22 Dec 2005
Views:49,396
Bookmarked:55 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
7 votes for this article.
Popularity: 3.67 Rating: 4.35 out of 5
1 vote, 14.3%
1

2
1 vote, 14.3%
3
2 votes, 28.6%
4
3 votes, 42.9%
5

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


Member
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.

**************************************
CodeTalk <<< Check this out if you write code!
Code Encrypter instead of Obfuscator for C# or VB.NET
-Now LIVE!
Occupation: Web Developer
Location: United States United States

Other popular Client side scripting articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 21 of 21 (Total in Forum: 21) (Refresh)FirstPrevNext
Generalhow to send an activity request with dotMSN in C# PinmemberLisa_qiao15:48 2 Nov '08  
GeneralCan we implement window.external.Channel.SendData with MFC ? PinmemberEureka Jim16:50 19 Dec '07  
GeneralHow Do I Connect This To MSN Messenger PinmemberRStern13:40 20 Mar '07  
GeneralRe: How Do I Connect This To MSN Messenger PinmemberGerald Gibson Jr16:48 20 Mar '07  
GeneralRe: How Do I Connect This To MSN Messenger PinmemberAchou!!!5:55 5 Mar '08  
GeneralVery useful Pinmemberrajantawate1(www.jhatak.com)16:08 8 Oct '06  
GeneralExcellent article Gerald -- one question PinmemberDonovan_Dillon12:26 19 Feb '06  
GeneralRe: Excellent article Gerald -- one question PinmemberGerald Gibson Jr14:32 19 Feb '06  
GeneralRe: Excellent article Gerald -- one question PinmemberDonovan_Dillon14:48 19 Feb '06  
GeneralRe: Excellent article Gerald -- one question PinmemberGerald Gibson Jr14:59 19 Feb '06  
GeneralRe: Excellent article Gerald -- one question PinmemberDonovan_Dillon16:04 19 Feb '06  
GeneralAwsome application and a quick question PinmemberGreenMask6:44 1 Feb '06  
GeneralRe: Awsome application and a quick question PinmemberGerald Gibson Jr6:47 1 Feb '06  
GeneralVOIP recorder Pinmembertriplebit8:58 4 Jan '06  
GeneralRe: VOIP recorder PinmemberGerald Gibson Jr9:02 4 Jan '06  
GeneralRe: VOIP recorder Pinmembertriplebit9:49 4 Jan '06  
GeneralRe: VOIP recorder PinmemberGerald Gibson Jr9:51 4 Jan '06  
GeneralSource? Pinmemberbhughes1010:00 22 Dec '05  
GeneralRe: Source? PinmemberGerald Gibson Jr10:03 22 Dec '05  
GeneralGood Topic Pinmembercraso6:18 18 Dec '05  
GeneralRe: Good Topic PinmemberGerald Gibson Jr6:23 18 Dec '05  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 22 Dec 2005
Editor: Smitha Vijayan
Copyright 2005 by Gerald Gibson Jr
Everything else Copyright © CodeProject, 1999-2009
Web10 | Advertise on the Code Project