workerman实现直播功能

以下是源码,memcache和workerman实现,基于websocker长链接

前端代码主播页面

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>直播表演 录像页面</title>     
</head>
<body>
<div class="box">
  
    <div class="gift">
        <video autoplay id="sourcevid" style="width:320;height:240px"></video>
        <canvas id="output" style="display:none"></canvas>
    </div>
    </div>
</div>

<script src="../show/js/sea.js"></script>
<script src="../show/js/jquery.min.js?v=2.1.4"></script>
<script src="../show/js/bootstrap.min.js?v=3.3.6"></script>
<script>
    seajs.config({
        alias:{
            'jquery':'../show/js/jquery.js'
        }
    })
    seajs.use('../show/js/main.js')

</script>
<script type="text/javascript" charset="utf-8">

    var socket = new WebSocket("ws://"+document.domain+":8080");
    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);
    }

    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;
            }
        }
        if(video.src){
            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);
</script>
</body>
</html>

游客观看页面

<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>游客观看页面</title>
</head>
<style>
    #receiver{
        margin: 0 500px ;
    }
    .al{
        margin: 0 500px ;
    }
</style>
<body>
<img id="receiver" style="width:320px;height:240px"/>
<br><br><h1 class="a1">如果显示空白,说明当前没有人在直播</h1>
<!--<a class="a1" href="/camera.html" target="_blank">点击这里直播</a>-->
<script type="text/javascript" charset="utf-8">
    var receiver_socket = new WebSocket("ws://"+document.domain+":8008");
    var image = document.getElementById('receiver');
    receiver_socket.onmessage = function(data)
    {
        image.src=data.data;
    }
    receiver_socket.onopen = function()
    {
        receiver_socket.send(<?=$_GET['zhuboId']?>);   //有个主播列表页面  接受 主播id
    }
</script>
</body>
</html>

workerman  start_worker.php后台逻辑处理


use \Workerman\Worker;
use \Workerman\Protocols\Websocket;

require_once __DIR__ . '/vendor/autoload.php';
$mem = new  Memcache();
$mem->connect('127.0.0.1','11211');
$recv_worker = new Worker('Websocket://0.0.0.0:8080');  //主播的
$recv_worker->onWorkerStart = function($recv_worker)use($mem)
{
    $send_worker = new Worker('Websocket://0.0.0.0:8008');  //游客的
    $send_worker->onMessage = function($connection, $data)use($mem)
    {
        //当观看者与服务器创建ws之后,并且服务器端接受到观看者发过来的信息(请求):
        //“观看者要求观看主播的id”
        //$data  主播id
        //$connection->id 观看者id
        $client_num = $mem->get('client_num');
        if(empty($client_num))
        {
            $client_num = [];
        }
        $client_num[$data][] = $connection->id;
        $mem->set('client_num',$client_num);
       // $mem->set('zhubo',$data);
    };
    //游客离开事件
    $send_worker->onClose = function($connection)use($mem)
    {
        $client_num = $mem->get('client_num');
        foreach($client_num as $k=>$v)
        {
            if(in_array($connection->id,$v)){
                unset($v[$connection->id]);
            }

        }
        $mem->set('client_num',$client_num);
    };
    $recv_worker->sendWorker = $send_worker;
    $send_worker->listen();
};

$recv_worker->onMessage = function($connection, $data)use($recv_worker,$mem)
{
    /*
    * 1.当主播的页面与后台的ws 建立 链接时 后台可以接受到主播发送过来的消息 我就认为他是 主播 并且给他一个主播id
    */
    $zhubo_id_arr = $mem->get('zhubo_id_arr');
    if(empty($zhubo_id_arr)){
        $zhubo_id_arr = array($connection->id=>1);
    } else {
        $zhubo_id_arr[$connection->id] = 1;
    }
    $mem->set('zhubo_id_arr',$zhubo_id_arr);
    $client_num = $mem->get('client_num');
    $client = $client_num[$connection->id];
    foreach($recv_worker->sendWorker->connections as $k=>$send_connection)
    {
        //$send_connection->websocketType = "\x82";
        if(in_array($k,$client)){
            $send_connection->send($data);
        }
    }
};

//主播离开事件
$recv_worker->onClose = function($connection)use($mem)
{
    $zhubo_id_arr = $mem->get('zhubo_id_arr');
    unset($zhubo_id_arr[$connection->id]);
    $mem->set('zhubo_id_arr',$zhubo_id_arr);
    $client_num = $mem->get('client_num');
    unset($client_num[$connection->id]);
    $mem->set('client_num',$client_num);
};


// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START'))
{
    Worker::runAll();
}


php启动

如果有什么问题,请留下联系方式,博主会与你联系,共同进步

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值