예제 #1
0
 /**
  * Send a message to WebSocket clients (use port + 1 for SSL connections)
  */
 public static function send($type, $msg, $to = false)
 {
     $proto = self::$ssl ? 'wss' : 'ws';
     $port = self::$ssl ? self::$port + 1 : self::$port;
     $ws = new WebSocketClient("{$proto}://localhost:" . self::$port);
     $ws->send(json_encode(array('type' => $type, 'from' => self::$clientID, 'msg' => $msg, 'to' => $to)));
     $ws->close();
 }
예제 #2
0
 private function send($msg)
 {
     $msg = WebSocketClient::draft10Encode($msg, 'text', true);
     if (!fwrite($this->sock, $msg)) {
         throw new \Exception('Socket write error! ' . PHP_EOL);
     }
 }
예제 #3
0
 private function registerClient()
 {
     if (($client = @stream_socket_accept($this->handle)) !== false) {
         $clientHandle = new WebSocketClient($client);
         $this->log('Start session %s:%d', self::LOG_INFO, $clientHandle->address, $clientHandle->port);
         $header = array();
         $state = false;
         $request = $clientHandle->read();
         foreach (explode("\n", trim($request)) as $line) {
             if ($state === false) {
                 $header[] = trim($line);
                 $state = true;
             } else {
                 $data = explode(':', $line);
                 $header[strtolower($data[0])] = trim(implode(':', array_slice($data, 1)));
             }
         }
         if (isset($header[0]) === false || preg_match('/^GET (.*?) HTTP/i', $header[0], $match) === 0) {
             $this->sendHandShakeError($clientHandle, 400);
             return false;
         }
         $resource = parse_url($match[1]);
         if (isset($resource['path']) === false) {
             $this->sendHandShakeError($clientHandle, 400);
             return false;
         }
         $clientHandle->resource = $resource === '/' ? '/' : substr($resource['path'], 1);
         if (isset($resource['query']) === true) {
             parse_str($resource['query'], $clientHandle->resourceQuery);
         } else {
             $clientHandle->resourceQuery = array();
         }
         if ($clientHandle->resource !== '/' && isset($this->maxResourceClients[$clientHandle->resource]) === false) {
             $this->sendHandShakeError($clientHandle, 400);
             return false;
         }
         $clientHandle->version = isset($header['sec-websocket-version']) === false ? 0 : (int) $header['sec-websocket-version'];
         if (isset($header['sec-websocket-key']) === true) {
             $clientHandle->rfc = true;
             if ($this->checkOrigin !== false) {
                 if (isset($header['origin']) === false && isset($header['sec-websocket-origin']) === false) {
                     $this->sendHandShakeError($client, 400);
                     return false;
                 }
                 $check = parse_url(isset($header['host']) === true ? $header['host'] : (isset($header['origin']) === true ? $header['origin'] : $header['sec-websocket-origin']));
                 if (isset($check['host']) === false || in_array($check['host'], $this->checkOrigin) === false || ($this->port !== 80 && $this->port !== 443 && isset($check['port']) === false || $this->port !== $check['port'])) {
                     $this->sendHandShakeError($client, 400);
                     return false;
                 }
             }
             // send handshake
             $handshake = "HTTP/1.1 101 Switching Protocols\r\n";
             $handshake .= "Upgrade: websocket\r\n";
             $handshake .= "Connection: Upgrade\r\n";
             $handshake .= "Sec-WebSocket-Accept: " . base64_encode(sha1($header['sec-websocket-key'] . self::GUID, true)) . "\r\n";
             $handshake .= "\r\n";
             $clientHandle->write($handshake);
         } else {
             if (isset($header['sec-websocket-key1'], $header['sec-websocket-key2'], $header['host']) === true) {
                 $clientHandle->rfc = false;
                 if (isset($header['origin']) === false && isset($header['sec-websocket-origin']) === false) {
                     $this->sendHandShakeError($clientHandle, 400);
                     return false;
                 }
                 $origin = isset($header['origin']) === true ? $header['origin'] : $header['sec-websocket-origin'];
                 if ($this->checkOrigin !== false) {
                     $check = parse_url(isset($header['host']) === true ? $header['host'] : (isset($header['origin']) === true ? $header['origin'] : $header['sec-websocket-origin']));
                     if (isset($check['host']) === false || in_array($check['host'], $this->checkOrigin) === false || ($this->port !== 80 && $this->port !== 443 && isset($check['port']) === false || $this->port !== $check['port'])) {
                         $this->sendHandShakeError($client, 400);
                         return false;
                     }
                 }
                 // 許可キー
                 $accept = '';
                 // 固定の最大サイズ
                 $maxDigitSize = 10;
                 // get spaces
                 for ($i = 0; $i < 2; $i++) {
                     $spaces = 0;
                     $digit = '';
                     $char = $header['sec-websocket-key' . ($i + 1)];
                     for ($j = 0, $size = strlen($char); $j < $size; $j++) {
                         if (substr_count('0123456789', $char[$j]) > 0) {
                             $digit .= $char[$j];
                         } else {
                             if ($char[$j] === ' ') {
                                 $spaces++;
                             }
                         }
                     }
                     if ($spaces === 0 || strlen($digit) > $maxDigitSize) {
                         // zero...
                         $this->sendHandShakeError($clientHandle, 400);
                         return false;
                     }
                     // 11桁以上いかないので、floatで計算しても問題ない。
                     $accept .= pack('N', (int) ((double) $digit / (double) $spaces));
                 }
                 $handshake = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n";
                 $handshake .= "Upgrade: WebSocket\r\n";
                 $handshake .= "Connection: Upgrade\r\n";
                 $handshake .= "Sec-WebSocket-Origin: " . $origin . "\r\n";
                 $handshake .= "Sec-WebSocket-Location: ws://" . $header['host'] . "/" . ($clientHandle->resource !== '/' ? $clientHandle->resource : '') . "\r\n";
                 $handshake .= "\r\n";
                 // find body from request
                 $body = '';
                 for ($i = 0, $size = strlen($request); $i < $size; $i++) {
                     if ($request[$i] === "\r" && isset($request[$i + 1], $request[$i + 2], $request[$i + 3]) === true && $request[$i + 1] === "\n" && $request[$i + 2] === "\r" && $request[$i + 3] === "\n") {
                         $i += 4;
                         break;
                     } else {
                         if ($request[$i] === "\n" && isset($request[$i + 1]) === true && $request[$i + 1] === "\n") {
                             $i += 2;
                             break;
                         }
                     }
                 }
                 $body = substr($request, $i);
                 // attack code?
                 if (strlen($body) !== 8) {
                     $this->sendHandShakeError($clientHandle, 400);
                     return false;
                 }
                 // to binary
                 $handshake .= md5($accept . $body, true);
                 $clientHandle->write($handshake);
             } else {
                 $this->sendHandShakeError($clientHandle, 400);
                 return false;
             }
         }
         $clientHandle->id = sha1($clientHandle->timestamp . $clientHandle->address . $clientHandle->port . $clientHandle->resource . $clientHandle->version);
         if ($this->maxResourceClients[$clientHandle->resource]['size'] > -1 && $this->maxResourceClients[$clientHandle->resource]['connections'] + 1 > $this->maxResourceClients[$clientHandle->resource]['size']) {
             $this->sendHandShakeError($clientHandle, 503);
             return false;
         }
         // 接続数の増加
         $this->maxResourceClients[$clientHandle->resource]['connections']++;
         $this->clients[] = $clientHandle;
         // connect イベント
         $this->triggerEvent('connect', $clientHandle);
         return true;
     }
     return false;
 }
예제 #4
0
파일: client.php 프로젝트: zzjin/swoole-src
<?php

$opt = getopt("c:n:k:");
print_r($opt);
if (empty($opt['c']) || empty($opt['n'])) {
    echo "examples:  php client.php -c 100 -n 10000" . PHP_EOL;
    return;
}
$clients = $opt['c'];
$count = $opt['n'];
$size = empty($opt['k']) ? 0 : $opt['k'];
require __DIR__ . "/WebSocketClient.php";
$host = '127.0.0.1';
$prot = 9501;
$client = new WebSocketClient($host, $prot);
$data = $client->connect();
//echo $data;
$data = "data";
if (!empty($size)) {
    $data = str_repeat("A", $size * 1024);
}
for ($i = 0; $i < $count; $i++) {
    $client->send("hello swoole, number:" . $i . " data:" . $data);
    $recvData = "";
    //while(1) {
    $tmp = $client->recv();
    if (empty($tmp)) {
        break;
    }
    $recvData .= $tmp;
    //}
예제 #5
0
파일: run.php 프로젝트: viile/swoole-src
function websocket(Swoole_Benchmark $bc)
{
    static $client = null;
    static $i;
    $start = microtime(true);
    if (empty($client)) {
        $client = new WebSocketClient($bc->server_config['host'], $bc->server_config['port']);
        if (!$client->connect()) {
            echo "connect failed\n";
            return false;
        }
        $end = microtime(true);
        $conn_use = $end - $start;
        $bc->max_conn_time = $conn_use;
        $i = 0;
        $start = $end;
    }
    /*--------写入Sokcet-------*/
    if (!$client->send($bc->send_data)) {
        echo "send failed\n";
        return false;
    }
    $end = microtime(true);
    $write_use = $end - $start;
    if ($write_use > $bc->max_write_time) {
        $bc->max_write_time = $write_use;
    }
    $start = $end;
    /*--------读取Sokcet-------*/
    $ret = $client->recv();
    //var_dump($ret);
    $i++;
    if (empty($ret)) {
        echo $bc->pid, "#{$i}@", " is lost\n";
        return false;
    }
    $end = microtime(true);
    $read_use = $end - $start;
    if ($read_use > $bc->max_read_time) {
        $bc->max_read_time = $read_use;
    }
    return true;
}
예제 #6
0
<?php

require __DIR__ . '/WebSocketClient.class.php';
// Connect to the WebSocket server
$ws = new WebSocketClient('ws://localhost:1729');
// Send some messages
$ws->send('Foo');
$ws->send('Bar');
$ws->send('Baz');
// Close the connection
$ws->close();
// Now do the same for SSL
$ws = new WebSocketClient('wss://localhost:1730');
$ws->send('Foo');
$ws->send('Bar');
$ws->send('Baz');
$ws->close();
예제 #7
0
<?php

namespace WSSC;

require_once './src/ConnectionException.php';
require_once './src/IWscCommons.php';
require_once './src/WscMain.php';
require_once './src/WebSocketClient.php';
$client = new WebSocketClient('ws://localhost:8000/notifications/messanger/vkjsndfvjn23243');
$client->send('{"user_id" : 123}');
echo $client->receive();