Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 1
<?php
2
namespace Ratchet\Wamp;
3
use Ratchet\MessageComponentInterface;
4
use Ratchet\WebSocket\WsServerInterface;
5
use Ratchet\ConnectionInterface;
6
 
7
/**
8
 * WebSocket Application Messaging Protocol
9
 *
10
 * @link http://wamp.ws/spec
11
 * @link https://github.com/oberstet/autobahn-js
12
 *
13
 * +--------------+----+------------------+
14
 * | Message Type | ID | DIRECTION        |
15
 * |--------------+----+------------------+
16
 * | WELCOME      | 0  | Server-to-Client |
17
 * | PREFIX       | 1  | Bi-Directional   |
18
 * | CALL         | 2  | Client-to-Server |
19
 * | CALL RESULT  | 3  | Server-to-Client |
20
 * | CALL ERROR   | 4  | Server-to-Client |
21
 * | SUBSCRIBE    | 5  | Client-to-Server |
22
 * | UNSUBSCRIBE  | 6  | Client-to-Server |
23
 * | PUBLISH      | 7  | Client-to-Server |
24
 * | EVENT        | 8  | Server-to-Client |
25
 * +--------------+----+------------------+
26
 */
27
class ServerProtocol implements MessageComponentInterface, WsServerInterface {
28
    const MSG_WELCOME     = 0;
29
    const MSG_PREFIX      = 1;
30
    const MSG_CALL        = 2;
31
    const MSG_CALL_RESULT = 3;
32
    const MSG_CALL_ERROR  = 4;
33
    const MSG_SUBSCRIBE   = 5;
34
    const MSG_UNSUBSCRIBE = 6;
35
    const MSG_PUBLISH     = 7;
36
    const MSG_EVENT       = 8;
37
 
38
    /**
39
     * @var WampServerInterface
40
     */
41
    protected $_decorating;
42
 
43
    /**
44
     * @var \SplObjectStorage
45
     */
46
    protected $connections;
47
 
48
    /**
49
     * @param WampServerInterface $serverComponent An class to propagate calls through
50
     */
51
    public function __construct(WampServerInterface $serverComponent) {
52
        $this->_decorating = $serverComponent;
53
        $this->connections = new \SplObjectStorage;
54
    }
55
 
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function getSubProtocols() {
60
        if ($this->_decorating instanceof WsServerInterface) {
61
            $subs   = $this->_decorating->getSubProtocols();
62
            $subs[] = 'wamp';
63
 
64
            return $subs;
65
        }
66
 
67
        return ['wamp'];
68
    }
69
 
70
    /**
71
     * {@inheritdoc}
72
     */
73
    public function onOpen(ConnectionInterface $conn) {
74
        $decor = new WampConnection($conn);
75
        $this->connections->attach($conn, $decor);
76
 
77
        $this->_decorating->onOpen($decor);
78
    }
79
 
80
    /**
81
     * {@inheritdoc}
82
     * @throws \Ratchet\Wamp\Exception
83
     * @throws \Ratchet\Wamp\JsonException
84
     */
85
    public function onMessage(ConnectionInterface $from, $msg) {
86
        $from = $this->connections[$from];
87
 
88
        if (null === ($json = @json_decode($msg, true))) {
89
            throw new JsonException;
90
        }
91
 
92
        if (!is_array($json) || $json !== array_values($json)) {
93
            throw new Exception("Invalid WAMP message format");
94
        }
95
 
96
        if (isset($json[1]) && !(is_string($json[1]) || is_numeric($json[1]))) {
97
            throw new Exception('Invalid Topic, must be a string');
98
        }
99
 
100
        switch ($json[0]) {
101
            case static::MSG_PREFIX:
102
                $from->WAMP->prefixes[$json[1]] = $json[2];
103
            break;
104
 
105
            case static::MSG_CALL:
106
                array_shift($json);
107
                $callID  = array_shift($json);
108
                $procURI = array_shift($json);
109
 
110
                if (count($json) == 1 && is_array($json[0])) {
111
                    $json = $json[0];
112
                }
113
 
114
                $this->_decorating->onCall($from, $callID, $from->getUri($procURI), $json);
115
            break;
116
 
117
            case static::MSG_SUBSCRIBE:
118
                $this->_decorating->onSubscribe($from, $from->getUri($json[1]));
119
            break;
120
 
121
            case static::MSG_UNSUBSCRIBE:
122
                $this->_decorating->onUnSubscribe($from, $from->getUri($json[1]));
123
            break;
124
 
125
            case static::MSG_PUBLISH:
126
                $exclude  = (array_key_exists(3, $json) ? $json[3] : null);
127
                if (!is_array($exclude)) {
128
                    if (true === (boolean)$exclude) {
129
                        $exclude = [$from->WAMP->sessionId];
130
                    } else {
131
                        $exclude = [];
132
                    }
133
                }
134
 
135
                $eligible = (array_key_exists(4, $json) ? $json[4] : []);
136
 
137
                $this->_decorating->onPublish($from, $from->getUri($json[1]), $json[2], $exclude, $eligible);
138
            break;
139
 
140
            default:
141
                throw new Exception('Invalid WAMP message type');
142
        }
143
    }
144
 
145
    /**
146
     * {@inheritdoc}
147
     */
148
    public function onClose(ConnectionInterface $conn) {
149
        $decor = $this->connections[$conn];
150
        $this->connections->detach($conn);
151
 
152
        $this->_decorating->onClose($decor);
153
    }
154
 
155
    /**
156
     * {@inheritdoc}
157
     */
158
    public function onError(ConnectionInterface $conn, \Exception $e) {
159
        return $this->_decorating->onError($this->connections[$conn], $e);
160
    }
161
}