/websocket/vendor/cboden/ratchet/src/Ratchet/Wamp/ServerProtocol.php

https://github.com/ivebeenlinuxed/Boiler · PHP · 157 lines · 87 code · 24 blank · 46 comment · 12 complexity · 4b154b7d66d3c46cca2934c1d8ceeaa9 MD5 · raw file

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