پروتکل XMPP چیست؟ بخش دوم عملکرد

پروتکل XMPP چیست؟ بخش دوم عملکرد

عملکرد پروتکل XMPP


در این بخش می خواهیم عملکرد پروتکل XMPP را در یک پیام رسان، با ایجاد یک مثالی از یک ارتباط فرضی، برای شما بیان کنیم. 

جزییات بیشتری از شروع یک ارتباط کلاینت با سرور یا (سرور به سرور) در زیر می آید که در آن از قابلیت namespace زبان XML استفاده می شود. ابتدا یک طرف برای شروع ارتباط اقدام می نماید و در جواب، سرور یک تگ stream می فرستد که حاوی یک id می باشد و به نوعی session id محسوب می شود.

سپس، سرور می تواند شرایطی را برای ادامه ارتباط تعیین کند، مانند احراز هویت، Authentication و امنیت کانال ارتباطی یا Confidentiality. این شرایط در قالب یک تگ <stream:features> به طرف شروع کننده ارسال می شود.

اولین مورد Handshake TLS است که امنیت و نبود شنود ارتباط را تامین می کند و به صورت زیر انجام می شود. البته استفاده از TLS در ارتباط کلاینت با سرور به معنی encryption  end to end نیست و به این منظور از یک XMPP Extension به نام OMEMO استفاده می شود.


R: <stream:features>
    <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
      <required/>
    </starttls>
  </stream:features>

I: <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

If Success:
R: <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>If Failure:
R: <failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
Closing Stream:
R: </stream:stream>

در صورت موفقیت در برقراری TLS دوباره کلاینت یک تگ stream جدید ارسال می کند و سرور با تگ stream با id جدید پاسخ می دهد و برای Authentication ، SASL Handshake را شروع می کند.

I: <?xml version='1.0'?>
  <stream:stream
      from='juliet@im.example.com'
      to='im.example.com'
      version='1.0'
      xml:lang='en'
      xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'>

R: <?xml version='1.0'?>
  <stream:stream
      from='im.example.com'
       id='++TR84Sm6A3hnt3Q065SnAbbk3Y='
      to='juliet@im.example.com'
      version='1.0'
      xml:lang='en'
      xmlns='jabber:client'
      xmlns:stream='http://etherx.jabber.org/streams'>

طرف شروع کننده ارتباط متناسب با یکی از مکانیسم های مطرح شده می تواند تگ <auth/> را بفرستد و پاسخ موفقیت یا شکست را دریافت نماید.

R: <stream:features>
    <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
      <mechanism>EXTERNAL</mechanism>
      <mechanism>SCRAM-SHA-1-PLUS</mechanism>
      <mechanism>SCRAM-SHA-1</mechanism>
      <mechanism>PLAIN</mechanism>
    </mechanisms>
  </stream:features>

I: <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
        mechanism='PLAIN'>AGp1bGlldAByMG0zMG15cjBtMzA=</auth>

If Success:
R: <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>

If Failure:
R: <failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
    <not-authorized/>
  </failure>

در صورت موفقیت، دوباره تگ <stream> ارسال شده و با id جدید دریافت می شود و سرور عملیات resource binding را شروع می کند. resource binding اجازه می دهد کاربر با یک JID بتواند به وسیله دستگاه های مختلف به سرور متصل شود. در مثال زیر کاربر با فرستادن تگ <iq> از سرور می خواهد که یک resource به صورت تصادفی به او اختصاص دهد و سرور با ارسال JID شامل resource به کاربر پاسخ می دهد. 

S: <stream:features>
    <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
  </stream:features>

C: <iq id='tn281v37' type='set'>
   <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
  </iq>

S: <iq id='tn281v37' type='result'>
   <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
     <jid>
       juliet@im.example.com/4db06f06-1ea4-11dc-aca3-000bcd821bfb
     </jid>
   </bind>
  </iq>

پس از این مرحله کلاینت می تواند در قالب تگ <message> پیام خود را ارسال کند.( attribute های to و from حتما باید معین باشد). و از طرف مقابل پاسخ دریافت کند.

C: <message from='juliet@im.example.com/balcony'
            id='ju2ba41c'
            to='romeo@example.net'
            type='chat'
            xml:lang='en'>
     <body>Hello Romeo!</body>
   </message>

E: <message from='romeo@example.net/orchard'
            id='ju2ba41c'
            to='juliet@im.example.com/balcony'
            type='chat'
            xml:lang='en'>
     <body>Hi Juliet! </body>
   </message>

همچنین کلاینت می تواند وضعیت آنلاین بودن خود را به وسیله تگ <presence> ارسال کند. در این مثال از قابلیت چند زبانه بودن XML استفاده شده است. وقتی یک کلاینت presence خود را اعلام می کند، سرور باید این اعلام را به تمام کلاینت هایی که برای این کلاینت subscribe کرده اند، بفرستد.

<presence from='romeo@example.net/orchard' xml:lang='en'>
  <show>dnd</show>
  <status>Wooing Juliet</status>
  <status xml:lang='cs'>Dvo&#x0159;&#x00ED;m se Julii</status>
</presence>

سومین نوع XML stanza که برای درخواست اطلاعات کلاینت از سرور استفاده می شود، Info/Query است که با تگ <iq> ارسال می شود و attribute های type و id حتما باید معین باشد. مثلا برای مدیریت لیست contact ها که roster نامیده می شود از این تگ استفاده می شود. مثال زیر برای دریافت لیست کاربران از سرور است و سرور با تگ item افراد موجود در لیست را ارسال می کند.

همچنین برای اضافه کردن یا حذف افراد از لیست کاربران query های مشابهی با تگ <iq> تعریف می شود.

C: <iq from='juliet@example.com/balcony'
          id='bv1bs71f'
          type='get'> 
      <query xmlns='jabber:iq:roster'/> 
    </iq>S: <iq id='bv1bs71f'   
       to='juliet@example.com/chamber'  
        type='result'>   
    <query xmlns='jabber:iq:roster' ver='ver7'>   
     <item jid='nurse@example.com'/>     
    <item jid='romeo@example.net'/>    
   </query>   
  </iq>

همچنین هر تگ <item> می تواند برای دسته بندی کاربران، تعدادی تگ <group> داشته باشد که کاربر می تواند آن را با ارسال درخواست <iq> تنظیم کند.  

C: <iq from='juliet@example.com/balcony'
          id='lf72v157'
          type='set'>
          <query xmlns='jabber:iq:roster'>
          <item jid='romeo@example.net'
                name='Romeo'>
            <group>Lovers</group>
          </item>
        </query>
      </iq>

برای حذف یک کاربر از لیست roster می توان به طریق زیر درخواست داد و attribute subscription را برابر remove قرار داد.

C: <iq from='juliet@example.com/balcony'
          id='hm4hs97y'
          type='set'>
        <query xmlns='jabber:iq:roster'>
          <item jid='nurse@example.com'
                subscription='remove'/>

 این بود خلاصه ای از عملکرد پروتکل XMPP که بسیاری از نیازمندی های لازم برای یک سیستم پیام رسانی را تعریف کرده است. همچنین جزییاتی مانند Error-Handling در شرایط مختلف و همین طور جلوگیری از مشکلات امنیتی را معین کرده که برای مطالعه بیشتر بهRFC 6120  و RFC 6121 می توان مراجعه کرد. در ضمن، Extension های مختلفی برای افزودن قابلیت های پیشرفته تر مثل Group Chat، ارسال فایل، تماس صوتی و تصویری، پیاده سازی روی Web به کمک WebSocket اضافه شده که لیست آن ها را در اینجا می توانید ببینید.

از بهترین نوشته‌های کاربران سکان آکادمی در سکان پلاس


online-support-icon