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.
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
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
Sending information to a peer is as simple as the following code snippet ...
and receiving data requires implementing an event handler like this...
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.
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 (
- To make a "web service" call, set the
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 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
- Treat the
innerText property of the
TextArea just like you would the results of a web method call.
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.
TextArea tag in the parent page should look something like this...
AfterWebMethod() handler function should check to see if the
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.
myTextArea.innerText = "";
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.
OnLoad event of your web page, use the following code to hook to the body tag's
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
OnMouseMove event instead.
var mLeft = event.clientX-2;
var mTop = event.clientY-7;
var data = "";
data += mLeft + "|" + mTop;
data += "|" + document.body.clientWidth + "|" +
Now, you need to capture this data on the peers and parse out the data.
var mouseData = myData.split("|");
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);
xRatio = myWidth/clientWidth;
yRatio = myHeight/clientHeight;
x = (x + ((myWidth)-(clientWidth*xRatio))*xRatio);
y = (y + ((myHeight)-(clientHeight*yRatio))*yRatio);
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...
<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
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
- A technique for simulating a mouse pointer on a peer that matches the mouse movements from a source peer.