Microsoft DirectX 9.0 SDK Update (Summer 2003) |
Peer-to-Peer Host Messages
This document describes how to handle Microsoft® DirectPlay® messaging for the host of a peer-to-peer session. It discusses only those messages that are specific to a host. For a discussion of messaging for a normal peer, see Handling Standard Peer-to-Peer Messages. For a discussion of general messaging issues, see Handling DirectPlay Messaging.
Starting a Session
You can set up a peer-to-peer session in two ways:
- Arrange the session in advance. For example, you can use an online lobby to collect a group of players prior to starting the session. The player selected as host is responsible for calling IDirectPlay8Peer::Host to start the session. The lobby typically provides the host's address to the other players, and they use that address to connect directly to the session. Players usually need not do a host enumeration. For details on how to handle lobbies, see DirectPlay Lobby.
- Create a stand-alone session. When a player does a host enumeration, an enumeration query is sent to every host at a specified network location, which matches the player's description of the type of session they want to join. If the host chooses to respond, the host passes the player the information needed to connect to the session. With a stand-alone session, there is no need for a lobby. The host calls IDirectPlay8Peer::Host and assembles the group of players by responding to enumeration queries and connection attempts.
In either case, you must start the session by calling IDirectPlay8Peer::Host. When you start the session, you must be prepared to handle the following messages:
- DPN_MSGID_ENUM_HOSTS_QUERY
If you have started a stand-alone session, a potential player must be able find it before the player can connect. Players who are looking for a stand-alone session call IDirectPlay8Peer::EnumHosts to enumerate the available sessions. They indicate the type of session they are interested in by filling in the guidApplication member of the DPN_APPLICATION_DESC structure. They can also specify the network location they are interested in by adding the appropriate items to the host address object, which is passed to the pdpaddrHost parameter of IDirectPlay8Peer::EnumHosts. For more information about how to handle DirectPlay address objects, see DirectPlay Addressing.
During enumeration, DirectPlay sends each available host a DPN_MSGID_ENUM_HOSTS_QUERY that includes the address of the player requesting the enumeration. If the player specified an application globally unique identifier (GUID), this message will go to only those hosts that have specified the same GUID. If the player does not specify an application GUID, DirectPlay will send DPN_MSGID_ENUM_HOSTS_QUERY to all available hosts at the specified network location.
You can accept the enumeration request by having your handler return DPN_OK. DirectPlay will then pass information about the session, specifically your address and the DPN_APPLICATION_DESC structure, to the player. You can also provide some application-specific data to the player by assigning a data buffer to the DPNMSG_ENUM_HOSTS_QUERY structure's pvResponse member. When this buffer is no longer needed, DirectPlay notifies you that it is safe to free the buffer by sending you a DPN_MSGID_RETURN_BUFFER message.
You can reject the enumeration request by having your message handler return a value other than DPN_OK. In that case, no information will be sent to the player. If you reject an enumeration request, there is no need for a response buffer, and you will not receive a DPN_MSGID_RETURN_BUFFER message.
Note You can receive a DPN_MSGID_ENUM_HOSTS_QUERY message at any time while you are a host. If you are hosting an arranged session, or do not want to add any more players, you must still handle this message and reject the enumeration request. - DPN_MSGID_INDICATE_CONNECT
Once a player has the address of a host, the player can attempt to connect to that session by calling IDirectPlay8Peer::Connect. The session host then receives a DPN_MSGID_INDICATE_CONNECT message with information about the player.
To accept a player's connection request, have your DPN_MSGID_INDICATE_CONNECT message handler return DPN_OK. As with DPN_MSGID_ENUM_HOSTS_QUERY, you can also return a data buffer to the player by assigning it to the DPNMSG_INDICATE_CONNECT structure's pvReplyData member. When this buffer is no longer needed, DirectPlay sends you a DPN_MSGID_RETURN_BUFFER message to notify you that you can safely free the buffer.
You can also create a local player context value for the player at this time. That value will be passed back to you later when you receive the a DPN_MSGID_CREATE_PLAYER message for the player. You have the option of changing the player context value when you handle that message. See Using Player Context Values for more information about player context values.
You can reject a connection request by having your handler return any value other than DPN_OK. In that case, there is no need for a response buffer and you will not receive a DPN_MSGID_RETURN_BUFFER message. You can return a data buffer to the rejected player by assigning it to the DPNMSG_INDICATE_CONNECT structure's pvReplyData member. When this buffer is no longer needed, DirectPlay sends you a DPN_MSGID_RETURN_BUFFER message to notify you that you can safely free the buffer.
You can also prevent connections by limiting the number of players in the session. When you call IDirectPlay8Peer::Host or IDirectPlay8Peer::SetApplicationDesc, set the dwMaxPlayers member of the DPN_APPLICATION_DESC structure to the maximum number of players you will allow in the session. When the number of players in the session reaches your specified maximum, you will receive no more DPN_MSGID_INDICATE_CONNECT messages. Instead, additional connection attempts will automatically fail, returning DPNERR_SESSIONFULL.
- DPN_MSGID_CREATE_PLAYER
After you have returned DPN_OK to accept a player's connection request, you will receive a corresponding DPN_MSGID_CREATE_PLAYER message. If you want to create a player context value or modify the value you created when you handled DPN_MSGID_INDICATE_CONNECT, you must do so when you handle DPN_MSGID_CREATE_PLAYER. When your DPN_MSGID_CREATE_PLAYER message handler returns, DirectPlay permits no further changes to the player context value.
- DPN_MSGID_INDICATED_CONNECT_ABORTED
If a player drops the connection after the host has processed the DPN_MSGID_INDICATE_CONNECT message but before it has processed DPN_MSGID_CREATE_PLAYER, the host receives a DPN_MSGID_INDICATED_CONNECT_ABORTED message. If you receive this message, free any memory that you allocated while processing DPN_MSGID_INDICATE_CONNECT. If you process DPN_MSGID_CREATE_PLAYER before the player disconnects, you will receive a DPN_MSGID_DESTROY_PLAYER message. You can free the memory you have allocated when you process that message. If the player disconnects while you are processing DPN_MSGID_CREATE_PLAYER, you will receive a DPN_MSGID_DESTROY_PLAYER message after your message handler returns from processing DPN_MSGID_CREATE_PLAYER.
Host Migration and Session Termination
Every peer-to-peer session must have a host. However, the original host may leave the session either by calling IDirectPlay8Peer::Close or by being disconnected. This situation can be handled in one of two ways:
- When host leaves the session, it terminates.
- When the host leaves the session, a new host is chosen.
The original host specifies which of those two options is to be followed when it calls IDirectPlay8Peer::Host to start the session. If it enables "host migration" by setting the DPNSESSION_MIGRATE_HOST flag in the DPN_APPLICATION_DESC structure, a new host will be chosen when the current host leaves. However, even if host migration is enabled, the host can force the session to terminate by calling IDirectPlay8Peer::TerminateSession. If host migration is not enabled, the session terminates when the host leaves. The host will then receive the same messages as all other members of the session. See Handling Standard Peer-to-Peer Messages for details.