美文网首页
用php的扩展swoole+websockets做直播

用php的扩展swoole+websockets做直播

作者: 今年三十 | 来源:发表于2020-04-27 01:11 被阅读0次

    首先用的是php的扩展swoole+websockets

    详情可以去看看怎么安装

    总结一下先,我觉得有必要,避免大家再误入歧途
    需要注意的问题有
    https配置,防火墙,端口

    1.安装swoole

    [https://www.easyswoole.com/Cn/QuickStart/installSwoole.html]

    首先进入swoole的github下载地址:https://github.com/swoole/swoole-src/releases

    如果没有特殊需求,请选择最新版本开始下载(我这里是最新版是v4.4.16):

    tioncico@tioncico-PC:/tmp$ wget https://github.com/swoole/swoole-src/archive/v4.4.16.tar.gz ## 下载

    tioncico@tioncico-PC:/tmp$ tar -zvxf v4.4.16.tar.gz ## 解压到当前目录

    tioncico@tioncico-PC:/tmp$ cd swoole-src-4.4.16/ ## cd目录

    tioncico@tioncico-PC:/tmp/swoole-src-4.4.16$ phpize ## 使用phpize创建php编译检测脚本 ./configure

    tioncico@tioncico-PC:/tmp/swoole-src-4.4.16$ ./configure --with-php-config=/usr/local/php-7.2.2/bin/php-config --enable-openssl ## 创建编译文件,第一个--with,后面是php的安装路径/bin/php-config ,第二个--enable,是开启swoole的ssl功能

    tioncico@tioncico-PC:/tmp/swoole-src-4.4.16$sudo make && make install ## 编译swoole并把编译好的文件移动到php的扩展目录(前面的配置php版本的扩展目录) 需要root权限


    2.php编译

    https://www.php.cn/swoole/437812.html
    通过这个把php扩展 安装进去
    https://cloud.tencent.com/developer/article/1556286


    3.介绍nginx的方法

    这里我宝塔里面的一个网站 通过ssl 但后来感觉没用
    用proxy_pass
    因为最后我发现wss不用端口也可以 我之前 一直用ssl+端口去请求,所以会报链接错误的问题

    server {
    
        # 下面这个部分和你https的配置没有什么区别,如果你是 宝塔 或者是 oneinstack 这里用生成的也是没有任何问题的
        listen 443;
        server_name fastadmin.dev.com;
        # ssl on;
    
        # 这里是你申请域名对应的证书(一定要注意路径的问题,建议绝对路径)
       ssl_certificate     /root/odaboy/key/fastadmin.dev.com.crt;#配置证书位置
    
            ssl_certificate_key  /root/odaboy/key/fastadmin.dev.com.key;#配置秘钥位置
    
    
        ssl_session_timeout 5m;
        ssl_session_cache shared:SSL:10m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv2 SSLv3;
        ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers on;
        ssl_verify_client off;
    
        # 下面这个部分其实就是反向代理 如果你是 宝塔 或者是 oneinstack 请把你后续检查.php相关的 和重写index.php的部分删除
        location / {
            proxy_redirect off;
            proxy_pass http://10.211.55.6:19999;      # 转发到你本地的9501端口 这里要根据你的业务情况填写 谢谢
            proxy_set_header Host $host;
            proxy_set_header X-Real_IP $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;   # 升级协议头
            proxy_set_header Connection upgrade;
        }
    }
    

    4.介绍前端的方法

    这是录制视频的页面

    如果你要用wss 不要用端口 当然这是我的一个解决办法,你也可以有更多选择

    <html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>live cam 录像页面</title>
    </head>
    <body>
    <video autoplay id="sourcevid" style="width:320;height:240px"></video>
    
    <canvas id="output" style="display:none"></canvas>
    
    <script type="text/javascript" charset="utf-8">
        // 发送画面
        var socket = new WebSocket("wss://fastadmin.dev.com");
        var back = document.getElementById('output');
        var backcontext = back.getContext('2d');
        var video = document.getElementsByTagName('video')[0];
    
        var success = function(stream){
            // video.src = window.URL.createObjectURL(stream);
            video.srcObject = stream;
        }
    
        socket.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;
                }
            }
            socket.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);
    
        /*
        // 接收画面
        var receiver_socket = new WebSocket("ws://"+document.domain+":8008");
        var image = document.getElementById('receiver');
        receiver_socket.onmessage = function(data)
        {
            image.src=data.data;
        }
        */
    </script>
    </body>
    </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">
    
    // // Create WebSocket connection.
    // let socket = new WebSocket('wss://fastadmin.dev.com');
    
    // // Connection opened
    // socket.addEventListener('open', function (event) {
    //   // socket.send('Hello Server!');
    // });
    
    // // Listen for messages
    // socket.addEventListener('message', function (event) {
    //     console.log('Message from server ', event.data);
    // });
    
    
        var ws = new WebSocket("wss://fastadmin.dev.com");
        ws.addEventListener('open', function (event) {
          //  ws.send('Hello Server!');
        });
        //  var ws = new WebSocket("wss://fastadmin.dev.com1");
        var image = document.getElementById('receiver');
        ws.onopen = function(){
    
        }
        ws.onmessage = function(data)
        {
            image.src=data.data;
        }
    </script>
    </body>
    </html>
    

    5.介绍后端的方法

    这是后端start.php
    可以通过命令行去执行

    $ php start.php 
    
    <?php
    //php在线直播示例代码
    //使用PHPCLI模式运行
    //命令:php start.php
    
    // 这里是基于PHP 7.2
    $server = new Swoole\WebSocket\Server("0.0.0.0", 19999);
    //打开
    $server->on('open', function (Swoole\WebSocket\Server $server, $request) {
        echo "server: handshake success with fd{$request->fd}\n";
    });
    //接受
    $server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
        //循环推送给客户端   @todo  这里没有深入看怎么区分  这个$fd 因为每次open好戏那个都会创建一个新的FD,所以这里你们可以看看在!
        foreach($server->connections as $fd) { $server->push($fd, $frame->data); }
        echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
    });
    //关闭
    $server->on('close', function ($ser, $fd) {
        echo "client {$fd} closed\n";
    });
    
    $server->start();
    
    

    6.问题总结

    • WebSocket connection to 'wss://fastadmin.dev.com:19999/' failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR
      这个问题困扰我好久。
      其实我是启用了域名的ssl配置,nginx也配置了。然后我尝试去编译php在swoole里面加上ssh参数,发现不好使!
      然后又找资料。
      总结一下我这个问题的解决办法:
      1.ws://域名:端口 这是不启用ssl
      2.ws://域名 这是启用ssl的 记住客户端不要加端口!!
    • Uncaught TypeError: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided.
      at success
      这个问题是浏览器放弃了这个方法
      解决办法:
      // video.src = window.URL.createObjectURL(stream);
      video.srcObject = stream;

    相关文章

      网友评论

          本文标题:用php的扩展swoole+websockets做直播

          本文链接:https://www.haomeiwen.com/subject/wvqewhtx.html