3

XMLに基づいてTCP/IPソケットを介して送信されるテキストプロトコルを開発したいと思います。次のように、クライアントとサーバー間の永続的なTCP/IP接続を介して送信される単純な要求/応答メカニズムがあるとします。

<?xml version="1.0" encoding="UTF-8"?>
<request id="1" command="get.answer">
    <value type="string">Answer to the Ultimate Question of Life, the Universe, and Everything</value>
</request>

<?xml version="1.0" encoding="UTF-8"?>
<response id="1" command="get.answer">
    <value type="int32">42</value>
</response>

どちらの側も着信データの処理をいつ開始する必要がありますか。言い換えると、サーバーは、着信クライアントデータが完全に転送され、応答を作成するために処理できることをいつ知るのでしょうか。

もちろん、私はそのトピックについていくつか調査しました。HTTPの例に基づいて、正しい方向を示すこの回答を見つけました。したがって、XMLメッセージの上に一種の「転送プロトコル」を使用すると確かに役立ちます。

しかし、少なくとも私が見た限りでは、HTTPのような「転送プロトコル」を使用しない純粋なXMLベースのXMPPプロトコルも調べました。

「2.4。構造化データ」のRFC6120から、次のようになっています。

XMPPの基本的なプロトコルデータユニットは、XMLストリーム(ポイントツーポイント通信のトランスポートを提供するだけです)ではなく、ストリームを介して送信されるXMLのフラグメントであるXML「スタンザ」です。スタンザのルート要素にはルーティング属性(「from」アドレスや「to」アドレスなど)が含まれ、スタンザの子要素には目的の受信者に配信するためのペイロードが含まれます。

したがって、基本的に小さなXMLチャンクを「転送プロトコル」なしでTCP / IP経由で送信し、wiresharkトレースから、各XMLスタンザの最後に2回のような特別な送信終了文字がないことがわかります\ r \nまたはそのようなもの。では、メッセージの終わり(スタンザ)をどうやって知るのでしょうか?

4

4 に答える 4

2

実際、XMPPはXMLストリームを使用してデータを転送します。参照しているデータユニットは、個々のメッセージの実際の交換ですが、それらはすべて、XMPPセッションの通信の開始と終了を定義するXMLストリーム内に含まれています。

これは、すべての送信の終わりのように、送信の終わりが発生する場所になります。そのストリーム内には、3つの定義されたパケットタイプ(IQ、メッセージ、およびプレゼンス)があり、個々のメッセージの開始と終了を示します(クライアントからサーバーへの通信用)。

基本的なケースはTCP接続を介して行われますが、ファイアウォールを通過するXMPPを許可するのに役立つHTTPなど、さまざまな有線プロトコルをサポートする拡張機能もあります。

同様のことをしたい場合は、同じアプローチに従うことができます。つまり、接続が確立されて切断されたときにXMLストリームを開始および終了します。次に、個々のメッセージタイプを定義するだけで、エンドポイントは完全なメッセージを構成するものを認識できます。

または、ユースケースに完全に適合すると思われるXMPPを使用することもできます。

于 2012-04-18T13:52:16.167 に答える
0

As it is mentioned in here there mainly two methods: Have a delimiter or the length in header. Your delimiter could simply be the end of your beginning tag and that's what XMPP is doing. This means as long as your XML messages are wrapped in a tag which starts and ends properly you are set to go. If you wanna have a sort of validation on the chunk of data you receive, what you need to do is to make sure that there is an end for all of your tags. Most of the parser packages do this for you. If you pass them a non-parsable package they will throw you a sort of exception. If you wanna write your own parser, then you need to study more about parsers rather than the transfer/XML protocol.

于 2012-04-19T10:04:21.307 に答える
0

@Robinが言うように、XMPPにはXMLストリームを介したトランスポートがあります。また、 BOSHを使用したトランスポートとしてHTTPを使用することもできます。

2番目の(HTTP)の場合、物事は簡単です。たとえば、 Strophe、BOSHを使用するjsライブラリ、リクエスト基本的にHTTPリクエストであるため、がありますContent-Length。次のようになります。

POST /webclient HTTP/1.1
Content-Type: text/xml; charset=utf-8
Content-Length: 240

<body rid='1573741825'
      sid='SomeSID'
      xmlns='http://jabber.org/protocol/httpbind'>
  <iq id='bind_1'
      type='set'
      xmlns='jabber:client'>
    <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
      <resource>httpclient</resource>
    </bind>
  </iq>
</body>

最初のケース(XMLストリーム)では、状況は異なりますが。私が使用している、パフォーマンスが高く、長い間存在し、テストされたpythonライブラリであるTwistedは、 ExpatXMLパーサーでpythonラッパーを使用します。パーサーは高速で検証されないパーサーであり、たとえば「ルート」要素の開始または終了を示す有用なイベントをスローします。次に、要素は受信時に1つずつ解析されます。

于 2012-04-18T18:42:59.770 に答える
0

XMPPエンドポイントはXMLを解析する必要があります。そうすることで、ドキュメント(トップレベル)要素は1つしか許可されないため、いつ終了するかがわかります(XMLプロセッサ命令が先行する可能性があるかどうかはわかりません)。

<?xml version="1.0" encoding="UTF-8"?>
<request id="1" command="get.answer">
    <value type="string">Answer to the Ultimate Question of Life, the Universe, and Everything</value>
</request>

これは自己区切りであり、<requestマークアップを解析すると、一致するにヒットしたときにこのXMLドキュメントが終了することがわかります</request>

(個人的には、(TCP)ストリームの上に生のxmlを詰め込む代わりに、以下のプロトコルレベルにフレーミングプロトコルを配置します。おそらく、すべてのメッセージの前に4バイトのビッグエンディアン長フィールドを配置します。)

于 2012-04-19T10:14:00.447 に答える