Created
October 29, 2014 14:53
-
-
Save ZiTAL/40bb7bafad693dc99c5c to your computer and use it in GitHub Desktop.
Revisions
-
ZiTAL created this gist
Oct 29, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,187 @@ <?php /* based on: http://stackoverflow.com/questions/7160899/websocket-client-in-php/16608429#16608429 FIRST EXEC PYTHON SCRIPT TO GET HEADERS */ $ws = new ws(array ( 'host' => '127.0.0.1', 'port' => 8080, 'path' => '' )); $result = $ws->send('message'); $ws->close(); echo $result; class ws { private $params; private $head; private $instance; public function __construct($params) { foreach($params as $key => $value) $this->params[$key] = $value; $local = "http://".$this->params['host']; if(isset($_SERVER['REMOTE_ADDR'])) $local = "http://".$_SERVER['REMOTE_ADDR']; $this->head = "GET / HTTP/1.1\r\n" . "Upgrade: websocket\r\n" . "Connection: Upgrade\r\n" . "Host: ".$this->params['host']."\r\n" . "Origin: ".$local."\r\n" . "Sec-WebSocket-Key: TyPfhFqWTjuw8eDAxdY8xg==\r\n" . "Sec-WebSocket-Version: 13\r\n"; } public function send($method) { $this->head .= "Content-Length: ".strlen($method)."\r\n\r\n"; $this->connect(); fwrite($this->instance, $this->hybi10Encode($method)); $wsdata = fread($this->instance, 2000); return $this->hybi10Decode($wsdata); } public function close() { if($this->instance) { fclose($this->instance); $this->instance = NULL; } } private function connect() { $sock = fsockopen($this->params['host'], $this->params['port'], $errno, $errstr, 2); fwrite($sock, $this->head); $headers = fread($sock, 2000); $this->instance = $sock; } private function hybi10Decode($data) { $bytes = $data; $dataLength = ''; $mask = ''; $coded_data = ''; $decodedData = ''; $secondByte = sprintf('%08b', ord($bytes[1])); $masked = ($secondByte[0]=='1') ? true : false; $dataLength = ($masked===true) ? ord($bytes[1]) & 127 : ord($bytes[1]); if ($masked===true) { if ($dataLength===126) { $mask = substr($bytes, 4, 4); $coded_data = substr($bytes, 8); } elseif ($dataLength===127) { $mask = substr($bytes, 10, 4); $coded_data = substr($bytes, 14); } else { $mask = substr($bytes, 2, 4); $coded_data = substr($bytes, 6); } for ($i = 0; $i<strlen($coded_data); $i++) $decodedData .= $coded_data[$i] ^ $mask[$i % 4]; } else { if ($dataLength===126) $decodedData = substr($bytes, 4); elseif ($dataLength===127) $decodedData = substr($bytes, 10); else $decodedData = substr($bytes, 2); } return $decodedData; } private function hybi10Encode($payload, $type = 'text', $masked = true) { $frameHead = array(); $frame = ''; $payloadLength = strlen($payload); switch ($type) { case 'text' : // first byte indicates FIN, Text-Frame (10000001): $frameHead[0] = 129; break; case 'close' : // first byte indicates FIN, Close Frame(10001000): $frameHead[0] = 136; break; case 'ping' : // first byte indicates FIN, Ping frame (10001001): $frameHead[0] = 137; break; case 'pong' : // first byte indicates FIN, Pong frame (10001010): $frameHead[0] = 138; break; } // set mask and payload length (using 1, 3 or 9 bytes) if ($payloadLength>65535) { $payloadLengthBin = str_split(sprintf('%064b', $payloadLength), 8); $frameHead[1] = ($masked===true) ? 255 : 127; for ($i = 0; $i<8; $i++) $frameHead[$i + 2] = bindec($payloadLengthBin[$i]); // most significant bit MUST be 0 (close connection if frame too big) if ($frameHead[2]>127) { $this->close(1004); return false; } } elseif ($payloadLength>125) { $payloadLengthBin = str_split(sprintf('%016b', $payloadLength), 8); $frameHead[1] = ($masked===true) ? 254 : 126; $frameHead[2] = bindec($payloadLengthBin[0]); $frameHead[3] = bindec($payloadLengthBin[1]); } else $frameHead[1] = ($masked===true) ? $payloadLength + 128 : $payloadLength; // convert frame-head to string: foreach (array_keys($frameHead) as $i) $frameHead[$i] = chr($frameHead[$i]); if ($masked===true) { // generate a random mask: $mask = array(); for ($i = 0; $i<4; $i++) $mask[$i] = chr(rand(0, 255)); $frameHead = array_merge($frameHead, $mask); } $frame = implode('', $frameHead); // append payload to frame: for ($i = 0; $i<$payloadLength; $i++) $frame .= ($masked===true) ? $payload[$i] ^ $mask[$i % 4] : $payload[$i]; return $frame; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,14 @@ # FIRST exec this script to get the headers to put then in the php script ;) # # requirements: # pip install websocket-client import websocket if __name__ == "__main__": websocket.enableTrace(True) ws = websocket.create_connection("ws://127.0.0.1:8080") ws.send("message") result = ws.recv() print result ws.close() This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,23 @@ /* websocket server requirements: npm install ws */ var WebSocketServer = require('ws').Server; var wss = new WebSocketServer( { host: '127.0.0.1', port: 8080 }); wss.on('connection', function(ws) { console.log('connect'); ws.on('message', function(message) { console.log('received: %s', message); }); ws.send('something'); });