
After reading the article and trying the team, we learn
--Connect with Jabber server
--Login
- Change statuses
--Send messages
--Disconnect
And all this is in pure XML
In principle, you can call the article "Introduction to XMPP" or something like that ... But the point will not change
Let's start the same!
A simple Jabber session consists of the following sequence of operations:
- Server connection
- Stream creation
- Enabling encryption and creating a new stream in an encrypted channel (optional)
- Authentication
- Binding a stream to a resource (name @ server / resource)
- Session creation
- Newsletter status is "available"
- Sending / receiving messages, statuses, roster, "business cards", working with services and vehicles, etc.
- Mailing status "disabled"
- Closing flow
- Disconnect from server
Let's try to implement this scheme. In my experiment, the server jabber.ru is used, it is assumed that you already have an account on it.
In the listing below, all my comments that are located inside the XML block are in the XML comment tags, the rest of the XML is presented without changes (unless line breaks are added for readability). If you are thinking of typing all this into the console (this is quite real, I did it myself), it is advisable to first copy all the code into a text editor, replace the authorization. data, delete comments and line feeds.
The XML block sent by the client is denoted --C :, transmitted by the server --S:
')
Server connection
Connecting to jabber.ru server via port 5222
telnet jabber.ru 5222
Trying 213.180.203.19...
Connected to pluton.relax.ru.
Escape character is '^]'.
Stream creation
We send the server the beginning of the XML stream, which includes the server address (jabber.ru)
--C:
<stream:stream xmlns="jabber:client" to="jabber.ru" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" >
In response, the beginning of the server's XML stream comes:
--S:
<? xml version ='1.0' ? >
< stream:stream xmlns ='jabber:client' xmlns:stream ='http://etherx.jabber.org/streams' id ='2689330648' from ='jabber.ru' version ='1.0' xml:lang ='en' >
<!-- -->
< stream:features >
<!-- TLS ( Jabber , , ) TLS , Gajim -->
< starttls xmlns ='urn:ietf:params:xml:ns:xmpp-tls' />
<!-- -->
< compression xmlns ='http://jabber.org/features/compress' >
<!-- gz -->
< method > zlib </ method >
</ compression >
<!-- SASL -->
< mechanisms xmlns ='urn:ietf:params:xml:ns:xmpp-sasl' >
<!-- DIGEST-MD5 -->
< mechanism > DIGEST-MD5 </ mechanism >
<!-- PLAIN -->
< mechanism > PLAIN </ mechanism >
</ mechanisms >
<!-- -->
< register xmlns ='http://jabber.org/features/iq-register' />
</ stream:features >
* This source code was highlighted with Source Code Highlighter .
Authentication
We will not include TLS encryption, we haven't grown yet))
Authentication in Jabber is implemented using the SASL (Simple Authentication and Security Layer). Of the proposed mechanisms, it is recommended to use the DIGEST-MD5 mechanism, but it is rather complicated to implement, so for a start we will consider the PLAIN mechanism.
A block is sent with the attribute
= “PLAIN” attribute and containing the
base64- encoded string, which includes:
{authorization ID eg. user1@jabber.ru (optional)} ASCII character \ x00 {user name, for example. user1} ASCII character \ x00 {password in clear text, eg 123456}The ASCII character \ x00 is an ASCII NUL character with a hexadecimal code 00
Such a string can be obtained, for example, in PHP:
base64_encode ($ id. "\ x00". $ login. "\ x00" $ pass);You can try it here:
Preparing data for SASL authentication--C:
<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">dXNlcjFAamFiYmVyLnJ1AHVzZXIxADEyMzQ=</auth>
In response, the server receives a message about successful authorization (success)
--S:
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
ATTENTION! NEVER use this authentication method (sending a password and login in clear text over an unencrypted channel) in real-world network programs. You can do this for a slight increase in performance if the client (bot) and Jabber server are on the same secure network or on the same server. In real network Jabber applications, they either use TLS encryption of the entire stream, or the DIGEST-MD5 authentication method, and more often both simultaneously.
After successful authentication, you need to start a new XML stream.
--C:
<stream:stream xmlns="jabber:client" to="jabber.ru" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" >
New stream from server:
--S:
<? xml version ='1.0' ? >
<!-- -->
< stream:features >
<!-- (bind) -->
< bind xmlns ='urn:ietf:params:xml:ns:xmpp-bind' />
<!-- XMPP- -->
< session xmlns ='urn:ietf:params:xml:ns:xmpp-session' />
</ stream:features >
Binding a thread to a resource
iq - server requests. Used to request / transfer any information (roster, "business cards", etc.). They have type and id attributes.
type is one of the list: get (requests data), set (sends data | sets / replaces any value), result (response to a successful get or set, may contain the requested data), error (response to an error get request or set)
id - just each subsequent iq request increments id by one (incremented). The server, responding to an iq request, repeats its id. This is due to the fact that sometimes several different iq requests are sent at once.
In response to a get or set, the request should return a result of the type result (or error, if something is wrong)
We assign this stream to the resource "telnet"
--C:
<iq type="set" id="9746"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
<resource>telnet</resource>
</bind>
</iq>
Iq with result type is returned
--S:
<iq id='9746' type='result'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<!-- JID @/ -->
<jid>user1@jabber.ru/telnet</jid>
</bind>
</iq>
Session creation
Then the server required to create a session ... This is necessary for sending statuses, messages, and indeed. We will not refuse:
--C:
<iq type="set" id="9747">
<session xmlns="urn:ietf:params:xml:ns:xmpp-session" />
</iq>
Session successfully created:
--S:
<iq type='result' id='9747'>
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
</iq>
Newsletter status is "available"
presence - to receive and send broadcast information (for example, status information), as well as subscription information (for example, adding a user to the contact list). Although it may include a pointer to to send data only to a specific user (for example, for a particular contact of the roster set the status "do not disturb":])
May have attributes
from - JID name @ server / resource from who presence. In principle, you can not install - put down the server.
to - JID (with or without resource) to whom this presence is intended. If not specified, is sent to all who are signed up (contact list, etc.)
type - type of presence, if not present - then a simple status message, otherwise one of the list: unavailable (disabled), probe (request for client status from the server), subscribe (request for subscription / request to add to the roster), unsubscribed (withdraw subscription / delete from roster), subscribed (approve / add to roster)
We send a message about the status change:
--C:
< presence >
<!-- ( , ) -->
< priority > 50 </ priority >
<!-- , — «» xa (eXtended Away ), away (), chat ( ), dnd ( — ) -->
< show > chat </ show >
<!-- , - -->
< c xmlns =" http : //jabber . org / protocol / caps " node =" http : //gajim . org / caps " ext =" xhtml cstates " ver =" 0 . 11 . 4 " />
<!-- -->
< status > </ status >
<!-- x- ( sha1-) -->
< x xmlns =" vcard-temp:x:update " >
< photo > b2730e40aba4f7225456d0b4789bf2d5af34c3e3 </ photo >
</ x >
</ presence >
I want to note that none of the nested parameters is required. You can send one <priority> </ priority> or only <status> </ status> ... What we want to change is what we send.
In response, the server sends to everyone from your contact list (more precisely, those who subscribed with the command prescence type = "subscribe" including sometimes you) a message
--S:
<presence from='seriy.pr@jabber.ru/telnet' to='seriy.pr@jabber.ru/telnet'>
<priority>50</priority>
<show>chat</show>
<c xmlns="http://jabber.org/protocol/caps" node="http://gajim.org/caps" ext="xhtml cstates" ver="0.11.4" />
<status> </status>
<x xmlns="vcard-temp:x:update">
<photo>b2730e40aba4f7225456d0b4789bf2d5af34c3e3</photo>
</x>
</presence>
Sending / receiving messages
message - to send and receive messages. Has attributes
to addressee - JID (with or without resource)
from sender - JID with the resource (it will not be possible to substitute someone else's: P)
type message type - one of the list: chat - chat tete-a-tete chat (like ICQ, usually used by default), normal - a single message that opens in a separate window, you can reply to it with the same message, groupchat (message in the conference), headline (messages sent by automatic notifications, RSS bots, etc., will open in a separate window, it cannot be answered), error - an error message is displayed in a chat window in a special way formatted
Send a chat message to the author of the article:
--C:
< message to =" seriy . pr @ jabber . ru " from =" user1 @ jabber . ru / telnet " type =" chat " >
<!-- , -->
< body > -! </ body >
<!-- , « »/« »/« » .., -->
</ message >
(scare friends - send a message with type error)
Mailing status "disabled"
To complete the session properly, a status message is usually sent “disabled” (type = “unavailable”)
--C:
<presence xmlns="jabber:client" type="unavailable" />
Closing flow
Close the stream with such a command
--C:
</stream:stream>
And the server also closes the stream.
--S:
</stream:stream>
Disconnect from server
The connection will be closed immediately after the stream is closed by the server.
But in general, that's all.
In continuation, I would like to consider:
- DIGEST-MD5 authentication (if I’ll figure it out myself)
- Enable channel encryption (there will be minor changes)
- Work with roster
- Work with conferences
- Work with the "business card"
- Service Overview
- Work with transports (m / b)
Literature:
Crosspost from my bloghttp://tools.ietf.org/html/rfc3920 rfc3920 XMPP protocol core
http://tools.ietf.org/html/rfc3921 rfc3921 XMPP statuses, sessions, etc.
http://tools.ietf.org/html/rfc2831 rfc2831 SASL authentication
http://www.bog.pp.ru/work/SASL.html a little about SASL in Russian
http://ru.wikipedia.org/wiki/XMPP XMPP on the wiki
http://ru.wikipedia.org/wiki/Jabber Jabber on the wiki