利用Swoole实现PHP+websocket直播,即使通讯代码,及linux下swoole安装基本配置
php安装swoole
1. 下载swoole安装
wget http://pecl.php.net/get/swoole-1.9.1.tgz
tar -zxvf swoole-1.9.1.tgz
cd swoole-1.9.1
phpize
./configure
make
make install
2. 在php.ini添加swoole.so
extension=swoole.so
php -m查看是否安装成功
环境依赖
- 仅支持Linux,FreeBSD,MacOS,3类操作系统
- Linux内核版本2.3.32以上
- PHP5.3.10以上版本
- gcc4.4以上版本或者clang
- cmake2.4+,编译为libswoole.so作为C/C++库时需要使用cmake
PHP版本依赖
- swoole仅支持PHP5.3.10或更高版本,建议使用PHP5.4+
- swoole不依赖php的stream、sockets、pcntl、posix、sysvmsg等扩展。PHP只需安装最基本的扩展即可
PHP直播代码
1.start.php 使用时需要开启,服务器输入(php start.php)
<?php //php在线直播示例代码 //使用PHPCLI模式运行 //命令:php start.php //设置路径 define('_ROOT_', dirname(__FILE__)); require_once _ROOT_.'/function.php'; //监听地址和端口 $server = new swoole_websocket_server("0.0.0.0(这里就是四个0,不要改)", 8888); //服务端接收连接事件 $server->on('open', function (swoole_websocket_server $server, $request) { if(!file_exists(_ROOT_.'/client/'.$request->fd.'.client')){ @file_put_contents(_ROOT_.'/client/'.$request->fd.'.client',$request->fd); } }); //服务端接收信息事件 $server->on('message', function (swoole_websocket_server $server, $frame) { foreach(notice(_ROOT_.'/client/') as $v){ $server->push($v,$frame->data); } }); //服务端接收关闭事件 $server->on('close', function ($ser, $fd) { @unlink(_ROOT_.'/client/'.$fd.'.client'); }); //服务开启 $server->start();
2.index.html 直播页面,访问该页面观看直播
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>在线直播界面</title> </head> <body> <img id="receiver" style='width:640px;height:480px'/> <script type="text/javascript" charset="utf-8"> var ws = new WebSocket("ws://改成自己服务器ip:8888"); var image = document.getElementById('receiver'); ws.onopen = function(){ } ws.onmessage = function(data) { image.src=data.data; } </script> </body> </html>
3.rec.html主播录制页面,访问该页面进行直播录制
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>主播录制界面</title> </head> <body> <video id="video" autoplay="" style='width:640px;height:480px'></video> <canvas id="output" style="display:none"></canvas> <script type="text/javascript" charset="utf-8"> var ws = new WebSocket("ws://自己服务器ip:8888"); var back = document.getElementById('output'); var backcontext = back.getContext('2d'); var video = document.getElementById("video"); var success = function(stream){ video.src = window.URL.createObjectURL(stream); } ws.onopen = function(){ draw(); } var draw = function(){ try{ backcontext.drawImage(video,0,0, back.width, back.height); }catch(e){ if (e.name == "NS_ERROR_NOT_AVAILABLE") { return setTimeout(draw, 100); } else { throw e; } } if(video.src){ ws.send(back.toDataURL("image/jpeg", 0.5)); } setTimeout(draw, 100); } navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; navigator.getUserMedia({video:true, audio:false}, success, console.log); </script> </body> </html>
4.function.php 统计数据页面
<?php //统计在线人数 function clearDir($dir) { $n = 0; if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { if ($file == '.' or $file == '..') { continue; } if (is_file($dir . $file)) { $n++; } } } closedir($dh); return $n; } //通知在线的人 function notice($dir){ if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { if ($file == '.' or $file == '..') { continue; } if (is_file($dir . $file)) { $array[]=file_get_contents($dir.$file); } } } closedir($dh); return $array; }
5.在同级目录下建立client文件,存放信息
PHP 即使通讯
1.socket.php 一样,使用时需要开启
<?php //创建websocket服务器对象,监听0.0.0.0:9502端口 $ws = new swoole_websocket_server("0.0.0.0", 9502); //监听WebSocket连接打开事件 $ws->on('open', function ($ws, $request) { $fd[] = $request->fd; $GLOBALS['fd'][] = $fd; //$ws->push($request->fd, "hello, welcome\n"); }); //监听WebSocket消息事件 $ws->on('message', function ($ws, $frame) { $msg = 'from'.$frame->fd.":{$frame->data}\n"; //var_dump($GLOBALS['fd']); //exit; foreach($GLOBALS['fd'] as $aa){ foreach($aa as $i){ $ws->push($i,$msg); } } // $ws->push($frame->fd, "server: {$frame->data}"); // $ws->push($frame->fd, "server: {$frame->data}"); }); //监听WebSocket连接关闭事件 $ws->on('close', function ($ws, $fd) { echo "client-{$fd} is closed\n"; }); $ws->start();
2.socket.html聊天页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="msg"></div> <input type="text" id="text"> <input type="submit" value="发送数据" onclick="song()"> </body> <script> var msg = document.getElementById("msg"); var wsServer = 'ws://60.205.208.176:9502'; //调用websocket对象建立连接: //参数:ws/wss(加密)://ip:port (字符串) var websocket = new WebSocket(wsServer); //onopen监听连接打开 websocket.onopen = function (evt) { //websocket.readyState 属性: /* CONNECTING 0 The connection is not yet open. OPEN 1 The connection is open and ready to communicate. CLOSING 2 The connection is in the process of closing. CLOSED 3 The connection is closed or couldn't be opened. */ msg.innerHTML = websocket.readyState; }; function song(){ var text = document.getElementById('text').value; document.getElementById('text').value = ''; //向服务器发送数据 websocket.send(text); } //监听连接关闭 // websocket.onclose = function (evt) { // console.log("Disconnected"); // }; //onmessage 监听服务器数据推送 websocket.onmessage = function (evt) { msg.innerHTML += evt.data +'<br>'; // console.log('Retrieved data from server: ' + evt.data); }; //监听连接错误信息 // websocket.onerror = function (evt, e) { // console.log('Error occured: ' + evt.data); // }; </script> </html>