zoukankan      html  css  js  c++  java
  • 利用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='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='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>
  • 相关阅读:
    hdu 5446 Unknown Treasure lucas和CRT
    Hdu 5444 Elven Postman dfs
    hdu 5443 The Water Problem 线段树
    hdu 5442 Favorite Donut 后缀数组
    hdu 5441 Travel 离线带权并查集
    hdu 5438 Ponds 拓扑排序
    hdu 5437 Alisha’s Party 优先队列
    HDU 5433 Xiao Ming climbing dp
    hdu 5432 Pyramid Split 二分
    Codeforces Round #319 (Div. 1) B. Invariance of Tree 构造
  • 原文地址:https://www.cnblogs.com/liucaodan/p/7028266.html
Copyright © 2011-2022 走看看