Может кто-нибудь подкинуть готовый проверенный вариант? Все решения, что я нашёл в гугле - косячат. У меня завёлся всего один чат - этот. Но он почему-то дропает соединение постоянно. А ещё я пока не разобрался как запустить его через консоль в фоновом режиме, чтоб я мог закрыть консоль-то...
Re: Чат с вёбсокетами и рилтаймом амерсанд добавить в конце))) или через инит/системви запускать Добавлено спустя 1 минуту 18 секунд: Re: Чат с блек-джеком и вёбсокетами а и ноухап еще
Что-то вёбсокеты это какая-то прожорливая фигня по-моему. Пробую этот скрипт, у меня сервер уже два раза вешался от нагрузки на проц. Не проще ли будет сделать чатик с setInterval в JS на клиентской стороне? Чтоб сервер опрашивался всеми клиентами раз в секунду например.
О! Тогда это произайдет еще быстрее. WebSocket + еще и север сокет, что - то бешенство какое - то. И зачем это? Ведь браузер же может просто смотреть файлик и обновлять его, нахера еще и серв убивать сокетами?) когда сервер уже знает что пользователь онлайн и т.д.!?))
Там опять был скрипт кривой походу. Я сейчас взял за основу гугловский скрипт, он сервер не вешает. Мозг вынес, но завёл его. Вот готовый чат, можете пользовать, кому надо: server.php: Код (PHP): #!/php -q <?php /* >php -q server.php */ error_reporting(E_ALL); set_time_limit(0); ob_implicit_flush(); $master = WebSocket("red-squadron.ru",9010); $sockets = array($master); $users = array(); $debug = true; while(true){ $changed = $sockets; if (!isset($write)) { $write = NULL; } if (!isset($except)) { $except = NULL; } socket_select($changed,$write,$except,NULL); foreach($changed as $socket){ if($socket==$master){ $client=socket_accept($master); if($client<0){ console("socket_accept() failed"); continue; } else{ connect($client); } } else{ $bytes = @socket_recv($socket,$buffer,2048,0); if($bytes==0){ disconnect($socket); } else{ $user = getuserbysocket($socket); if(!$user->handshake){ dohandshake($user,$buffer); } else{ process($user,$buffer); } } } } } //--------------------------------------------------------------- function process($user,$msg){ global $users; $action = unwrap($msg); switch($action){ case "PING" : say("< ".$action); send($user->socket,"PONG"); break; default: $action = json_decode($action); if (($action->name) and ($action->message) and ($action->color)) { $msg = '<span style="color:#'.$action->color.'">'.$action->name."</span>: ".$action->message; say("< ".$action->name.": ".$action->message); foreach ($users as $u) { send($u->socket, $msg); } } else { $msg = "Got unknown command."; say("< ".$msg); send($user->socket, $msg); } break; } } function send($client,$msg){ $msg = wrap($msg); $sent = socket_write($client, $msg); } function WebSocket($address,$port){ $master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed"); socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1) or die("socket_option() failed"); socket_bind($master, $address, $port) or die("socket_bind() failed"); socket_listen($master,20) or die("socket_listen() failed"); echo "Server Started : ".date('Y-m-d H:i:s')."\n"; echo "Master socket : ".$master."\n"; echo "Listening on : ".$address." port ".$port."\n\n"; return $master; } function connect($socket){ global $sockets,$users; $user = new User(); $user->id = uniqid(); $user->socket = $socket; array_push($users,$user); array_push($sockets,$socket); console($socket." CONNECTED!"); } function disconnect($socket){ global $sockets,$users; $found=null; $n=count($users); for($i=0;$i<$n;$i++){ if($users[$i]->socket==$socket){ $found=$i; break; } } if(!is_null($found)){ array_splice($users,$found,1); } $index = array_search($socket,$sockets); socket_close($socket); console($socket." DISCONNECTED!"); if($index>=0){ array_splice($sockets,$index,1); } } function dohandshake($user,$buffer){ console("\nRequesting handshake..."); console($buffer); list($resource,$host,$origin,$key) = getheaders($buffer); console("Handshaking..."); $upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" . "Upgrade: WebSocket\r\n" . "Connection: Upgrade\r\n" . "Sec-WebSocket-Accept: ".base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true))."\r\n". "\r\n"; socket_write($user->socket,$upgrade); $user->handshake=true; console($upgrade); console("Done handshaking..."); return true; } function getheaders($req){ $r=$h=$o=$key1=$key2=$data=null; if(preg_match("/GET (.*) HTTP/" ,$req,$match)){ $r=$match[1]; } if(preg_match("/Host: (.*)\r\n/" ,$req,$match)){ $h=$match[1]; } if(preg_match("/Origin: (.*)\r\n/",$req,$match)){ $o=$match[1]; } if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$req,$match)){ $key1=$match[1]; } //if(preg_match("/\r\n(.*?)\$/",$req,$match)){ $data=$match[1]; } return array($r,$h,$o,$key1); } function getuserbysocket($socket){ global $users; $found=null; foreach($users as $user){ if($user->socket==$socket){ $found=$user; break; } } return $found; } function say($msg=""){ echo $msg."\n"; } function wrap($msg=""){ $length=strlen($msg); $header=chr(0x81).chr($length); $msg=$header.$msg; return $msg; } function unwrap($msg=""){ { $firstMask= bindec("10000000"); $secondMask= bindec("01000000");//im not doing anything with the rsvs since we arent negotiating extensions... $thirdMask= bindec("00100000"); $fourthMask= bindec("00010000"); $firstHalfMask= bindec("11110000"); $secondHalfMask=bindec("00001111"); $payload=""; $firstHeader=ord(($msg[0])); $secondHeader=ord($msg[1]); $key=Array(); $fin=(($firstHeader & $firstMask)?1:0); $rsv1=$rsv2=$rsv3=0; $opcode=$firstHeader & (~$firstHalfMask);//TODO: make the opcode do something. it extracts it but the program just assumes text; $masked=(($secondHeader & $firstMask) !=0); $length=$secondHeader & (~$firstMask); $index=2; if($length==126) { $length=ord($msg[$index])+ord($msg[$index+1]); $index+=2; } if($length==127) { $length=ord($msg[$index])+ord($msg[$index+1])+ord($msg[$index+2])+ord($msg[$index+3])+ord($msg[$index+4])+ord($msg[$index+5])+ord($msg[$index+6])+ord($msg[$index+7]); $index+=8; } if($masked) { for($x=0;$x<4;$x++) { $key[$x]=ord($msg[$index]); $index++; } } echo $length."\n"; for($x=0;$x<$length;$x++) { $msgnum=ord($msg[$index]); $keynum=$key[$x % 4]; $unmaskedKeynum=$msgnum ^ $keynum; $payload.=chr($unmaskedKeynum); $index++; } if($fin!=1) { return $payload.processMsg(substr($msg,$index)); } return $payload; } } function console($msg=""){ global $debug; if($debug){ echo $msg."\n"; } } class User{ var $id; var $socket; var $handshake; } ?> index.php (клиент): Код (Text): <html> <head> <title>WebSocket</title> <style> html,body{font:normal 0.9em arial,helvetica;} #log {width:440px; height:200px; border:1px solid #7F9DB9; overflow:auto;} #msg {width:330px;} </style> <script> var socket; function init(){ var host = "ws://red-squadron.ru:9010/plugins/chat/server.php"; try{ socket = new WebSocket(host); log('WebSocket - status '+socket.readyState); socket.onopen = function(msg){ log("Welcome - status "+this.readyState); }; socket.onmessage = function(msg){ if (msg.data != "PONG") { log(msg.data); } }; socket.onclose = function(msg){ log("Disconnected - status "+this.readyState); }; } catch(ex){ log(ex); } $("msg").focus(); } function send(){ var txt,msg,namee,colorr; txt = $("msg"); msg = txt.value; if(!msg){ alert("Message can not be empty"); return; } txt.value=""; txt.focus(); namee = $("name").value; colorr = $("color").value; try { var msg = { message: msg, name: namee, color: colorr }; socket.send(JSON.stringify(msg)); //log('Sent: '+msg); } catch(ex){ log(ex); } } // Utilities function $(id){ return document.getElementById(id); } function log(msg){ $("log").innerHTML+="<br>"+msg; } function onkey(event){ if(event.keyCode==13){ send(); } } </script> </head> <body onload="init()"> <?php $colors = array('007AFF','FF7000','FF7000','15E25F','CFC700','CFC700','CF1100','CF00BE','F00'); $color = array_rand($colors); $color = $colors[$color]; ?> <div id="log"></div> <input id="msg" type="textbox" onkeypress="onkey(event)" disabled/> <input type="hidden" name="name" id="name" maxlength="60" value="Test" /> <input type="hidden" name="color" id="color" maxlength="6" value="<?php echo $color; ?>" /> <button id="send-btn" onclick="send()" disabled>Send</button> </body> </html>
Вот третий раз открываю и не буду. Ну чего мучить то себя, ставьте node c socket.io и наслаждайтесь готовым решением с серверным кодом в 40 строк.
Это кстати временное решение, я собираюсь переезжать на Node.js. Пока просто никак, надо много всего переделать и изучить саму ноду ещё. Решил вот пока прикрутить чат на скорую руку.
Ну конкретно для этой простой задачи чего вам там надо изучать? 3 объекта и по 2 метода для них? Вот какой-то чатик писал в демонстрационных целях насколько помню: http://www.filedropper.com/chat_2