Server : Apache System : Linux iZ2vcgyutqttsd1p850kl8Z 3.10.0-1160.92.1.el7.x86_64 #1 SMP Tue Jun 20 11:48:01 UTC 2023 x86_64 User : www ( 1000) PHP Version : 5.6.40 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv Directory : /www/wwwroot/saimikebio.com/includes/prism-php/lib/ |
<?php class prism_notify { private $client; private $connected = false; private $sock; private $_frames = array(); private $messages = array(); private $last_buf = ''; private $consuming = false; const TextFrame = 0x01; const BinaryFrame = 0x02; const CloseFrame = 0x08; const PingFrame = 0x09; const PongFrame = 0x09; const action_publish = 1; const action_ack = 3; const action_consume = 2; function __construct(&$client){ $this->client = $client; $this->client->register_handler(101, array($this, 'handle_upgrade')); $this->connect(); } public function pub($routing_key, $message, $ctype="text/plain"){ $size_routing_key = strlen($routing_key); $size_message = strlen($message); $size_ctype = strlen($ctype); $this->send(self::action_publish, pack("na*Na*na*", $size_routing_key, $routing_key, $size_message, $message, $size_ctype, $ctype)); } public function close(){ if($this->connected){ fwrite($this->sock, $this->encode(self::CloseFrame)); fclose($this->sock); $this->connected = false; } } private function consume(){ if(!$this->consuming){ $this->send(self::action_consume); $this->consuming = true; } } private function send($type, $message=""){ if(!$this->connected || !@fwrite($this->sock, $this->encode(self::BinaryFrame, pack("ca*", $type , $message)))){ $this->connected = false; throw new prism_exception("websocket is not connected"); } } public function ack($tid){ return $this->send(prism_notify::action_ack, $tid); } public function get(){ if(!$this->consuming){ $this->consume(); } while (!isset($this->messages[0])){ $this->recv_message(); } return new prism_message($this, array_shift($this->messages)); } public function handle_upgrade($c, $sock){ $this->client->log("connected"); $this->connected = true; $this->consuming = false; $this->sock = $sock; register_shutdown_function(array($this, 'close')); } private function connect(){ $headers = array('Upgrade'=>'websocket', 'Sec-Websocket-Key' => $this->wskey(), 'Sec-WebSocket-Version' => 13, 'Sec-WebSocket-Protocol' => 'chat', 'Origin' => $this->client->base_url.'/platform/notify', 'Connection'=>'Upgrade'); $error = $this->client->get('platform/notify', array(), $headers); if($error){ if (is_object($error)){ $error = $error->message; } $this->client->log("websocket handshake error: ".$error); } } private function recv_message(){ $raw = fread($this->sock, 8192); $raw = $this->last_buf . $raw; $this->last_buf = ''; $i = 0; while($raw){ $i ++; $len = ord($raw[1]) & ~128; $data = substr($raw, 2); if ($len == 126) { $arr = unpack("n", $data); $len = array_pop($arr); $data = substr($data, 2); } elseif ($len == 127) { list(, $h, $l) = unpack('N2', $data); $len = ($l + ($h * 0x0100000000)); $data = substr($data, 8); } if(strlen($data)>=$len){ array_push($this->messages, substr($data, 0, $len)); $raw = substr($data, $len); }else{ $this->last_buf = $raw; return $i; } } return $i; } private function encode($type, $data='') { $b1 = 0x80 | ($type & 0x0f); $length = strlen($data); if($length <= 125) $header = pack('CC', $b1, 128 + $length); elseif($length > 125 && $length < 65536) $header = pack('CCn', $b1, 128 + 126, $length); elseif($length >= 65536) $header = pack('CCN', $b1, 128 + 127, $length); $key = 0; $key = pack("N", rand(0, pow(255, 4) - 1)); $header .= $key; return $header.$this->rotMask($data, $key); } private function wskey(){ return base64_encode(time()); } private function rotMask($data, $key, $offset = 0) { $res = ''; for ($i = 0; $i < strlen($data); $i++) { $j = ($i + $offset) % 4; $res .= chr(ord($data[$i]) ^ ord($key[$j])); } return $res; } } class prism_exception extends Exception{ } class prism_command{ var $type; var $data; function __construct($type, $data=""){ $this->type = $type; $this->data = $data; } function __toString(){ return json_encode(array( 'type'=> &$this->type, 'data'=> &$this->data, )); } } class prism_message{ public $body; public $content_type; private $conn; private $raw; private $tid; function __construct($conn, $raw){ $this->raw = $raw; $this->data = json_decode($raw); $this->conn = $conn; if($this->data){ $this->body = &$this->data->body; $this->tid = &$this->data->tag; $this->content_type = $this->data->type; }else{ $this->body = &$this->raw; } } function ack(){ return $this->conn->ack($this->tid); } function __toString(){ return (string)$this->body; } }