xmpp即时通讯四

简介:      TLS协商(5节)后,如果需要SASL协商(6节)与资源绑定(7节),XML节可通过流来发送。定义了三种XML节用于 'jabber:client'与'jabber:server'命名空间:<message/>, <presence/>, and <iq/>。另外,这种节有五个通用属性。这些通用属性,像三种节的基本语义一样,都定义在此;与即时消
     TLS协商(5节)后,如果需要SASL协商(6节)与资源绑定(7节),XML节可通过流来发送。定义了三种XML节用于 'jabber:client'与'jabber:server'命名空间:<message/>, <presence/>, and <iq/>。另外,这种节有五个通用属性。这些通用属性,像三种节的基本语义一样,都定义在此;与即时消息与表示应用相关的XML节的更详细信息在[XMPP-IM]中提供。

9.1通用属性
      以下五个属性对message, presence与IQ均通用:

9.1.1 to
      ‘to’属性指定接收节的JID。
      在‘jabber:client’命名空间中,节应当处理‘to’属性,虽然,由服务器处理的从客户端到服务器端的节不应该拥有‘to’属性。
      在'jabber:server'命名空间中,节必须拥有‘to’属性;如果服务器收到一个不满足此限制的节,它必须产生一个<improper-addressing/>流错误条件并终止两个XML流与错误服务器的潜在连接。
      如果‘to’属性无效或不能连接,发现此事实的(通常是发送的或接收的服务器)实体必须返回一个合适的错误给发送者,设置错误节的‘from’属性为错误服务器提供的‘to’属性值。

9.1.2 from
      ‘from’属性指明发送者的IID。
      当服务器收到一个在由'jabber:client'命名空间认证的已授权流的上下文中的XML节,它必须做以下事件之一:
1) 验证客户端提供的‘from’属性值就是用于联合实体的已连接资源的值。
2) 加一个‘from’地址值给节,此节的值是裸JID(<node@domain>)或全JID(<node@domain/resource>),这些JID由服务器决定用于产生节的已联接资源(看地址决定(3.5节))。

        如果一个客户端试图发送‘from’属性并不匹配实体的已联接资源的XML节,服务器应该返回一个<invalid-from/>流错误给客户端。如果一个客户端试图通过一个流来发送一个还未授权的XML节,服务器应当返回一个<not-authorized/>流错误给客户端。如果产生了,这些条件都必须关闭流并终止潜在的TCP连接;这有助于阻止来自于欺诈客户端的否认服务攻击。
        当一个服务器产生一个来自于服务器本身的节,用于传送到一个已连接的客户端(例如:在由服务器代表客户端提供的数据存储服务的上下文中),节必须既(1)不包括‘from’属性或(2)包括‘from’属性,其值是帐户的裸JID(<node@domain>)或客户的全 JID(<node@domain/resource>)。服务器不准发送给客户端一个不包括‘from’属性的节,它必须设想节是从服务器到已连接客户端。
        在'jabber:server'命名空间中,一个节必须处理一个‘from’属性;如果服务器收到不满足此限制的节,它必须产生一个<improper-addressing/>流错误条件。更进一步,包含在‘from’属性中的JID的域标识符部分必须匹配发送服务器(或任何已认证相关域,如发送服务器的主机名或其它由发送服务器已认证域)的主机名,当在SASL协商或回叫协商通信中;如果一个服务器收到一个不满足此约束的节,它必须产生一个<invalid-from/>流错误条件。这些条件都必须关闭流并终止潜在的TCP连接;这有助于阻止欺诈服务器的否认服务攻击。

9.1.3 id
      可选‘id’属性可能由发送实体因内部跟踪收发(特别是跟踪固有在IQ节语义中的请求-响应交互)节而使用。对值‘id’属性来说,它是可选的唯一全局的,在域内的或流中的。IQ节语义强加了其它约束;看IQ语义(9.2.3)。

9.1.4 type
      类型域属性指定目的或消息上下文,出席或IQ节的详细信息。‘type’属性的特别允许值依赖节是否是一个消息,出席,或IQ;消息与出席节的值是特别用于即时消息与出席应用的,并因此定义义在[XMPP-IM],然而IQ节的值特指IQ节在一个结构化的请求-响应“会话”中的角色,并因此定义在以下IQ 语义(9.2.3节)。对三种节仅有的一个通用‘type’值是“error”;看节错误(9.3节)。

9.1.5 xml:lang
      此节应当处理一个‘xml:lang’属性(定义在[XML]2.2节),如果节包含倾向于表示到一个人类用户(RFC2277[CHARSET]中有解释,“对人的国际化”)的XML字符数据。‘xml:lang’属性值指定任意人类可读XML字符数据的缺省语言,可能被特定的子元素的 ‘xml:lang’属性覆盖。如果节没有‘xml:lang’属性,实现必须设想为流指定的缺省语言已在以下流属性(4。4节)中定义。 ‘xml:lang’属性的值必须是一个NMTOKEN并必须遵从定义在3066[LANGTAGS]中的格式。

9.2基本语义
9.2.1消息语义
      <message/>节种类可被看作“推”机制,一个实体推信息给其它实体,与EMAIL系统中发生的通信类似。所有消息节应该拥有‘to’ 属性,指定有意的消息接收者;根据接收到那样的一个节,服务器应该路由或传送它到有意的接收者(参考服务器处理用于相关XML节的通用路由与传送规则 XML节的规则(10节))。

9.2.2 出席语义
      <presence/>元素可被看作基本广播或“出版-订阅”机制,多实体收到他们已订阅(在这种情况下,网络可利用信息)实体的信息。总的来说,出版实体应该发送一个不带‘to’属性的出席节,在这种情况下,与此实体相连的服务器应该广播或复用节给所有订阅实体。然而,一个出版实体也可能发送一个带有‘to’属性的出席节,此种情况下,服务器应该路由或传送节到有意的接收者。参考处理XML节(10节)的服务器规则,用于通用路由与相关 XML节的传送规则,并且用于即时消息与出席应用的出席-特定规则[XMPP-IM]。

9.2.3 IQ语义
      信息/请求,或IQ,是一个请求-响应机制,与[HTTP]在某些方面相似。IQ语义让一个实体向其它实体请求或接收其它实体的响应成为可能。请求与响应的数据内容由IQ无素的直接子元素的命名空间声明定义,并且,交互由请求实体通过使用‘id’属性来跟踪。因此,IQ交互遵从结构化数据交换的一个通用模式,此交换例如得到/结果或设置/结果(虽然如果合适的话,对一个请求的响应可能会以错误返回):

   Requesting                 Responding
     Entity                     Entity
   ----------                 ----------
       |                           |
       | <iq type='get' id='1'>    |
       | ------------------------> |
       |                           |
       | <iq type='result' id='1'> |
       | <------------------------ |
       |                           |
       | <iq type='set' id='2'>    |
       | ------------------------> |
       |                           |
       | <iq type='error' id='2'>  |
       | <------------------------ |
       |                           |

      为了加强这些语义,以下规则应用:
1) 对IQ节来说,‘id’属性是REQUIRED。
2) 对IQ节来说。‘type’属性是需要的。值必须是以下之一:
*get——节是一个用于信息或需求的请求。
*set——节提供所需数据,设置新值,或替换现存值。
*result——节是成功得到或设置请求的响应。
*error——先前发送得到或设置的相关过程或传送的错误(参考节错误(9.3节))。
3) 收到类型为“get”或“set”的IQ请求的实体必须以类型为“result”或“error”的IQ响应来响应(响应必须保留请求的‘id’属性)。
4) 收到类型为“result”或“error”的节不准靠发送一个进一步的类型为“result”或“error”的IQ响应节来响应;然而,如以上显示,请求实体可能发送另一个请求(如:一个类型为“set”的IQ,为了提供通过得到/结果对发现的所需的信息)。
5) 类型为“get”或“set”的IQ节必须包含一个并仅有一个子元素,指定特别的请求或响应语义。
6) 一个类型为“result”的IQ节必须包含0或一个子元素。
7) 类型为“error”类型的IQ节应当包含在相关“get”或“set”子元素中,并且,必须包含一个<error/>子元素;详细信息,参考节错误(9.3节)。

9.3 节错误
      节相关错误以类似流错误(4.7节)的方式处理。然而,不像流错误,节错误不可是不可恢复的;因此,暗含相关源发送者行为的错误节能按顺序纠正错误。

9.3.1 规则
      以下规则应用于节相关错误:
1) 检测相关节错误条件的接收或处理实体必须返回给发送实体一个同种节(消息,出席或IQ),它的‘type’属性被设置成值“error”(那样的节在此被称为“错误节”)。
2) 产生错误节的实体应当包含被送的源XML,为了发送者能够检测,并且,如果必要的话,在试图重送前纠正XML。
3) 一个错误节必须包含一个<error/>子元素。
4) 一个<error/>子元素不准被包括,如果‘type’属性有不止一个“错误”值(或无‘类型’属性)。
5) 接收一个错误节的实体不准响应带有进一步错误节的节;这有助于阻止循环。

9.3.2 语法
      节相关错误语法如下:
   <stanza-kind to='sender' type='error'>
     [RECOMMENDED to include sender XML here]
     <error type='error-type'>
       <defined-condition xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
       <text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'
             xml:lang='langcode'>
         OPTIONAL descriptive text
       </text>
       [OPTIONAL application-specific condition element]
     </error>
   </stanza-kind>

      节种类是消息、出席或iq之一。
<error/>元素的‘type’属性值必须是以下之一:
*cancel——不重试(错误不可恢复)
*continue——进行(仅是一个警告条件)
*modify——改变数据发送后重试
*auth——提供信任后重试
*wait——等待之后重试(错误是临时的)

      <error/>元素:
      必须包含一个子元素,此子元素与以下指定的已定义的节错误条件一致;此元素必须被'urn:ietf:params:xml:ns:xmpp-stanzas'命名空间所认证。
      可能包含<text/>子元素,此子元素包含XML字符数据,用于描绘更细节的错误;此元素必须被'urn:ietf:params:xml:ns:xmpp-stanzas'命名空间所认证,并且应该拥有一个'xml:lang'属性。
      可能包含一个子元素,用于特殊-应用错误条件;此元素必须由一个已定义-应用命名空间认证,并且,它的结构由此命名空间定义。

      <text/>元素是可选的。如果包括在内,它应当仅用于提供描述性或诊断性信息,这些信息用于补充已定义条件或特殊-应用条件的意思。它不应当由应用程序性的描述。它不应当用作向用户表达的错误信息,但可能显示除与包含条件元素(或元素们)相关的错误消息。

      最后,为维护向后兼容性,此方案(在[XMPP-IM]中指定的)允许可选的在<error/>元素中包含‘code’属性。

9.3.3 已定义条件
      以下条件被定义用于节错误。

<bad-request/>——发送者已发送畸形的或不能被处理的(例如,一个包含未识别‘type’属性值的IQ节)XML;相关错误类型应当是“modify”。

<conflict/>——访问不被授权,因为一个现存资源或会话以同样名字或地址存在;相关错误类型应当是“cancel”。

<feature-not-implemented/>——被请求特征未被接收者或服务器实现,并且因此不能被处理;相关错误类型应当是“cancel”。

<forbidden/>——请求实体不拥有执行行为的所需许可;相关错误类型应当是“auth”。

<gone/>——接收者或服务器不在以此地址联系(错误节可能包含一个新地址在<gone/>元素的XML字符数据中);相关错误类型应当是“modify”。

<internal-server-error/>——服务器不能处理节,因为错误配置或一个另外-未定义内部服务器错误;相关错误类型应当是“wait”。

<item-not-found/>——JID地址或被请求项不能被发现;相关错误类型应当是“cancel”。

<jid-malformed/>——已提供的发送实体或与一个XMLL地址(例:‘to’属性值)通信或其它方面(例:资源标识符)与地址方案(3节)中定义的语法不符;相关错误类型应当是“modify”。

<not-acceptable/>——接收者或服务器理解请求,但拒绝处理它,因为它不满足由接收者或服务器(例:消息中相关可接受字的本地策略)所定义的标准;相关错误类型应当是“modify”。

<not-allowed/>——接收者或服务器不允许任何实体执行动作;相关错误类型应当是“cancel”。

<not-authorized/>——发送者必须在被允许执行动作前提供合适的信任,或已经提供不合适的信任;相关错误类型应当是“auth”。

<payment-required/>——请求实体未授权去访问被需求服务,因为需要付费;相关错误类型应当是“auth”。

<recipient-unavailable/>——有意的接收者临时不可用;相关错误类型应当是“wait”(注:一个应用不准返回此错误,如果这样做将提供关于意向接收 者对未授权知道此类信息的实体的网络可利用性信息)。

<redirect/>——接收者或服务器为此信息重定向请求到其他实体,通常是临时的(错误节应当包含可替换地址,必须是一个有效的JID,在<redirect/>元素的XML字符数据中);相关错误类型应当是“modify”。

<registration-required/>——请求实体未被授权访问所请求服务,因为需要注册;相关错误类型应当是“auth”。

<remote-server-not-found/>——一个指定作为意向接收者的部分或全部的JID的远程服务器或服务不存在;相关错误类型应当是“cancel”。

<remote-server-timeout/>——一个指定作为意向接收者(或被请求去执行一个请求)的部分或全部的JID的远程服务器或服务不能在一个合理的时间内被联系到;相关错误类型应当是“wait”。

<resource-constraint/>——服务器或接收者缺少必要的系统资源去服务请求;相关错误类型应当是“wait”。

<service-unavailable/>——服务器或接收者当前并不提供所请求的服务;相关错误类型应当是“cancel”。

<subscription-required/>——请求实体不被授权访问被请求服务,因为需要订阅;相关错误类型应当是“auth”。

<undefined-condition/>——错误条件并不是此列表中由其它条件定义的那些之一;任何错误类型可能与此条件相关,并且,它应当仅用于与一个特殊-应用条件相连。

<unexpected-request/>——接收者或服务器理解请求,但此时(例:请求无序/请求不在状态)并不期望它;相关错误类型应当是“wait”。

9.3.4 特殊-应用条件
      像所知道的,一个应用可能靠包含一个错误元素中的合适的-命名空间的子元素来提供特殊-应用节错误信息。特殊-应用元素应当补充或进一步认证一个已定义元素。因此,<error/>元素将包含两个或三个子元素:

   <iq type='error' id='some-id'>
     <error type='modify'>
       <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
       <too-many-parameters xmlns='application-ns'/>
     </error>
   </iq>

   <message type='error' id='another-id'>
     <error type='modify'>
       <undefined-condition
             xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
       <text xml:lang='en'
             xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>
         Some special application diagnostic information...
       </text>
       <special-application-condition xmlns='application-ns'/>
     </error>
   </message>

10. 处理XML节的服务器规则
      兼容服务器实现必须确保有序处理任两实体间的XML节。
超出有序处理的需求,每个服务器实现将包含它自己的“传送树”用于处理它所接收的节。那样的一个树决定是否一个节需要被路由到其它域,内部处理,或传送到与被连节点相关的资源。以下规则应用:

10.1 无‘to’地址
      如果节拥有无‘to’属性,服务器应当代表发送它的实体处理它。因为所有从其它服务器收到的节必须拥有一个‘to’属性,此规则仅应用于从一个连到服务器的已注册实体(如客户端)收到的节。如果服务器收到一个无‘to’属性的出席节,服务器应当广播它到被订阅到发送实体的出席实体,如果可利用的话(用于定义在[XMPP-IP]即时消息与表示应用的出席广播的语义。)如果服务器接收一个类型为“get”或“set”的没有‘to’属性的IQ节,并且它理解认证节内容的命名空间,它必须也能代表发送实体处理节或返回给发送实体(在“process”意思处被认证命名空间的语义决定)一个错误。

10.2 外部域
      如果JID的域标识符部分的主机包含在‘to’属性中并不匹配服务器本身的已配置主机名或子域中的已配置主机之一,服务器应当路由节到外部域(服从本地服务提供与相关内部域通信的安全策略)。有两种可能情况:

      一个服务器到服务器流已在两域间存在:发送者的服务器为现存流的外部域路由节到已授权服务器。

      两域间存在无主机到主机流:发送者的服务器(1)解析外部域(定义在以下服务器到服务器通信(节14。4))的主机名,(2)在两域间(定义在如下使用 TLS(节5)并且使用SASL(节6))协商服务器到服务器的流,并(3)为通过新近-建立的流的外部域路由节到授权服务器。

      如果路由到接收者的服务器不成功,发送者的服务器必须返回一个错误给发送者;如果接收者的服务器能被联系但被接收者的服务器传送到接收者是不成功的,接收者的服务器必须经由发送者的服务器返回一个错误给发送者。

10.3 子域
      如果包含在‘to’属性中的JID域标识符部分的主机名匹配服务器本身已配置主机名之一的子域,服务器必须也处理节本身或路由节到一个特别的对那个子域(如果子域被配置)有责任的服务,或返回一个错误给发送者(如果子域不被配置)。

10.4 仅有域或特别资源
      如果包含在‘to’属性中的JID域标识符部分的主机名匹配服务器本身的一个已配置主机名,并且包含在‘to’属性中的JID 是<domain>或<domain/resource>形式,服务器(或在内的一个已定义资源)必须合乎节种类处理节或返回错误节给发送者。

10.5 同域中的节点
      如果包含在‘to’属性中的JID域标识符部分的主机名匹配服务器本身的一个已配置主机名,并且包含在‘to’属性中的JID 是<node@domain>或<node@domain/resource>形式,服务器应当传送节到由包含在‘to’属性中的JID表达的节的意向接收者。以下规则应用:

1) 如果JID包含一个资源标识符(例:是<node@domain/resource>形式)并且,这儿存在一个已连接资源匹配全JID,接收者的服务器应当传送的节到确切匹配此资源标识符流或会话。
2) 如果JID包含一个资源标识符并且这儿存在匹配全JID的无连接资源,接收者的服务器应当返回一个<service-unavailable/>节错误给发送者。
3) 如果JID是<node@domain>形式,并且这儿存在为此结点的至少一个已连接资源,接收者的服务器应当传送节到连接资源的至少一个,根据应用-特殊规则(一套传送规则,用于定义在[XMPP-IM]即时消息与出席应用)。

11. XMPP内的XML使用

11.1 约束
      XMPP是流XML元素的一个简单与特殊的协议,用来近实时的交换结构化信息。由于XMPP不需要任意分析与完整XML文档,这儿没有XMPP需要支持[XML]全特征的需求。特别的,以下约束应用。

      关于XML产生,一个XMPP实现不准注入以下任意一个XML流:
*评论(定义在[XML]节2。5)
*处理说明(2。6节)
*内部或外部DTD子集(2。8节)
*除了预定义实体(4。6节)的内部或外部实体参考。
*包含映射到预定义实体(4。6节)保留字符的字符数据或属性值;那样的字符必须被避免

      关于XML处理,如果一个XMPP实现接收到那样的约束XML数据,它必须忽略此数据。

11.2 XML命名空间名与前缀
      XML命名空间[XML-NAMES]被用在所有与XMPP-兼容的XML中,去创建数据拥有权的严格界限。命名空间的基本功能是分离结构的混合在一起的 XML元素的不同词汇。确保XMPP-兼容XML是命名空间-了解使任意允许的XML能够与XMPP中的任意数据元素结构化的混合。XML命名空间名与前缀的规则定义在以下子部分。

11.2.1 流命名空间
      流命名空间声明在所有XML流头中都是需要的。流命名空间名必须是'http://etherx.jabber.org /streams'。<stream/>元素与它的<features/>与<error/>子元素的元素名必须被所有实例中的流命名空间认定合格。一个实现应当为那些元素产生仅有的'stream:'前缀,并且因为历史原因可能接受仅有的'stream:'前缀。

11.2.2 缺省命名空间
      缺省命名空间声明是需要的,并且用在所有XML流中,为了定义允许的根流元素的第一级子元素。此命名空间声明必须与初始流与响应流相同,为了两个流一致的被认证合格。缺省命名空间声明应用于流与所有在由其它命名空间认证合格的流(除非由另一命名空间显示认定合格,或由流命名空间或回叫命名空间前缀认证)中发送的节。

      服务器实现必须支持以下两个缺省命名空间(由于历史原因,一些实现可能支持仅有的那些两个缺省命名空间):
*jabber:client——缺省命名空间,当流用于客户端与服务器通信时所声明的。
*jabber:server——缺省命名空间,当流用于两服务器间通信时声明的。

      客户端实现必须支持'jabber:client'缺省命名空间,并且由于历史原因可能只支持缺省命名空间。

      实现不准为缺省命名空间中的元素产生命名空间前缀,如果缺省命名空间是'jabber:client'或'jabber:server'。一个实现不应当为元素产生命名空间前缀,元素由'jabber:client'与'jabber:server'之外的内容(与流相反)命名空间认证的。

      注:'jabber:client'与'jabber:server'命名空间是接近同一的,但用在不同的上下文中(客户端到服务顺通信用 'jabber:client'与服务器到服务器通信用'jabber:server')。这两个仅有的不同是‘to’与‘from’属性在 'jabber:client'中发送的节中是可选的,然而在'jabber:server'中发送的节是必须的。如果一个兼容实现接受一个由 'jabber:client'或'jabber:server'命名空间认证合格的流,它必须支持所有三个核心节种类的(消息,出席,与IQ)通用属性(9。1节)与基本语义(9。2节)。

11.2.3 回叫命名空间
      回叫命名空间声明对于所有用在服务器回叫(8节)中的元素都是需要的。回叫命名空间的名字必须是'jabber:server:dialback'。所有由这个命名空间认证合格的元素必须被加前缀。一个实现应当为那种元素仅产生'db:'前缀并可能接受仅有的'db:'前缀。

11.3 确认(验证)
      除了'jabber:server'命名空间中节的相关‘to’与‘from’地址,服务器不为转发到客户端或另一个服务器的XML元素负责;一个实现可能选择提供仅有的认证数据元素,但这是可选的(虽然一个实现不准接受XML,那也不是好格式)。客户端不应当依赖此能力去发送数据,这些数据与方案并不符,并且应当忽略一个来的XML流中的非构造元素或属性。XML流与节的验证是可选的,包含在此的方案仅用于描述目的。

11.4 包含文本声明
      实现应当在发送流头之前发送文本声明。应用必须遵循文本声明包含在内的相关环境的[XML]中的规则。

11.5 字符编码

      实现必须支持UTF-8 (RFC 3629 [UTF-8])统一字符集(ISO/IEC 10646-1 [UCS2])字符传输,RFC 2277 [CHARSET]中查。实现不准试图使用其它编码。

目录
相关文章
|
8月前
|
数据格式
直播APP开发,协议盘点(五):实时传输协议RTP
简单搭建实时传输协议RTP的部分参考代码: import socket rtp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) rtp_port = 1234 rtp_socket.bind(('localhost', rtp_port)) packet_size = 1024 while True:
直播APP开发,协议盘点(五):实时传输协议RTP
|
8月前
|
网络协议 BI
直播系统源码协议探索篇(二):网络套接字协议WebSocket
直播系统源码网络套接字协议WebSocket搭建参考代码 connected_clients.add(websocket) try: async for message in websocket: await broadcast(message) finally: connected_clients.remove(websocket)
直播系统源码协议探索篇(二):网络套接字协议WebSocket
|
Ubuntu TensorFlow 算法框架/工具
基于 socket 的即时通讯文件传输聊天软件
基于 socket 的即时通讯文件传输聊天软件
103 0
基于 socket 的即时通讯文件传输聊天软件
dzq
|
XML Web App开发 移动开发
深入浅出即时通讯(1)_即时通讯协议对比
主要介绍了市面上可供即时通讯选型的多种技术方案,包括http, Websocket, xmpp, mqtt, socket.io 以及自定义的TCP/UDP协议等。并在最后介绍了"E聊SDK"的通讯方案选型的考虑,以便打造一个现代化即时通讯应用。
dzq
575 0
深入浅出即时通讯(1)_即时通讯协议对比
|
消息中间件 网络协议 物联网
浅谈物联网开发最热协议—MQTT协议
浅谈物联网开发最热协议—MQTT协议
447 0
浅谈物联网开发最热协议—MQTT协议
|
分布式计算 关系型数据库 数据库
|
XML API 数据安全/隐私保护
|
消息中间件 存储 网络协议
MQTT, XMPP, WebSockets还是AMQP?泛谈实时通信协议选型 good
Wolfram Hempel 是 deepstreamIO 的联合创始人。deepstreamIO 是一家位于德国的技术创业公司,为移动客户端、及物联网设备提供高性能、安全和可扩展的实时通信服务。文本由魏佳翻译,转载译文请注明来自高可用架构。
3528 0