安裝Stomp擴展時錯誤提示error: 'zend_class_entry' has no member named 'default_properties'


在安裝stomp擴展時, 有這樣的提示 error: 'zend_class_entry' has no member named 'default_properties'

交待下安裝上下文, stomp 版本是 1.0.3 而最新的是 1.0.8  php 版本是5.4.x , 猜想可能是由於版本差異造成的, 因為1.0.3的 stomp 出現的年份是2010年... 

於是網上搜索了一下, 文章點這 說在出錯的文件中把 default_properties 改成 default_properties_table 就行了, 於是, 照做, 果不其然, 接下來的 make make install 都沒有出錯了.

擴展知識:

php stomp 擴展下載 

消息處理利器 ActiveMQ 的介紹 & Stomp 協議的使用

stomp 是什么? <轉自 http://simlegate.com/2013/10/17/stomp-specification-1.2/ >

17 October 2013

原文: STOMP Protocol Specification, Version 1.2

摘要

STOMP是一個簡單的可互操作的協議, 被用於通過中間服務器在客戶端之間進行異步消息傳遞。它定義了一種在客戶端與服務端進行消息傳遞的文本格式.

STOMP已經被使用了很多年,並且支持很多消息brokers和客戶端庫。這個規范定義STOMP 1.2協議以及對1.1版本的更新。

發送反饋到stomp-spec@googlegroups.com.

概述

背景

由於需要用腳本語言如RubyPythonPerl去連接企業級的消息brokers, STOMP產生了.在這種情況下,STMOP實現了一些簡單的操作,比如可靠地發送單一的消息,然后斷開或者從目的地消費所有消息。

STOMP是除AMQP開放消息協議之外地另外一個選擇, 實現了被用在JMS brokers中特定的有線協議,比如OpenWire. 它僅僅是實現通用消息操作中的一部分,並非想要覆蓋全面的消息API.

STOMP目前已經是個成熟的協議,在wire-level方面, 它提供了一些簡單的用例,但仍保持其核心設計原則:簡單性和互操作性。 ### 協議概述

STOMP是基於frame的協議, 與HTTP的frame相似.一個frame包含一個command,一系列可選的headersbody.STOMP雖然是基於消息但同於也允許傳遞二進制消息。STMOP的默認消息格式是UTF-8,但是在消息體中同樣支持其他格式編碼。

STOMP服務器就好像是一系列的目的地, 消息會被發送到這里。STOMP協議把目的地當作不透明的字符串,其語法是服務端具體的實現。 此外STOMP沒有定義目的地的交付語義是什么。 交付,或“消息交換”,語義的目的地可以從服務器到服務器,甚至從目的地到目的地。這使得服務器有可創造性的語義,去支持STOMP。

STOMP client的用戶代理可以充當兩個角色(可能同時): * 作為生產者,通過SENDframe發送消息到server * 作為消費者,發送SUBSCRIBEframe到目的地並且通過MESSAGEframe從server獲取消息。

STOMP版本之間的變化

STOMP 1.2 大部分向后兼容1.1. 有兩點不兼容的改變: * 用回車加換行符代替只用換行符結束frame * 簡化了消息應答,用專用的header

除此之外,STOMP 1.2並沒有增加新特性,而是闡述規格中的一些模糊概念,比如: * 重復的frame header條目 * content-lengthcontent-typeheaders的用法 * 必須支持servers STOMP frame * 連接延遲 * 作用域,訂閱的唯一,事務的標示符 *RECEIPTframe的含義

 設計哲學

簡易性,互通性是STOMP主要設計哲學.
STOMP被設計成為輕量級的協議,它很容易用其他語言在client和server實現。這就意味着servers的架構沒有太多的約束,以及沒有太多的特性比如目的地命名空間,可靠的語法需要去實現。

在這份規格書里面,注意,我們沒有明確定義的STOMP 1.2 servers特性。你應該查閱STMOMP servers 文檔去獲得這些特性的詳細描述。

一致性

RFC 2119中詳細地解釋了MUSTMUST NOTREQUIREDSHALLSHALL NOTSHOULD,SHOULD NOTRECOMMENDEDMAY, 和 OPTIONAL這些關鍵字
為了阻止來自服務端地攻擊,保護內存溢出,消除平台限制,限制了不受約束的輸入。

規格中一致性的級別適用於STOMP clients and STOMP servers.

STOMP Frames

STOMP是基於幀的協議,它假定底層為一個2-way的可靠流的網絡協議(如TCP)。客戶端和服務器通信使用STOMP幀流通訊。幀的結構看起來像:

COMMAND
header1:value1
header2:value2

Body^@

幀以command字符串開始,以EOL結束,其中包括可選回車符(13字節),緊接着是換行符(10字節)。command下面是0個或多個<key>:<value>格式的header條目, 每個條目由EOL結束。一個空白行(即額外EOL)表示header結束和body開始。body連接着NULL字節。本文檔中的例子將使用^@,在ASCII中用control-@表示,代表NULL字節。NULL字節可以選擇跟多個EOLs。欲了解更多關於STOMP幀的詳細信息,請參閱Augmented BNF節本文件。

本文檔中引用的所有command 和header 名字都是大小寫敏感的.

編碼方式

commands和headers 都是用UTF-8編碼的.在用UTF-8編碼的headers中除了CONNECTCONNECTED幀以外,任何的回車符,換行符,colon found(?)都將被轉義.

轉義的目的在於允許header中的鍵值包含那些把octets當作值的frame header.

為了向后兼容STOMP 1.0, CONNECTCONNECTED不會轉義回車符,換行符,colon found(?)

C風格的字符串轉義被用在UTF-8編碼的headers中去轉義回車符,換行符以及colon found.當解碼headers時,必須使用下列轉換: * \r (octet 92 and 114) translates to carriage return (octet 13) * \n (octet 92 and 110) translates to line feed (octet 10) * \c (octet 92 and 99) translates to : (octet 58) * \\ (octet 92 and 92) translates to \ (octet 92)

未定義轉義序列如\t(octet 92 and 116)必須被視為一個致命的錯誤。相反,當編碼幀頭,必須使用逆轉變.

The STOMP 1.0 specification included many example frames with padding in the headers and many servers and clients were implemented to trim or pad header values. This causes problems if applications want to send headers that SHOULD not get trimmed. In STOMP 1.2, clients and servers MUST never trim or pad headers with spaces.

Body

只有SENDMESSAGE, 和ERROR幀有body。所有其他的幀不能有body。

大多數被用的header都有特殊的含義。

Header content-length

所有的幀可能都包括有content-length的header。它定義了消息體的大小。如果header包含了content-length, 包含空字節的消息體的最大字節數不能超過這個數. 幀仍然需要以空字節結束。

如幀體存在,SENDMESSAGE 和 ERROR幀應該包含content-length.如果幀體包含空字節,那么這個幀必須包括content-length.

Header content-type

如果幀體存在,SENDMESSAGE 和 ERROR幀應該包含content-type幫助接受者去理解幀體.如果設置了content-type, 它的值必須是描述幀體格式的MINE類型.否則,接收者應該認為幀體格式為二進制Blob.

text/開頭的MINE類型的默認文本編碼是UTF-8. 如果你正在用一個基於MINE類型的不同編碼, 你應該添加;charset=<encoding>MINE類型。例如:如果你發送一個UTF-16編碼的HTML body, 應該設置text/html;charset=utf-16;charset=<encoding>也能添加到任何非text/ MINE類型后去作為說明。UTF-8編碼的XML是個很好的例子。它的編碼被設置為application/xml;charset=utf-8.

所有STOMP客戶端和服務端必須支持UTF-8編碼和解碼。因此,為了最大限度地使用在異構環境中的互操作性,建議基於文本的內容使用UTF-8編碼.

Header receipt

任何除了CONNECT的客戶端幀可以為receipt header指定任何值。這會讓服務端應答帶有RECEIPT的客戶端幀的處理過程。

Repeated Header Entries

Since messaging systems can be organized in store and forward topologies, similar to SMTP, a message may traverse several messaging servers before reaching a consumer. A STOMP server MAY ‘update’ header values by either prepending headers to the message or modifying a header in-place in the message.

如果client或者server受到重復的header條目,只有第一個會被用作header條目的值。其他的值僅僅用來維持狀態改變,或者被丟棄。

例如,如果client收到:

MESSAGE
foo:World
foo:Hello

^@

foo header的值為World.

大小限制

為了客戶端濫用服務端的內存分配,服務端可以設置可分配的內存大小:

  • 單個幀允許幀頭的個數
  • header中每一行的最大長度
  • 幀體的大小

如果超出了這些限制,server應該向client發送一個error frame,然后關閉連接.

連接延遲

STOMP servers必須支持client快速地連接server和斷開連接。 這意味着server在連接重置前只允許被關閉的連接短時間地延遲.

結果就是,在socket重置前client可能不會收到server發來的最后一個frame(比如ERROR或者RECEIPTframe去應答DISCONNECTframe)

Connecting

STOMP client通過CONNECTframe與server建立流或者TCP連接.

CONNECT
accept-version:1.2
host:stomp.github.org

^@

如果server收到請求,將返回CONNECTEDframe:

CONNECTED
version:1.2

^@

server能拒絕所有的連接請求。server應該響應ERRORframe去說明為什么連接被拒絕然后關閉連接。

CONNECT or STOMP Frame

STOMP servers 處理STOMPframe必須和處理CONNECTframe一樣。STOMP1.2 clients應該繼續使用CONNECTcommand去向后兼容1.0.

使用STOMPframe的clients只能連接上STOMP1.2 servers(以及一些STOMP1.1 servers),但是好處在於協議探針能夠從HTTP連接中區分開STOMP連接。

STOMP 1.2 clients 必須設置以下headers: * accept-version: clients支持的STOMP的版本號。詳情見Protocol_Negotiation * host:client希望連接的虛擬主機名字,建議設置已經連接的socket為主機名,或者任何名字。如果headers沒有匹配到任何可用的虛擬主機,支持虛擬主機的servers將選擇默認的虛擬主機或者拒絕連接。

STOMP 1.2 clients可選擇設置以下headers: * login: 用於在server驗證的用戶id *passcode: 用於在server驗證的密碼 * heart-beat心跳設置

CONNECTED Frame

STOMP 1.2 servers 必須設置以下headers:

STOMP 1.2 servers可選擇設置以下headers:

  • heart-beat: 心跳設置
  • session: 唯一的會話identifier
  • server: 描述STOMP server信息。它必須包含server-name,可以包含一些注釋信息(用空格分開) server-name后面也可以帶着可選的版本號.

      server = name ["/" version] *(comment)
    

    例如:

      server:Apache/1.3.9
    

Protocol Negotiation

STOMP1.1 以后的版本,CONNECTframe必須包括accept-versionheader.它的值為clients支持的STOMP版本號,多個版本號用,隔開。如果不存在accept-versionheader,那么表明clients只支持1.0.

在一次會話中將使用雙方都支持的最高版本。

例如,如果client發送:

CONNECT
accept-version:1.0,1.1,2.0
host:stomp.github.org

^@

server將返回與客戶端同時支持的最高版本。

CONNECTED
version:1.1

^@

如果client和server不支持共同的協議版本,server必須返回如下的ERRORframe,然后斷開連接。

ERROR
version:1.2,2.1
content-type:text/plain

Supported protocol versions are 1.2 2.1^@

心跳

心跳被用於去測試底層TCP連接的可用性,確保遠端服務處於活動狀態。

要使用心跳,每個部分必須聲明它能干什么以及想要其他部分干什么. 通過在CONNECTCONNECTEDframe中增加heart-beatheader, 讓心跳在會話開始被定義好。heart-beatheader必須包含兩個用逗號隔開的正整數。

第一個數字代表發送方能做什么: * 0表示它不能發送心跳 * 否則它是能保證兩次心跳的最小毫秒數

第二個數字代表發送方能獲得什么: * 0表示它不想接收心跳 * 否則它表示兩次心跳期望的毫秒數

heart-beatheader是OPTIONAL的。沒有的話會被當作heart-beat:0,0header 處理,意思就是說它不會發送心跳並且不想接收心跳。

heart-beatheader提供了足夠的信息去了解每個部分心跳是否可用,發送到哪里,頻率的大小.

原始frame像這個樣子:

CONNECT
heart-beat:<cx>,<cy>
   
CONNECTED:
heart-beat:<sx>,<sy>

對於client發送server的心跳: * 如果<cx>為0(client不能發送心跳)或者<sy>為0(server不想接收心跳),將不起任何作用。 * 否則心跳頻率為MAX(<cx>,<sy>)毫秒數.

相反,<sx><cy>同樣是這樣的.

關於心跳本身,通過網絡連接收到的任何數據表明遠端服務是可用的。在給定的指向,如果心跳的頻率被期望是<n>毫秒:

  • 發送者必須每<n>毫秒發送新數據。
  • 如果發送者沒有真實的STOMP frame,必須發送一個end-of-line (EOL)
  • 如果接受者在規定的時間內沒有收到新數據,表明連接已經斷開
  • 由於時間誤差,接收者應該容錯和考慮定義錯誤的界限

Client Frames

client可以發送下列列表以外的frame,但是STOMP1.2 server會響應ERRORframe,然后關閉連接。

SEND

SENDframe發送消息到目的地,它必須包含表示目的地地址的destinationheader.SENDframe body是被發送的消息。例如:

SEND
destination:/queue/a
content-type:text/plain

hello queue a
^@

這個消息被發送到/queue/a.注意STOMP把目的地看作為一個不透明的字符串,沒有目的地假設的交互語義.你應該查閱STOMP server文檔,搞清楚如何構造目的地名字。

可靠的消息語義是server指定的,依賴備用的目的地的值和其他消息headers,比如事務headers,或者其他server指定的消息headers。

SEND可以添加transactionheader來支持事務處理.

如果body存在,那么SENDframe應該包含一個content-lengthcontent-typeheader

一個應用可以給SENDframe增加任意多個用戶定義的headers。 通常用於用戶定義的頭,讓消費者能夠根據應用程序定義的報頭使用選擇訂閱幀過濾消息。 被定義的用戶必須通過MESSAGEframe傳送。

如果server不能無故成功處理SENDframe,那么server必須向client發送ERRORframe然后關閉連接。

SUBSCRIBE

SUBSCRIBEframe用於注冊給定的目的地.和SENDframe一樣,SUBSCRIBEframe需要包含destinationheader表明client想要訂閱目的地。 被訂閱的目的地收到的任何消息將通過MESSAGEframe發送給client。 ackheader控制着確認模式。

例子:

SUBSCRIBE
id:0
destination:/queue/foo
ack:client

^@

如果server不能成功創建此次訂閱,那么server將返回ERRORframe然后關閉連接。

STOMP服務器可能支持額外的服務器特定的頭文件,來自定義有關訂閱傳遞語義.

SUBSCRIBE id Header

一個單連接可以對應多個開放的servers訂閱,所以必須包含idheader去唯一標示這個訂閱.這個idframe可以把此次訂閱與接下來的MESSAGEframe和UNSUBSCRIBEframe聯系起來。

在相同的連接中,不同的訂閱必須擁有不同訂閱id。

SUBSCRIBE ack Header

ackheader可用的值有autoclient,client-individual, 默認為auto.

ackauto時,client收到server發來的消息后不需要回復ACKframe.server假定消息發出去后client就已經收到。這種確認方式可以減少消息傳輸的次數.

ackclient時, client必須發送ACkframe給servers, 讓它處理消息.如果在client發送ACKframe之前連接斷開了,那么server將假設消息沒有被處理,可能會再次發送消息給另外的客戶端。client發送的ACKframe被當作時積累的確認。這就意味這種確認方式會去操作ACKframe指定的消息和訂閱的所有消息

由於client不能處理某些消息,所以client應該發送NACKframe去告訴server它不能消費這些消息。

當ack模式是client-individual,確認工作就像客戶端確認模式(除了由客戶端發送的ACKNACK幀)不會被累計。這意味着,后續ACKNACK消息幀,也不能影響前面的消息的確認。

UNSUBSCRIBE

UNSUBSCRIBEframe被用於去移除已經存在訂閱。一旦訂閱被刪除后,STOMP連接將不再會收到來自訂閱發出的消息。

一個單連接可以對應多個開放的server訂閱,所以必須包含idheader去唯一標示被刪除的訂閱.這個header中的id必須匹配已存在訂閱.

例如:

UNSUBSCRIBE
id:0

^@

ACK

ACKclientclient-individual去確認訂閱消息的消費.只有通過ACK確認過后,訂閱的消息才算是被消費.

ACKframe必須包含一個idheader去匹配將要被確認的ackheader中的id.可以選擇地指定transactionheader表明消息確認應該是命名事務地一部分。

ACK
id:12345
transaction:tx1

^@

NACK

NACKACK相反地作用。它地作用是告訴server client不想消費這個消息。server然后發送這個消息給另外的client,丟棄它或者把它放在無效的消息隊列中。這種准確的行為是server特定的。

NACK有相同的ACKheaders: id(必選)和transaction(可選)。

NACK適用於單個消息(訂閱的ack模式為client-individual), 或者那些還沒有被ACK'edNACK'ed的消息(訂閱模式ack為client).

BEGIN

BEGIN用於事務的開始。事務被用於發送和確認消息,被發送和被確認的消息在事務過程中會被自動處理。

BEGIN
transaction:tx1

^@

transactionheader是必填的,並且事務id將被用於在SEND, COMMIT, ABORT, ACK, and NACK frames去綁定命名的事務.在相同的連接中,不同事務必須用不同的id

如果client發送DISCONNECTframe或者TCP連接失敗,任何已開始但沒有提交的事務默認都會被中斷.

COMMIT

COMMIT用於在過程中提交事務.

COMMIT
transaction:tx1

^@

transactionheader是必填的並且必須指定將要提交的事務的id.

ABORT

ABORT用於在過程中回滾事務.

ABORT
transaction:tx1

^@

transactionheader是必填的並且必須指定將要提交的事務的id.

DISCONNECT

client能在任何時候斷開server的連接,但是不能保證已經發送的frame已經到達了server。為了讓這一切顯得不那么暴力,client確保所有已經發送的frames已經被server收到,client應該做以下3點:

  1. 發送帶有receiptheader的DISCONNECTframe

     DISCONNECT
     receipt:77
     ^@
    
  2. 等待帶有RECEIPTframe的響應

     RECEIPT
     receipt-id:77
     ^@
    
  3. 關閉socket

注意,如果server過早地關閉socket,client將不會收到期望地RECEIPTframe.見Connection_Lingering

client發送DISCONNECTframe后不必要在發送任何frame.

Server Frames

server偶爾也會發送frame給客戶端(除了連接最初的CONNECTEDframe).

這些frames為: * MESSAGE * RECEIPT * ERROR

MESSAGE

MESSAGEframe用於將訂閱的消息發送給client.

MESSAGEframe必須包含destinationheader表明信息要到達的目的地。如果消息已經用STOMP發送,那么destinationheader應該和SENDframe中的一樣。

MESSAGEframe必須包含帶有唯一標識的message-idheader和帶有將接收消息的訂閱的idsubscriptionheader.

如果從訂閱收到的消息需要明確作出確認(client或者client-individual模式),那么MESSAGEframe必須包含帶有任何值的ackheader.這個header將把消息和后來的ACK,NACKframe關聯起來。

下面這個frame body包含了消息的內容:

MESSAGE
subscription:0
message-id:007
destination:/queue/a
content-type:text/plain

hello queue a^@

如果frame body包含內容的話,MESSAGEframe應該包含content-lengthheader和content-typeheader.

除了那些server指定的headers, 消息被發送到目的地時,MESSAGEframe同樣應該包括所有用戶定義的headers.查閱有關文檔,找出那些server指定添加到messages的headers.

RECEIPT

server成功處理請求帶有receipt的client frame后, 將發送RECEIPTframe到client.RECEIPTframe必須包含receipt-id header,它的值為client frame中receiptheader的值。

RECEIPT
receipt-id:message-12345

^@

RECEIPTframe是作為server處理的client frame后的應答. 既然STOMP是基於流的,那么receipt也是對server已經收到所有的frames的累積確認。但是,以前的frames可能並沒有被完全處理。如果clients斷開連接,以前接收到的frames應該繼續被server處理。

ERROR

如果出錯的話,server將發送ERRORframe.這種情況下,server還應該斷開連接。查看下一章connection lingering ERRORframe應該包含帶有簡單錯誤信息的messageheader,或者Body包含詳細的描述信息,也可能沒有。

ERROR
receipt-id:message-12345
content-type:text/plain
content-length:171
message: malformed frame received

The message:
-----
MESSAGE
destined:/queue/a
receipt:message-12345

Hello queue a!
-----
Did not contain a destination header, which is REQUIRED
for message propagation.
^@

如果錯誤關聯到了具體的某個client frame,那么server應該增加額外的headers去識別引起錯誤的frame。例如,如果frame包含receiptheader,ERRORframe應該設置receipt-idheader的值為引起錯誤的frame的receiptheader的值。

如果frame body包含內容的話,ERRORframe應該包含content-lengthheader和content-typeheader

Frames and Headers

除了上述標准headers之外(content-lengthcontent-typereceipt),下面列出了所有規范中定義的headers:

  • CONNECT or STOMP
    • REQUIRED: accept-version, host
    • OPTIONAL: login, passcode, heart-beat
  • CONNECTED
    • REQUIRED: version
    • OPTIONAL: session, server, heart-beat
  • SEND
    • REQUIRED: destination
    • OPTIONAL: transaction
  • SUBSCRIBE
    • REQUIRED: destination, id
    • OPTIONAL: ack
  • UNSUBSCRIBE
    • REQUIRED: id
    • OPTIONAL: none
  • ACK or NACK
    • REQUIRED: id
    • OPTIONAL: transaction
  • BEGIN or COMMIT or ABORT
    • REQUIRED: transaction
    • OPTIONAL: none
  • DISCONNECT
    • REQUIRED: none
    • OPTIONAL: receipt
  • MESSAGE
    • REQUIRED: destination, message-id, subscription
    • OPTIONAL: ack
  • RECEIPT
    • REQUIRED: receipt-id
    • OPTIONAL: none
  • ERROR
    • REQUIRED: none
    • OPTIONAL: message

除此之外,SENDMESSAGEframes可能包含任意的用戶定義的headers ,它們會成為carried message的一部分。同樣,ERRORframe應該包含額外的headers來識別引起錯誤的frame。

最終,STOMP servers可以用額外的headers去訪問持久化或者有效期特性.查閱server文檔獲得更多信息。

Augmented BNF

A STOMP session can be more formally described using the Backus-Naur Form (BNF) grammar used in HTTP/1.1 RFC 2616.

NULL                = <US-ASCII null (octet 0)>
LF                  = <US-ASCII line feed (aka newline) (octet 10)>
CR                  = <US-ASCII carriage return (octet 13)>
EOL                 = [CR] LF 
OCTET               = <any 8-bit sequence of data>

frame-stream        = 1*frame

frame               = command EOL
                      *( header EOL )
                      EOL
                      *OCTET
                      NULL
                      *( EOL )

command             = client-command | server-command

client-command      = "SEND"
                      | "SUBSCRIBE"
                      | "UNSUBSCRIBE"
                      | "BEGIN"
                      | "COMMIT"
                      | "ABORT"
                      | "ACK"
                      | "NACK"
                      | "DISCONNECT"
                      | "CONNECT"
                      | "STOMP"

server-command      = "CONNECTED"
                      | "MESSAGE"
                      | "RECEIPT"
                      | "ERROR"

header              = header-name ":" header-value
header-name         = 1*<any OCTET except CR or LF or ":">
header-value        = *<any OCTET except CR or LF or ":">

License

This specification is licensed under the Creative Commons Attribution v3.0 license.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM