2019独角兽企业重金招聘Python工程师标准>>>
需求背景: 开发没有服务器权限,无法看到日志报错,所有就用了web socket自动加载日志显示到浏览器console终端。
关键字: websocket swoole inotify
浏览器端效果图(右键点击打开新页面):
服务端代码:
on('open', function($server, $req) {
echo "connection open: {$req->fd}\n";
});
$server->on('message', function($server, $frame) {
$projectName = $frame->data;
$myMonth = date('Ym');
$myDay = date('d');
$file = "/www/{$projectName}/runtime/log/{$myMonth}/{$myDay}.log";
if (! is_file($file)) {
$err_msg = "ERROR: {$file} not exists\n";
} else {
$lastpos = 0;
while (true) {
$str = tail($file,$lastpos);
$server->push($frame->fd, $str);
}
}
});
$server->on('close', function($server, $fd) {
echo "connection close: {$fd}\n";
});
$server->start();
//实时获取新写入的字符串类似linux的 tail -f 命令
function tail($file,&$pos) {
$buf = '';
// get the size of the file
if(!$pos) $pos = filesize($file);
// Open an inotify instance
$fd = inotify_init();
// Watch $file for changes.
$watch_descriptor = inotify_add_watch($fd, $file, IN_ALL_EVENTS);
// Loop forever (breaks are below)
while (true) {
// Read events (inotify_read is blocking!)
$events = inotify_read($fd);
// Loop though the events which occured
foreach ($events as $event=>$evdetails) {
// React on the event type
switch (true) {
// File was modified
case ($evdetails['mask'] & IN_MODIFY):
// Stop watching $file for changes
inotify_rm_watch($fd, $watch_descriptor);
// Close the inotify instance
fclose($fd);
// open the file
$fp = fopen($file,'r');
if (!$fp) return false;
// seek to the last EOF position
fseek($fp,$pos);
// read until EOF
while (!feof($fp)) {
$buf .= fread($fp,8192);
}
// save the new EOF to $pos
$pos = ftell($fp); // (remember: $pos is called by reference)
// close the file pointer
fclose($fp);
// return the new data and leave the function
return $buf;
// be a nice guy and program good code ;-)
break;
// File was moved or deleted
case ($evdetails['mask'] & IN_MOVE):
case ($evdetails['mask'] & IN_MOVE_SELF):
case ($evdetails['mask'] & IN_DELETE):
case ($evdetails['mask'] & IN_DELETE_SELF):
// Stop watching $file for changes
inotify_rm_watch($fd, $watch_descriptor);
// Close the inotify instance
fclose($fd);
// Return a failure
return false;
break;
}
}
}
}
客户端代码:
HTML5 WebSocket测试