美文网首页
用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