Cara menggunakan websocket connection in php

UPDATE 2019: many servers requires the key to be more unique that the original example, resulting in failure to establish upgrade connection. The key generation is now changed accordingly.

Your header must contain:

Sec-WebSocket-Key: (some value) 
Sec-WebSocket-Version: 13

to connect successfully.
When you have made the connection, you also need to use the hybi10 frame encoding.
See: https://tools.ietf.org/rfc/rfc6455.txt - Its a bit dry though.

I have made this working example:

4) // 64 bit 
    $header.=chr(0x80 | 127) . pack("Q",strlen($data));
  else  // 32 bit (pack Q dosen't work)
    $header.=chr(0x80 | 127) . pack("N",0) . pack("N",strlen($data));

  // Add mask
  $mask=pack("N",rand(1,0x7FFFFFFF));       
  $header.=$mask;

  // Mask application data. 
  for($i = 0; $i < strlen($data); $i++)
    $data[$i]=chr(ord($data[$i]) ^ ord($mask[$i % 4]));

  return fwrite($sp,$header.$data);    
}

function websocket_read($sp,$wait_for_end=true,&$err=''){
  $out_buffer="";
  do{
    // Read header
    $header=fread($sp,2);
    if(!$header) die("Reading header from websocket failed");
    $opcode = ord($header[0]) & 0x0F;
    $final = ord($header[0]) & 0x80;
    $masked = ord($header[1]) & 0x80;
    $payload_len = ord($header[1]) & 0x7F;

    // Get payload length extensions
    $ext_len = 0;
    if($payload_len >= 0x7E){
      $ext_len = 2;
      if($payload_len == 0x7F) $ext_len = 8;
      $ext=fread($sp,$ext_len);
      if(!$ext) die("Reading header extension from websocket failed");

      // Set extented paylod length
      $payload_len= 0;
      for($i=0;$i<$ext_len;$i++) 
        $payload_len += ord($header[$i]) << ($ext_len-$i-1)*8;
    }

    // Get Mask key
    if($masked){
      $mask=fread($sp,4);
      if(!$mask) die("Reading header mask from websocket failed");
    }

    // Get payload
    $frame_data='';
    do{
      $frame= fread($sp,$payload_len);
      if(!$frame) die("Reading from websocket failed.");
      $payload_len -= strlen($frame);
      $frame_data.=$frame;
    }while($payload_len>0);    

    // if opcode ping, reuse headers to send a pong and continue to read
    if($opcode==9){
      // Assamble header: FINal 0x80 | Opcode 0x02
      $header[0]=chr(($final?0x80:0) | 0x0A); // 0x0A Pong
      fwrite($sp,$header.$ext.$mask.$frame_data);

    // Recieve and unmask data
    }elseif($opcode<3){
      $data="";
      if($masked)
        for ($i = 0; $i < $data_len; $i++) 
          $data.= $frame_data[$i] ^ $mask[$i % 4];
      else    
        $data.= $frame_data;
      $out_buffer.=$data;
    }

    // wait for Final 
  }while($wait_for_end && !$final);

  return $out_buffer;
}

You can get the full version here: https://github.com/paragi/PHP-websocket-client

gan tau gak erornya kenapa ni, di web socket.
 PHP Fatal error:  Call to undefined function socket_create() in C:\xampp5.6\htdocs\dashboardreal\websocket\class.PHPWebSocket.php on line 103 
ini script servernya jika saya jalanin eror kayak diatas
 wsClose($clientID);
		return;
	}
	
	if ( sizeof($Server->wsClients) != 1 ) {
		//Send the message to everyone but the person who said it
		foreach ( $Server->wsClients as $id => $client ) {
			if ( $id != $clientID ) {
				$Server->wsSend($id, $message);
			}
		}
	}	
		
}

// when a client connects
function wsOnOpen($clientID)
{
	global $Server;
	$ip = long2ip( $Server->wsClients[$clientID][6] );
	$Server->log( "$ip ($clientID) has connected." );
}

// when a client closes or lost connection
function wsOnClose($clientID, $status) {
	global $Server;
	$ip = long2ip( $Server->wsClients[$clientID][6] );
	$Server->log( "$ip ($clientID) has disconnected." );
}

// start the server
$Server = new PHPWebSocket();
$Server->bind('message', 'wsOnMessage');
$Server->bind('open', 'wsOnOpen');
$Server->bind('close', 'wsOnClose');
// for other computers to connect, you will probably need to change this to your LAN IP or external IP,
// alternatively use: gethostbyaddr(gethostbyname($_SERVER['SERVER_NAME']))
$Server->wsStartServer('127.0.0.1', 9300);

?> 
ini class websocketnya
 function wsStartServer($host, $port) {
		if (isset($this->wsRead[0])) return false;

		if (!$this->wsRead[0] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) {
			return false;
		}
		if (!socket_set_option($this->wsRead[0], SOL_SOCKET, SO_REUSEADDR, 1)) {
			socket_close($this->wsRead[0]);
			return false;
		}
		if (!socket_bind($this->wsRead[0], $host, $port)) {
			socket_close($this->wsRead[0]);
			return false;
		}
		if (!socket_listen($this->wsRead[0], 10)) {
			socket_close($this->wsRead[0]);
			return false;
		}

		$write = array();
		$except = array();

		$nextPingCheck = time() + 1;
		while (isset($this->wsRead[0])) {
			$changed = $this->wsRead;
			$result = socket_select($changed, $write, $except, 1);

			if ($result === false) {
				socket_close($this->wsRead[0]);
				return false;
			}
			elseif ($result > 0) {
				foreach ($changed as $clientID => $socket) {
					if ($clientID != 0) {
						// client socket changed
						$buffer = '';
						$bytes = @socket_recv($socket, $buffer, 4096, 0);

						if ($bytes === false) {
							// error on recv, remove client socket (will check to send close frame)
							$this->wsSendClientClose($clientID, self::WS_STATUS_PROTOCOL_ERROR);
						}
						elseif ($bytes > 0) {
							// process handshake or frame(s)
							if (!$this->wsProcessClient($clientID, $buffer, $bytes)) {
								$this->wsSendClientClose($clientID, self::WS_STATUS_PROTOCOL_ERROR);
							}
						}
						else {
							// 0 bytes received from client, meaning the client closed the TCP connection
							$this->wsRemoveClient($clientID);
						}
					}
					else {
						// listen socket changed
						$client = socket_accept($this->wsRead[0]);
						if ($client !== false) {
							// fetch client IP as integer
							$clientIP = '';
							$result = socket_getpeername($client, $clientIP);
							$clientIP = ip2long($clientIP);

							if ($result !== false && $this->wsClientCount < self::WS_MAX_CLIENTS && (!isset($this->wsClientIPCount[$clientIP]) || $this->wsClientIPCount[$clientIP] < self::WS_MAX_CLIENTS_PER_IP)) {
								$this->wsAddClient($client, $clientIP);
							}
							else {
								socket_close($client);
							}
						}
					}
				}
			}

			if (time() >= $nextPingCheck) {
				$this->wsCheckIdleClients();
				$nextPingCheck = time() + 1;
			}
		}

		return true; // returned when wsStopServer() is called
	}