]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/liberalstomp.php
Merge branch '0.9.x' of git@gitorious.org:statusnet/mainline into 0.9.x
[quix0rs-gnu-social.git] / lib / liberalstomp.php
1 <?php
2
3 /**
4  * Based on code from Stomp PHP library, working around bugs in the base class.
5  *
6  * Original code is copyright 2005-2006 The Apache Software Foundation
7  * Modifications copyright 2009 StatusNet Inc by Brion Vibber <brion@status.net>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 class LiberalStomp extends Stomp
23 {
24     /**
25      * We need to be able to get the socket so advanced daemons can
26      * do a select() waiting for input both from the queue and from
27      * other sources such as an XMPP connection.
28      *
29      * @return resource
30      */
31     function getSocket()
32     {
33         return $this->_socket;
34     }
35
36     /**
37      * Make socket connection to the server
38      * We also set the stream to non-blocking mode, since we'll be
39      * select'ing to wait for updates. In blocking mode it seems
40      * to get confused sometimes.
41      *
42      * @throws StompException
43      */
44     protected function _makeConnection ()
45     {
46         parent::_makeConnection();
47         stream_set_blocking($this->_socket, 0);
48     }
49
50     /**
51      * Version 1.0.0 of the Stomp library gets confused if messages
52      * come in too fast over the connection. This version will read
53      * out as many frames as are ready to be read from the socket.
54      *
55      * Modified from Stomp::readFrame()
56      *
57      * @return StompFrame False when no frame to read
58      */
59     public function readFrames ()
60     {
61         if (!$this->hasFrameToRead()) {
62             return false;
63         }
64         
65         $rb = 1024;
66         $data = '';
67         $end = false;
68         $frames = array();
69
70         do {
71             // @fixme this sometimes hangs in blocking mode...
72             // shouldn't we have been idle until we found there's more data?
73             $read = fread($this->_socket, $rb);
74             if ($read === false) {
75                 $this->_reconnect();
76                 // @fixme this will lose prior items
77                 return $this->readFrames();
78             }
79             $data .= $read;
80             if (strpos($data, "\x00") !== false) {
81                 // Frames are null-delimited, but some servers
82                 // may append an extra \n according to old bug reports.
83                 $data = str_replace("\x00\n", "\x00", $data);
84                 $chunks = explode("\x00", $data);
85
86                 $data = array_pop($chunks);
87                 $frames = array_merge($frames, $chunks);
88                 if ($data == '') {
89                     // We're at the end of a frame; stop reading.
90                     break;
91                 } else {
92                     // In the middle of a frame; keep going.
93                 }
94             }
95             // @fixme find out why this len < 2 check was there
96             //$len = strlen($data);
97         } while (true);//$len < 2 || $end == false);
98
99         return array_map(array($this, 'parseFrame'), $frames);
100     }
101     
102     /**
103      * Parse a raw Stomp frame into an object.
104      * Extracted from Stomp::readFrame()
105      *
106      * @param string $data
107      * @return StompFrame
108      */
109     function parseFrame($data)
110     {
111         list ($header, $body) = explode("\n\n", $data, 2);
112         $header = explode("\n", $header);
113         $headers = array();
114         $command = null;
115         foreach ($header as $v) {
116             if (isset($command)) {
117                 list ($name, $value) = explode(':', $v, 2);
118                 $headers[$name] = $value;
119             } else {
120                 $command = $v;
121             }
122         }
123         $frame = new StompFrame($command, $headers, trim($body));
124         if (isset($frame->headers['transformation']) && $frame->headers['transformation'] == 'jms-map-json') {
125             require_once 'Stomp/Message/Map.php';
126             return new StompMessageMap($frame);
127         } else {
128             return $frame;
129         }
130         return $frame;
131     }
132 }
133