Author: | Mark Rowe |
---|---|
Contact: | bdash@users.sourceforge.net |
Version: | overview.txt 339 2005-02-06 06:50:39Z bdash |
Status: | Work in Progress |
This document contains a high level overview of libmsn 3.2. libmsn 3.2 is based on Meredydd Luff's libmsn 2.1, but is closer to a complete rewrite than a new version.
Communication with MSN Messenger takes place in connections to two primary types of servers. A connection is established with the notification server when you signed in, and this connection is maintained until you sign out of the service. Instant messages to other users take place after connecting to switchboard servers. A connection is made to a switchboard server for every conversation that you take part in.
The notification server is responsible for managing your online presence, buddy list, and dispatching invitations to join conversations to your buddies. It also notifies you of changes in your buddy's status, and when a buddy requests your presence in a chat.
The switchboard server's sole responsibility is the transmission of messages between buddies. Connections to the switchboard server map one-to-one to the concept of a conversation with one or more buddies. That is to say, a switchboard connection is opened for every conversation that you participate in.
For more detailed information about the MSN Messenger system, you should look to the hypothetic.org MSN Messenger protocol documentation.
libmsn is a single-threaded, asynchronous library that is written in C++. All of it's code is defined within the namespace MSN. In this documentation, the qualifying MSN:: will omitted for the sake of brevity.
All code that needs to access libmsn's functionality should use the following syntax to include it's headers:
#include <msn/msn.h>
Bare in mind that you will need to instruct your compiler to link to the libmsn library. This can be done by passing -lmsn as an argument to gcc.
Communication with libmsn is done via an object-oriented API and user-provided callback functions. An instance of a user-defined subclass of MSN::Callbacks should be passed to the NotificationServerConnection constructor. All callbacks are declared within msn/externals.h. All callbacks listed need to be defined, otherwise you will get linker errors when you attempt to build your program. Many of the callbacks can be defined as an empty function, but those listed under Required Callbacks need to be implemented with the documented semantics.
To use libmsn you need to be aware of several key classes.
Below is a list of the general program flow and interaction with libmsn.
Create a NotificationServerConnection with the correct username and password, and ask it to connect to messenger.hotmail.com on port 1863:
struct pollfd mySockets[32]; int numberOfSockets = 0; MSN::NotificationServerConnection *mainConnection; Callbacks cb; mainConnection = new MSN::NotificationServerConnect("myPassport@example.com", "myS3cr3t", cb); mainConnection->connect("messenger.hotmail.com", 1863);
libmsn will then register and unregister sockets to be checked for completed connections, available data, and writability by calling MSN::Callbacks::registerSocket and MSN::Callbacks::unregisterSocket one or more times as is appropriate.
Enter your main event loop. This may be based on select, poll, or a similar API that will notify you when data is available on a given socket:
poll(mySockets, numberOfSockets, -1);
Inform libmsn when data has a socket connection has completed, data has arrived on a socket, or a socket has become writable. This can be done by using the Connection object's socketConnectionCompleted, dataArrivedOnSocket, and socketIsWritable methods as is appropriate:
MSN::Connection *c; // Retrieve the connection associated with the // socket's file handle on which the event has // occurred. c = mainConnection->connectionWithSocket(mySockets[i].fd); // if this is a libmsn socket if (c != NULL) { // If we aren't yet connected, a socket event means that // our connection attempt has completed. if (c->isConnected() == false) c->socketConnectionCompleted(); // If this event is due to new data becoming available if (mySockets[i].revents & POLLIN) c->dataArrivedOnSocket(); // If this event is due to the socket becoming writable if (mySockets[i].revents & POLLOUT) c->socketIsWritable(); }
When a socket used by libmsn is closed, you should delete the Connection object that it is associated with:
MSN::Connection *c; // Retrieve the connection associated with the // socket's file handle on which the event has // occurred. c = mainConnection->connectionWithSocket(mySockets[i].fd); // if this is a libmsn socket if (c != NULL) { // Delete the connection. This will cause the resources // that are being used to be freed. delete c; }
These four steps are all that is required to use libmsn. Your program code can then use the API that is provided to manipulate your buddy list, request switchboard sessions, and send instant messages.
The following callbacks are required by libmsn to implement the documented semantics as they are used to integrate with your program:
All other callback functions may optionally be implemented. If you have no use for the callback, it may be defined as an empty function.
A switchboard connection is required for interaction with any other buddy on the MSN Messenger service.
You can use the NotificationServerConnection's requestSwitchboardConnection method to request a session. You may pass an optional piece of data as the tag argument so that you can identify this switchboard request:
// Request a switchboard session, using requestContext to allow // us to identify this session request void *requestContext = <some data>; mainConnection->requestSwitchboardConnection(requestContext);
MSN::Callbacks::gotSwitchboard will be called when the requested switchboard session is established.
Once you have established a switchboard session, you need to invite your receiving buddy into the session. You can do this by using the SwitchboardServerConnection's inviteUser method. Note that the buddy is not considered to have joined the session until MSN::Callbacks::buddyJoinedConversation has been called with the switchboard server and buddy as arguments.
When your switchboard session has been established, and buddies invited, you can then send an instant message. libmsn represents messages with it's Message class, so an instance needs to be created that contains the message that you wish to send. This instance will then allow you to control such things as the font and color that the message will appear in. The message can then be transmitted into the switchboard session by using the SwitchboardServerConnection's sendMessage method:
MSN::SwitchboardServerConnection *theSwitchboard = <a switchboard connection>; MSN::Message msg(myMessageText); msg.setFontName("Courier New"); msg.setFontEffects(MSN::Message::ITALIC_FONT); theSwitchboard->sendMessage(&msg);