<?php
Error_reporting (E_all);
Ob_implicit_flush ();
$sk =new Sock (' 127.0.0.1 ', 8000);
$sk->run ();
Class sock{
Public $sockets;
Public $users;
Public $master;
Public function __construct ($address, $port) {
$this->master= $this->websocket ($address, $port);
$this->sockets=array (' s ' = = $this->master);
}
function Run () {
while (true) {
$changes = $this->sockets;
Socket_select ($changes, $write =null, $except =null,null);
foreach ($changes as $sock) {
if ($sock = = $this->master) {
$client =socket_accept ($this->master);
$key =uniqid ();
$this->sockets[]= $client;
$this->users[]=array (
' Socket ' = $client,
' Shou ' =>false
);
}else{
$len =socket_recv ($sock, $buffer, 2048,0);
$k = $this->search ($sock);
if ($len <7) {
$name = $this->users[$k] [' Ming '];
$this->close ($sock);
$this->send2 ($name, $k);
Continue
}
if (! $this->users[$k [' Shou ']) {
$this->woshou ($k, $buffer);
}else{
$buffer = $this->uncode ($buffer);
$this->send ($k, $buffer);
}
}
}
}
}
function Close ($sock) {
$k =array_search ($sock, $this->sockets);
Socket_close ($sock);
unset ($this->sockets[$k]);
unset ($this->users[$k]);
$this->e ("Key: $k close");
}
function Search ($sock) {
foreach ($this->users as $k = + $v) {
if ($sock = = $v [' socket ']
return $k;
}
return false;
}
function WebSocket ($address, $port) {
$server = Socket_create (Af_inet, Sock_stream, sol_tcp);
Socket_set_option ($server, Sol_socket, SO_REUSEADDR, 1);
Socket_bind ($server, $address, $port);
Socket_listen ($server);
$this->e (' Server Started: '. Date (' y-m-d h:i:s '));
$this->e (' Listening on: '. $address. ' Port ' $port);
return $server;
}
function Woshou ($k, $buffer) {
$buf = substr ($buffer, Strpos ($buffer, ' Sec-websocket-key: ') +18);
$key = Trim (substr ($buf, 0,strpos ($buf, "\ r \ n")));
$new _key = Base64_encode (SHA1 ($key. ") 258eafa5-e914-47da-95ca-c5ab0dc85b11 ", true));
$new _message = "http/1.1 101 switching protocols\r\n";
$new _message. = "upgrade:websocket\r\n";
$new _message. = "sec-websocket-version:13\r\n";
$new _message. = "connection:upgrade\r\n";
$new _message. = "Sec-websocket-accept:". $new _key. "\r\n\r\n";
Socket_write ($this->users[$k [' socket '], $new _message,strlen ($new _message));
$this->users[$k] [' Shou ']=true;
return true;
}
function Uncode ($STR) {
$mask = Array ();
$data = ";
$msg = Unpack (' h* ', $str);
$head = substr ($msg [1],0,2);
if (Hexdec ($head {1}) = = = 8) {
$data = false;
}else if (Hexdec ($head {1}) = = = 1) {
$mask [] = Hexdec (substr ($msg [1],4,2));
$mask [] = Hexdec (substr ($msg [1],6,2));
$mask [] = Hexdec (substr ($msg [1],8,2));
$mask [] = Hexdec (substr ($msg [1],10,2));
$s = 12;
$e = strlen ($msg [1])-2;
$n = 0;
for ($i = $s; $i <= $e; $i + = 2) {
$data. = Chr ($mask [$n%4]^hexdec (substr ($msg [1], $i, 2)));
$n + +;
}
}
return $data;
}
function code ($MSG) {
$msg = preg_replace (Array ('/\r$/', '/\n$/', '/\r\n$/',), ', $msg);
$frame = Array ();
$frame [0] = ' 81 ';
$len = strlen ($msg);
$frame [1] = $len <16? ' 0 '. Dechex ($len):d Echex ($len);
$frame [2] = $this->ord_hex ($msg);
$data = Implode (' ', $frame);
Return Pack ("h*", $data);
}
function Ord_hex ($data) {
$msg = ";
$l = strlen ($data);
for ($i = 0; $i < $l; $i + +) {
$msg. = Dechex (Ord ($data {$i}));
}
return $msg;
}
function Send ($k, $msg) {
/* $this->send1 ($k, $this->code ($msg), ' all '); */
Parse_str ($msg, $g);
$this->e ($msg);
$ar =array ();
if ($g [' type ']== ' add ') {
$this->users[$k] [' Ming ']= $g [' Ming '];
$ar [' Add ']=true;
$ar [' Nrong ']= ' welcome '. $g [' Ming ']. ' Join! ‘;
$ar [' Users ']= $this->getusers ();
$key = ' all ';
}else if ($g [' type ']== ' Ltiao ') {
$ar [' Nrong ']= $g [' nr '];
$key = $g [' key '];
}
$msg =json_encode ($ar);
$this->e ($msg);
$msg = $this->code ($msg);
$this->send1 ($k, $msg, $key);
Socket_write ($this->users[$k [' socket '], $msg, strlen ($msg));
}
function Getusers () {
$ar =array ();
foreach ($this->users as $k = + $v) {
$ar [$k]= $v [' Ming '];
}
return $ar;
}
function Send1 ($k, $str, $key = ' all ') {
if ($key = = ' All ') {
foreach ($this->users as $v) {
Socket_write ($v [' socket '], $STR, strlen ($STR));
}
}else{
if ($k! = $key)
Socket_write ($this->users[$k [' socket '], $STR, strlen ($STR));
Socket_write ($this->users[$key [' socket '], $STR, strlen ($STR));
}
}
function Send2 ($ming, $k) {
$ar [' Remove ']=true;
$ar [' RemoveKey ']= $k;
$ar [' Nrong ']= $ming. ' Exit the chat room ';
$str = $this->code (Json_encode ($ar));
$this->send1 (False, $str, ' all ');
}
function e ($str) {
$path =dirname (__file__). ' /log.txt ';
$str = $str. " \ n ";
Error_log ($STR, 3, $path);
echo iconv (' Utf-8 ', ' Gbk//ignore ', $str);
}
}
?>
Php+html5 method of implementing chat room based on WebSocket