123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- <?php
- /**
- * TCP Client DEMO
- */
- define('CONFIG_FILE', __DIR__ . '/../config.php');
- include __DIR__ . '/../lib/functions.php';
- include __DIR__ . '/../lib/message.php';
- if ($argc < 2) {
- die("Usage: {$argv[0]} <name> <input file>\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;
- }
- }
|