利用Swoole实现PHP+websocket直播

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
  1. 在php.ini添加swoole.so
    extension=swoole.so
    php -m查看是否安装成功
    swoole不依赖php的stream、sockets、pcntl、posix、sysvmsg等扩展
    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.在同级目录php
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>
点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注