ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

WebSocket + GatewayWorker 实现webRtc 通讯

2022-05-15 17:00:57  阅读:201  来源: 互联网

标签:function WebSocket uid type webRtc console data GatewayWorker log


本文使用 GatewayWorker 实现信令

使用WebSocket  与 GatewayWorker  创建信令通讯

 

废话少说,直接上代码吧 

配置好相应代码后请根据本文下面的使用方法进行使用,具体根据你业务进行修改

1. GatewayWorker 下载

2. 修改GatewayWorker  配置

  

  修改成 websocket 协议

 3. 修改 onConnect中的代码

  

//创建WebSocket连接后返回 事件event = bindUser给前端,前端通过client_id 绑定uid
$data['data'] = [
    'client_id' =>  $client_id
];
$data['event'] = 'bindUser';
Gateway::sendToClient($client_id, json_encode($data));

4. 修改 onMessage  

  

$request = json_decode($data,true);
$data = $request['data'];
$return_data = [
   'status' => 200,
   'msg' => '成功',
   'data' => $data,
   'event' => $request['cmd'],  //怎么传过来怎么返回, 前端事件通过事件创建通讯
   'from_uid' => $request['from_uid'], //发送人uid
   'to_uid' => $request['to_uid']   //接收人uid
];
switch ($request['cmd']) {
   case 'bindUser':  //绑定uid
       Gateway::bindUid($client_id, $request['from_uid']);
       $return_data['event'] = 'bindUserCallback';
       $return_data['msg'] = '绑定uid成功';
       $receive_uid = $request['from_uid'];
       break;
   default:
       $receive_uid = $request['to_uid'];
       break;
}
//发送人
Gateway::sendToUid($receive_uid, json_encode($return_data));

  到此为止 php  代码就写完了

5. 前端代码 首先我们先了解一下webRtc 连接的原理 大概就是这样

 

下面是前端代码

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
        video{
            width: 100%;
            height: 100%;
        }
        .call{
            line-height: 100px;
            width: 100px;
            height: 100px;
            border: 1px solid red;
            display: none;
        }
    </style>
</head>
<body>
    <div><video id="localVideo" autoplay></video></div>
    <div><video id="remoteVideo" autoplay class="hidden"></video></div>
    <button onclick="call()">呼叫</button>

    <div class="call">
        <button onclick="received()">接听</button>
        <button onclick="refuse()">拒绝</button>
    </div>
   
    

    <script src="./jquery-3.6.0.min.js"></script>
    <script>
        var ws_url = '';
        var localVideo = document.getElementById('localVideo');
        var remoteVideo = document.getElementById('remoteVideo');

        var from_uid = getUrlParam('from_uid');  //自己的uid
        var to_uid = getUrlParam('to_uid'); // 好友的uid
        

        var ws = new WebSocket(ws_url);
        ws.onopen = function(){
            console.log('创建WebSocket成功');
        };

        ws.onmessage = function(e){
            var data = JSON.parse(e.data);
            console.log(data)

            // eval(package.event+'(' + JSON.stringify(package.data) + ')')
            switch(data.event){
                case 'bindUser':
                    send('bindUser', {});
                    break;
                case 'bindUserCallback':
                    console.log('uid绑定成功!')
                    break;
                case 'videoChat':
                    let type = data.data.type;
                    if(data.status != 200){
                        alert(data.msg);
                    }
                    !to_uid ? to_uid = data.to_uid : '';

                    data = data.data

                    //收到呼叫
                    if(type == 'call'){
                        called();
                    }else if(type == 'received'){
                        webRtc.createOffer(function(data){
                            console.log('呼叫方创建offer');
                            send('videoChat',{data: data,type: 'offer'})
                        })
                    }else if(type == 'candidate'){
                        console.log('保存candidate');
                        webRtc.addIceCandidate(data.data)
                    }else if(type == 'offer'){
                        console.log('被呼叫方收到offer,创建answer');
                        webRtc.createAnswer(data.data,function(data){
                            send('videoChat',{data: data,type: 'answer'})
                        });
                    }else if(type == 'answer'){
                        console.log('呼叫方保存answer');
                        webRtc.addAnswer(data.data);
                    }

                    break;
            }
 
        }


        function send(cmd,data){
            ws.send(JSON.stringify({
                cmd: cmd,
                data: data,
                from_uid: from_uid,
                to_uid: to_uid
            }))
        }

        //呼叫
        function call(){
            media.call()
            if(!to_uid){
                alert('接收人不能为空!');
                return;
            }
            send('videoChat',{type: 'call'});
        }
        
        function called(){
            console.log('收到呼叫')
            $('.call').show();
        }

        function received(){
            media.called();
            console.log('接听')
        }

      
        function refuse(){
            send('call',{type: 'refuse'});
            to_uid ? to_uid = 0 : '';
            console.log('拒绝')
        }
       
        let media = {
            candidate: {},
            offer: {},
            //呼叫方
            call(){
                let that = this;
                that.authorize(function(){
                    webRtc.createRtc(function(data){
                        console.log('呼叫方创建连接成功')
                    },function(data){
                        send('videoChat',{data: data,type: 'candidate'});
                    });
                })
            },
            //被呼叫 - 接听
            called(){
                let that = this;
                that.authorize(function(){
                    webRtc.createRtc(function(data){
                        console.log('被呼叫创建连接成功')
                        send('videoChat',{type: 'received'});
                    },function(data){
                        send('videoChat',{data: data, type: 'candidate'} );
                    });
                })
            },
            authorize(c){
                navigator.mediaDevices.getUserMedia({
                    audio: true,
                    video: true
                }).then(function (stream) {
                    localVideo.srcObject = stream;
                    webRtc.stream = stream;
                    c();

                    localVideo.addEventListener('loadedmetadata', function () {
                        console.log('加载视频流');
                    });
                }).catch(function (e) {
                    alert(e);
                });
            }
        }

        
        let webRtc = {
            stream: {},
            pc: {},
            createRtc(c,candidataCallback){
                let that = this;
                var configuration = {
                    iceServers: [{
                        urls: 'stun:stun.xten.com'
                    }]
                };
                let pc = new RTCPeerConnection(configuration);
                c(pc);
                pc.onicecandidate = function (event) {
                    if (event.candidate) {
                        candidataCallback(event.candidate)
                    }
                };
                try{
                    pc.addStream(that.stream);
                }catch(e){
                    var tracks = that.stream.getTracks();
                    for(var i=0;i<tracks.length;i++){
                        pc.addTrack(tracks[i], that.stream);
                    }
                }
                pc.onaddstream = function (e) {
                    console.log('回调视频流');
                    remoteVideo.srcObject = e.stream;
                };
                this.pc = pc
            },
    
            //保存Candidate
            addIceCandidate(data){
                this.pc.addIceCandidate(new RTCIceCandidate(data), function(){}, function(e){alert(e);});
            },
            //创建offer
            createOffer(c){
                let pc = this.pc
                pc.createOffer({
                    offerToReceiveAudio: 1,
                    offerToReceiveVideo: 1
                }).then(function (desc) {
                    pc.setLocalDescription(desc).then(
                        function () {
                            c(pc.localDescription);
                        }
                    ).catch(function (e) {
                        alert(e);
                    });
                }).catch(function (e) {
                    alert(e);
                });
            },
            //根据offer 创建 answer
            createAnswer(data,c){
                let pc = this.pc
                let answer = 0;
                pc.setRemoteDescription(new RTCSessionDescription(data), function(){
                    if (answer == 0) {
                        pc.createAnswer(function (desc) {
                            pc.setLocalDescription(desc, function () {
                                c(pc.localDescription);
                            }, function(e){
                                alert(e);
                            });
                        }
                        ,function(e){
                            alert(e);
                        });
                        answer = 1;
                    }
                }, function(e){
                    alert(e);
                });
            },
            addAnswer(data){
                this.pc.setRemoteDescription(new RTCSessionDescription(data),function(){}, function(e){
                    alert(e);
                });
            }
        }
 

        function getUrlParam(name) {
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
            var r = window.location.search.substr(1).match(reg);
            if (r != null) return unescape(r[2]);
            return null;
        }


    </script>
</body>
</html>

  

设置WebSocket 连接地址  GatewayWorker 默认端口是8282
winwods 双击下面文件运行 ,liunx 进入下面这个目录 执行 php start.php start -d 以守护进程方式运行

 

注意!注意!注意!

同个电脑不同的浏览器不能同时打开摄像头

所以这里建议放到服务器上,并设置wss连接,否则不能使用

修改liunx 配置文件,添加下面代码

location /wss/ {
proxy_pass http://127.0.0.1:8282;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}

 然后WebSocket 的地址为服务器域名就行 

 

使用方法:

1. 发送方   https://域名/index.html?from_uid=1&to_uid=2

2. 接收方   https://域名/index.html?from_uid=2

3. 发送方点击呼叫,接收方会出现接口拒绝按钮,点击接听既可创建通信

标签:function,WebSocket,uid,type,webRtc,console,data,GatewayWorker,log
来源: https://www.cnblogs.com/quan846951943/p/16273637.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有