AIMCC Technote 9
DIM (Direct IM)
Q: What is DIM?
A: DIM is a session type of IAccImSession. It is similar to standard IM, with these key differences:
- As in most other secondary sessions, an invitation must be sent and accepted to establish a connection.
- The connection is peer-to-peer. It does not go through AOL servers unless both endpoints are behind firewalls, in which case it may go through an AOL relay server.
- IMs can be unlimited length.
- IMs can contain embedded data (images and other data).
- Rate limits do not apply to IMs.
Q: How does one initiate a DIM session?
A:
- To start a new DIM IAccImSession, call IAccSession's CreateImSession(<remote username>, AccImSessionType_DirectIm,...).
- If one is already in a standard IM session with a remote user, the session can be rolled over to DIM. To initiate rollover, call the IAccImSession's ProposeChange(AccImSessionType_DirectIm).
- OnInviteResult, OnParticipantJoined, OnParticipantLeft and OnSecondarySessionStateChange events fire, as appropriate, just as in other secondary sessions.
Q: How does one handle a DIM session invitation?
A:
- Handle the OnNewSecondarySession and OnSecondarySessionStateChange(AccSecondarySessionState_ReceivedProposal, S_OK) events as you would for any secondary session.
- Call IAccSecondarySession's Accept() or Reject().
- OnInviteResult, OnParticipantJoined, OnParticipantLeft and OnSecondarySessionStateChange events fire, as appropriate, just as in other secondary sessions.
Q: How does one embed data in an IM?
A:
- Build the markup (xhtml is recommended, but AOL-RTF can also be used). Wherever an embed occurs, insert an img tag and create an IAccStream with the embedId.
- To create a stream for a file, call IAccSession's CreateStream(OLESTR("file://<absolute path>"),...). To create a stream from memory, call AccStreamCreateFromMemory(); flags can contain ACC_STREAM_CREATE_FLAGS_NOCOPY.
- Create an IM by calling IAccSession's CreateIm().
- Call the IAccIm's SetStream() for each embed.
- Call the IAccImSession's SendIm().
- You can monitor embed upload progress via OnEmbedUploadProgress and OnEmbedUploadComplete events.
- You cannot send another IM in this IAccImSession until uploads complete.
Q: How does one receive embedded data in an IM?
A:
- When parsing IM markup (xhtml is recommended, but AOL-RTF can also be used), look for img tags with src="aoldim:...". You may also implement a pluggable protocol handler for aoldim: URLs.
- When a DIM img tag is found, parse the embedId and call the IAccIm's GetStream(embedId).
- Call the IAccStream's SetAsyncListener() to specify an IAccStreamListener to receive stream events.
- When the IAccStreamListener's OnDataAvailable fires, call the IAccStream's Read() method to read data. Read() returns E_PENDING if there is no more data available or S_FALSE when all data have been read.
- You can monitor embed download progress via OnEmbedDownloadProgress and OnEmbedDownloadComplete events.
- Embeds can be any data format.
- DIM UI should allow users to save embeds as files.
Q: What attributes does a DIM img tag have in xhtml?
A:
- src="aoldim:/c/e", where c is the IM cookie and e is the embedId. The cookie can be obtained via the IAccIm's get_Property(AccImProp_Cookie,...).
- alt="<name>"
- width="w", where w is the embedded image width in pixels, or 0 if the embed is not an image. Note: Some older applications don't specify width even for images, so code should fallback to determining width from data.
- height="h", where h is the embedded image height in pixels, or 0 if the embed is not an image. Note: Some older applications don't specify height even for images, so code should fallback to determining height from data.
- datasize="d", where d is the embed's number of bytes
Q: What is an embedId?
A: It uniquely identifies an embed within a particular IAccIm. For historical reasons, embedIds are one-based numbers (the first embed in an IAccIm has id "1", the next embed has id "2", etc.).
Q: How can I tell how many streams there are in an IAccIm?
A: Call the IAccIm's get_Property(AccImProp_StreamCount,...).
Q: How do I implement embed suppression?
A:
- Find out whether an incoming IAccIm contains embeds by calling the IAccIm's get_Property(AccImProp_ContainsImages,...).
- If the IAccIm contains embeds, ask the user whether to display embeds.
- Call the IAccIm's put_Property(AccImProp_AllowImages,...).
Q: How does one support the embedded image navigation feature that AIM 6 has?
A: This is not a feature of AIMCC. AIM 6 implemented a custom protocol on top of the DIM feature. If there is enough interest, we may be able to document the protocol.
Q: How can I tell when a DIM session ends, and how can I tell when a DIM session fails to start?
A: In both cases, the OnSecondarySessionStateChange event fires. Unlike the way most secondary sessions end, when a DIM session ends the state is AccSecondarySessionState_Online because it rolls over to AccImSessionType_Im. To distinguish between a DIM session that ended and a DIM session that failed to start, callers must maintain their own state variable. For example, one can observe when the session state changes to AccSecondarySessionState_Online while the session type is AccImSessionType_DirectIm, and set a flag.
rev. 2007/03/11