We are now ready to start implementing support for XMPP in our devices. We will begin with the sensor. Most of the implementation needed is generic and will be reused in all our projects created so far. Device-specific interfaces will be described afterwards. The Clayster.Library.Internet.XMPP
namespace has an XMPP client that allows us to communicate using the XMPP primitives and register custom message handlers and IQ handlers.
To connect to the XMPP network, we first need to instantiate an XMPP client. To do this, we need a JID
, a password, the name of the XMPP server and its port number, and the ISO code of the default language we use by default:
xmppClient = new XmppClient (xmppSettings.Jid, xmppSettings.Password, xmppSettings.Host, xmppSettings.Port, "en");
If automatic account creation is supported by the server but requires a signature to make sure malicious account creation is not allowed, you also need to provide a key and secret. Such a key and secret is obtained by the corresponding service provider. If not supported or desired, you can omit these lines of code:
xmppClient.SignatureKey = xmppSettings.ManufacturerKey; xmppClient.SignatureSecret = xmppSettings.ManufacturerSecret;
When connecting to an XMPP server, the client will validate the certificate provided by the server to make sure it corresponds to the domain. If, for some reason, the certificate does not validate, the default action is to abort the connection attempt. If you connect to a server where you know the certificate does not validate the domain or if the certificate is self-signed, you can override this validation as follows:
xmppClient.TrustCertificates = true;
Additionally, if you want to view the actual communication that takes place, you need to register a line listener with the client in the same way you did for other protocols:
xmppClient.RegisterLineListener ( new ConsoleOutLineListenerSink (BinaryFormat.ByteCount));
Finally, we open the connection as follows. The parameter to the Open
method tells the client that we will allow an account to be created if it is not found on the server. If an account is created, it will be done so using the credentials already provided:
xmppClient.Open (true);
When terminating the application, it is important to call the static Terminate
method on the XmppClient
class. This method makes sure the heart beat thread is gracefully terminated. This thread ensures the connections are alive even when nothing is being communicated:
XmppClient.Terminate ();
All the operations in XMPP are asynchronous. This means that the Open
method we just discussed only starts the connection process. Any state changes, successes, or failures are reported by raising different events. There are various event handlers defined on the XMPP client that the application can use to keep track of the state and progress of the connection attempt.
To learn whether an account was successfully created, we can register an event handler on the OnAccountRegistrationSuccessful
event. In the same way, we can use the OnAccountRegistrationFailed
event to detect a permanent failure when an account is not found and a new account could not be created:
xmppClient.OnAccountRegistrationFailed += (Client, Form) => { xmppPermanentFailure = true; Client.Close (); };
Once the client has been successfully authenticated by the server (or an account created), the OnConnected
event is raised. The first thing we must do once this is done is set the desired presence of the client. This presence will be distributed to friends subscribing to presence notifications to alert them of the new status of the connection. It will also alert them of the current resource bound to the connection, enabling them to communicate with your application. This is done as follows:
xmppClient.OnConnected += (Client) => { Client.SetPresence (PresenceStatus.Online);
We have defined a lot of HTTP resources in the previous chapters. It is possible for the web server to serve HTTP requests that come over XMPP connections as well. By calling the following method during application initialization, HTTP requests can be served, both by clients with IP access to the device (normal HTTP) and friends over the XMPP network.
HttpServer.RegisterHttpOverXmppSupport (6000, 1024 * 1024);
The first number represents the maximum number of bytes to be sent in a single message and should result in messages smaller than the smallest maximum allowed stanza size (10000 bytes). If a response is larger, a chunked service will be used, where the response will be divided into chunks and sent in a sequence of messages. As chunks are base64-encoded, 6000 bytes are encoded as 8000 bytes, leaving some margin for the XML encapsulating the chunk. The second number is an upper limit for the chunked service where the corresponding content should be transferred using a streaming option instead. In our examples, HTTP requests over XMPP will be used to fetch the camera picture from our camera device. It already has an HTTP resource to retrieve a camera image. Using this single method call, we will make sure it is possible to retrieve the same image over the XMPP network as well.
3.144.47.208