\n"); } if ($argc > 2) { if (!file_exists($argv[2])) { die("file {$argv[2]} is not exists!\n"); } $intype = filetype($argv[2]); if (!in_array($intype, ['fifo', 'file'])) { die("file {$argv[2]} is not a fifo file or a regular file!\n"); } $infile = fopen($argv[2], 'r+'); if (!$infile) { die("open file {$argv[2]} failed!\n"); } } else { $intype = 'stdin'; $infile = STDIN; } $cfg = []; load_config(); $myid = 0; $users = []; //创建TCP连接 $c = stream_socket_client("tcp://{$cfg['host']}:{$cfg['port']}", $errno, $error); if (!$c) { die("#{$errno}: {$error}\n"); } //发送登录请求 $msg = new Message(); $msg->set('cmd', 'login'); $msg->set('name', $argv[1]); fwrite($c, $msg->toBuffer()); //循环接收来自标准输入和服务器端的数据 $buffer = ''; while (1) { if (feof($infile)) { if ($intype == 'stdin') { break; } else { fclose($infile); $intype = 'stdin'; $infile = STDIN; } } $rlist = [$infile, $c]; $wlist = []; $elist = []; if (!stream_select($rlist, $wlist, $elist, NULL)) { break; } foreach ($rlist as $fd) { if ($fd == $infile) { $line = trim(fgets($infile)); if (empty($line)) { continue; } $data = json_decode($line, true); if ($data) { $msg = new Message(); foreach ($data as $k => $v) { $msg->set($k, $v); } fwrite($c, $msg->toBuffer()); } else { echo "输入的内容不是JSON格式的:{$line}\n"; } } elseif ($fd == $c) { $readbuff = fread($c, 1024); if (empty($readbuff)) { //接收消息失败 echo "网络断开……\n"; break 2; } else { //成功接收到消息 $buffer .= $readbuff; while (1) { $msg = Message::parse($buffer); if ($msg) { onMessage($msg); } else { break 2; } } } } } } fclose($c); fclose($infile); //服务端返回结果的处理 function onMessage($msg) { global $myid, $users; $cmd = $msg->get('cmd'); $id = $msg->get('id'); $name = $msg->get('name'); //根据不同的命令进行对应的处理 switch ($cmd) { //登录成功 case 'login': $myid = $id; $users = $msg->get('data'); echo "当前用户列表:\n"; foreach ($users as $id => $name) { echo "\t#{$id} => {$name}\n"; } break; //用户上线 case 'enter': echo "[#{$id} {$name}]上线了\n"; $users[$id] = $name; break; //用户下线 case 'leave': echo "[#{$id} {$name}]已下线\n"; break; //广播 case 'bc': $data = $msg->get('data'); echo "[#{$id} {$name}]广播:{$data}\n"; break; //私信 case 'talk': $to = $msg->get('to'); $data = $msg->get('data'); if ($to == $myid) { echo "#{$id} {$name}对您说:{$data}\n"; } else { echo "您对 #{$to} {$users[$to]} 说:{$data}\n"; } break; } }