How to Create a User-Defined Protocol
The user can create a user-defined protocol.
To create a user-defined protocol, you must create a COM Object that is a free threaded component which implements three interfaces (ILMNetProtocol, ILMNetConnection and ILMNetConnectionPoint ) for each supported user-defined protocol.
To create a user-defined protocol, perform the following steps:
-
Create a new network protocol class that implements the ILMNetProtocol interface (e.g. CMyNetProtocol). The ILMNetProtocol interface contains both the client and the server methods. - To create client side behavior:
1. Create a new class (e.g. CMyNetConnection) that inherits from the ILMNetConnection interface.
2. Add a new helper method ConnectToServer to the CMyNetConnection class. This method will be called to make a connection to the server. It will receive the server URL as an input parameter.
3. To provide client functionality, you need to override the Connect method In CMyNetProtocol class. Typically, the Connect method is responsible for:
a) Creating an instance of your implementation of the ILMNetConnection interface (CMyNetConnection).
b) Making a call to the ConnectToServer method from the newly created CMyNetConnection object, and sending it the URL as an input parameter. ConnectToServer will format and parse the URL that represents the server address that the client will connect to then open a physical network connection to create a network connection reference (e.g. Socket). The created connection reference will be used later to receive the data from the server.
c) Returning the created CMyNetConnection object reference to the caller method using the corresponding output parameter. The returned ILMNetConnection object will be used to receive data. - To create server side behavior:
1. Create a new class (e.g. CMyNetConnectionPoint) that inherits from the ILMNetConnectionPoint interface. An instance of connection point class will provide the server listening and client request retrieval (through ILMNetConnection) capabilities.
2. Add a new helper method Listen to the CMyNetConnectionPoint class. This method will be used to start listening to client incoming connection requests. This method will receive the local server address URL as an input parameter.
3. To provide server functionality, you need to override the CreateConnectionPoint method in the CMyNetProtocol class. Typically, the CreateConnectionPoint method is responsible for:
- Creating an instance of your implementation of the ILMNetConnectionPoint interface (CMyNetConnectionPoint).
- Making a call to the Listen method from the newly created CMyNetConnectionPoint object, and sending it the URL as an input parameter. The Listen will format and parse the URL that represents the local address that the server will use to listen to the incoming client connection requests then open a physical network connection point (e.g. Socket).
- Returning the created CMyNetConnectionPoint object reference to the caller method using the corresponding output parameter. The returned ILMNetConnectionPoint object will be used to listen to the new incoming client requests calls using GetConnection method.
Note: Remember that you need to register your newly created protocol class before you can use it in your application. Normally you will use an instance of the ILMNetProtocolManager interface to start either client or server functionality. Internally, the ILMNetProtocolManager object will use the URL information to decide about the suitable protocol to use. Therefore, if you pass a URL that contains your newly created protocol schema information, then the protocol manager will instantiate your protocol and start using it.
-
Now add the needed functionality to receive the clients incoming calls at the server side by performing the following steps:
1. Add a new helper method Attach to the CMyNetConnection. This method will receive a connection reference as an input parameter.
2. For your connection point to provide the Server functionality, then you need to override the GetConnection method in the CMyNetConnectionPoint class. The GetConnection method is responsible for:
a) Accepting the connection from the client side and creating a connection reference (e.g. Socket).
b) Creating an instance of your implementation of the ILMNetConnection interface (CMyNetConnection) that represents the new incoming connection from the connection point.
c) Calling the Attach method from the created CMyNetConnection reference and passing the created connection reference to it. The Attach method will save the connection reference in a data member. The saved connection reference will be used later to send the data to corresponding client.
d) Returning the pointer to the caller method using the corresponding output parameter. The returned ILMNetConnection object will be used to receive data.
3. In your CMyNetConnectionPoint class, override the Close method to provide the closing the created connection point. In this method use the network connection point reference to close the connection point.
4. In your CMyNetConnectionPoint class, override the CancelBlockingCall method to cancel any operation that may be blocking on another thread.
-
Now add the needed functionality to do the actual communication work (send/receive data) by performing the following steps:
1. For the Client side: In your CMyNetConnection class, override the Recv method to provide the retrieving data functionality. The Recv method is responsible for retrieving the incoming data from the other side of connection (server side). Use the network connection reference created upon calling the ConnectToServer helper method.
2. For the Server side: In your CMyNetConnection class, override the Send method to provide the sending data functionality. The Send method is responsible to send the data. You can send the data in any format you want. You can send it as packets and also you can add some extra data to each packet. Use the network connection reference that received upon calling the Attach helper method.
3. For both the Client and Server sides:
a) In your CMyNetConnection class, you need to override the Disconnect method to close the network connection.
b) In your CMyNetConnection class, you need to override the IsConnected method to check if the network connection with the other side is available or not.
c) In your CMyNetConnection class, you need to override the GetPeerName method to get the peer name.
d) In your CMyNetConnection class, you need to override the CancelBlockingCall method to cancel any operation that may be blocking on another thread.
- Once the ILMNetProtocol, ILMNetConnection and ILMNetConnectionPoint objects are created and the required interface methods are implemented, the protocol object is ready to be registered with the ILMNetProtocolManager. Once your user-defined protocol is registered, ILMNetProtocolManager will make use of it.
You can use the following source to register your user-defined protocol object.
To register your user-defined protocol, you need to pass your protocol name (e.g. myschema). To use your protocol, your URL should contains your protocol name (e.g. myschema:\\10.0.4.2: 27015,XXXX)
C Source
ILMNetProtocolManager* pManager;
hRes = CoCreateInstance(CLSID_LMNetProtocolManager, NULL, CLSCTX_ALL, IID_ILMNetProtocolManager, (void**)&pManager);
if (FAILED(hRes))
return hRes;
hRes = ILMNetProtocolManager_RegisterProtocol(pManager, L"myschema", CLSID_MyProtocol);
if (FAILED(hRes))
{
ILMNetProtocolManager_Release(pManager);
return hRes;
}
ILMNetProtocolManager_Release(pManager);
C++ Source<
ILMNetProtocolManager* pManager;
hRes = CoCreateInstance(CLSID_LMNetProtocolManager, NULL, CLSCTX_ALL, IID_ILMNetProtocolManager, (void**)&pManager);
if (FAILED(hRes))
return hRes;
hRes = pManager->RegisterProtocol(L"myschema", CLSID_MyProtocol);
if (FAILED(hRes))
{
pManager->Release();
return hRes;
}
pManager->Release();
5. Now, the protocol is ready to be used.
6. When the newly created protocol is no longer needed, unregister and release it.
You can use the following source to un-register and release your user-defined protocol object.
C Source
ILMNetProtocolManager* pManager;
hRes = CoCreateInstance(CLSID_LMNetProtocolManager, NULL, CLSCTX_ALL, IID_ILMNetProtocolManager, (void**)&pManager);
if (FAILED(hRes))
return hRes;
hRes = ILMNetProtocolManager_UnregisterProtocol(pManager, L"myschema");
if (FAILED(hRes))
{
ILMNetProtocolManager_Release(pManager);
return hRes;
}
ILMNetProtocolManager_Release(pManager);
C++ Source
ILMNetProtocolManager* pManager;
hRes = CoCreateInstance(CLSID_LMNetProtocolManager, NULL, CLSCTX_ALL, IID_ILMNetProtocolManager, (void**)&pManager);
if (FAILED(hRes))
return hRes;
hRes = pManager->UnregisterProtocol(L"myschema");
if (FAILED(hRes))
{
pManager->Release();
return hRes;
}
pManager->Release();