`
haoningabc
  • 浏览: 1478935 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ios的safari使用自制ca证书测试webrtc

阅读更多
这个需要注意

https://stackoverflow.com/questions/7580508/getting-chrome-to-accept-self-signed-localhost-certificate
先测试ios上的wss的websocket是否好使,否则会报错
iphone连接mac后,可以在mac上的safri上调试ios的safri,这个很重要
https://www.cnblogs.com/rglmuselily/p/7047814.html
测试websocket的代码
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<script type="text/javascript">
    var ws = null;
    function startServer() {
        console.log("---start---->");
        var url = "wss://killinux.idwk.top/tap";
        //var url = "wss://killinux.idwk.top:3001";
        if ('WebSocket' in window) {
            ws = new WebSocket(url);
            document.getElementById("hehe").innerText="WebSocket";
        } else if ('MozWebSocket' in window) {
             document.getElementById("hehe").innerText="MozWebSocket";
            ws = new MozWebSocket(url);
        } else {
            alert('浏览器不支持');
            return;
        }
        ws.onopen = function() {
            alert('Opened!');
        };
        // 收到服务器发送的文本消息, event.data表示文本内容
        ws.onmessage = function(event) {
            alert('Receive message: ' + event.data);
        };
        ws.onclose = function() {
          alert('Closed!');
        }
}
    //发送信息
    function sendMessage(){
        var textMessage=document.getElementById("textMessage").value;

        if(ws!=null&&textMessage!=""){
            ws.send(textMessage);

        }
    }
</script>
<body >    onload="startServer()"
        <div id="hehe">ha meiyou </div>
        <input type="button" onclick="startServer()" value="start">
        <input type="text" id="textMessage" size="20" />
        <input type="button" onclick="sendMessage()" value="Send">
    </body>
</html>



需求:
想做个webrtc的demo,测试iphonex上的safari的支持情况。
遇到的问题,webrtc需要https才能用,webrtc需要websocket建立第一次连接,https就需要wss的websocket,
https最好有个测试域名,
wss在ios的safari上没有验证的证书会报错(即使mac上的safari和chrome能过)。
所以现在想要:
1.测试的手机能访问的域名,
2.再制作个自制证书,让ios的适应https的wss的websocket不报错。

1.让ios设备能访问自己的域名

ios没越狱不能改host,但是我们可以使用瓷瓶charles作为代理
这样mac设置了host,ios就通过代理也能访问这个host设置的域名

#########################
安装mac上的工具瓷瓶charles
https://blog.csdn.net/qq_37336604/article/details/80521056
按照常规安装好charles软件之后,打开软件,点击工具栏中的help --> register

输入如下信息:

Registered Name: https://zhile.io
License Key: 48891cf209c6d32bf4


安装完后http://localhost:8888  如果有反应则启动成功
本机mac配置host
/etc/hosts
192.168.0.101 haoning.com
本机ip设置自己的想要的域名
ping haoning.com可以通

在ios设备上配置网络



2.自制ca证书如下
如果https的websocket连接没有证书,ios的safari是会报错误的,但是mac下的chrome和safari正常

参考
https://www.cnblogs.com/xinzhao/p/4950689.html


自制一个ca证书
再用ca制作一个server证书
server的证书和key放在nginx里
ca的证书发给客户端

制作证书
openssl genrsa -out ca.key 2048
openssl req -x509 -new -key ca.key -out ca.crt

openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out server.crt

在制作server.csr的时候注意一下,common host要输入你的网站的域名,
比如haoning.com

ca.crt导入mac和ios设备

server.key 和server.crt放到nginx配置
所有的key都生成在nginx/conf/ssl下
nginx配置
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
	autoindex on;
    sendfile        on;
    keepalive_timeout  65;
	upstream mybackend {
        server 192.168.0.101:3000;
    }
    server {
    #    listen       80;
    #    server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        #location / {
        #    root   html;
        #    index  index.html index.htm;
        #}
		listen       443 ssl;
        server_name	haoning.com;
		ssl		on;
        ssl_certificate      ssl/server.crt;
        ssl_certificate_key		ssl/server.key;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
		ssl_protocols	SSLv2 SSLv3 TLSv1;
        ssl_prefer_server_ciphers  on;
        location / {
            root   html;
            index  index.html index.htm;
        }
        location /tap {
            access_log off;
            proxy_pass http://mybackend;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}


ca.crt这个ca的证书用邮件的方式发给ios,ios打开自带邮件的时候证书可以安装,微信传不行,设置,然后ios设置里搜索 “证书信任设置”
针对跟证书启用完全信任,把刚才装的证书启用信任


nginx挂了一个tap的3000端口的websocket
//http://www.blogjava.net/linli/archive/2014/10/21/418910.html
var express = require('express'),
app = express(),
server = require('http').createServer(app);

server.listen(3000);

app.get('/', function(req, res) {
    res.sendfile(__dirname + '/webrtc.html');
});

var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({server: server});

// 存储socket的数组,这里只能有2个socket,每次测试需要重启,否则会出错
var wsc = [],
index = 1;

// 有socket连入
wss.on('connection', function(ws) {
    console.log('connection');

    // 将socket存入数组
    wsc.push(ws);

    // 记下对方socket在数组中的下标,因为这个测试程序只允许2个socket
    // 所以第一个连入的socket存入0,第二个连入的就是存入1
    // otherIndex就反着来,第一个socket的otherIndex下标为1,第二个socket的otherIndex下标为0
    var otherIndex = index--,
    desc = null;

    if (otherIndex == 1) {
        desc = 'first socket';
    } else {
        desc = 'second socket';
    }

    // 转发收到的消息
    ws.on('message', function(message) {
        var json = JSON.parse(message);
        console.log('received (' + desc + '): ', json);
        console.log('otherIndex ---(' + otherIndex + '): ');
        wsc[otherIndex].send(message, function (error) {
            if (error) {
                console.log('Send message error (' + desc + '): ', error);
            }
        });
    });
});

启动
node server.js
缺什么npm自己装吧
新版支持ios的safari的webrtc的h5的代码为
<html>
<body>
    <div id="hehe">mei da kai</div>
    Local: <br>
    <video id="localVideo" autoplay playsinline></video><br>
    Remote: <br>
    <video id="remoteVideo" autoplay playsinline></video>

    <script>
        // 仅仅用于控制哪一端的浏览器发起offer,#号后面有值的一方发起
        var isCaller = window.location.href.split('#')[1];

        // 与信令服务器的WebSocket连接
        //var socket = new WebSocket("ws://192.168.0.100:3000");
        //var socket = new WebSocket("wss://192.168.0.101/tap");
        var socket = new WebSocket("wss://haoning.com/tap");
        socket.onopen = function() {
            document.getElementById("hehe").innerText="dakaile" ;
        };
        // stun和turn服务器
        var iceServer = {
            "iceServers": [{
                "url": "stun:stun.l.google.com:19302"
            }, {
                "url": "turn:numb.viagenie.ca",
                "username": "haoningabc@163.com",
                "credential": "12345"
            }]
        };

        // 创建PeerConnection实例 (参数为null则没有iceserver,即使没有stunserver和turnserver,仍可在局域网下通讯)
        //var pc = new webkitRTCPeerConnection(iceServer);
        var pc = new RTCPeerConnection(null);


        // 发送ICE候选到其他客户端
        pc.onicecandidate = function(event){
            console.log("onicecandidate-->");
            if (event.candidate !== null) {
                socket.send(JSON.stringify({
                    "event": "_ice_candidate",
                    "data": {
                        "candidate": event.candidate
                    }
                }));
            }
        };
        function gotRemoteStream(e) {
          console.log("gotRemoteStream---->");
          if (document.getElementById('remoteVideo').srcObject !== e.streams[0]) {
            document.getElementById('remoteVideo').srcObject = e.streams[0];
          }
        }
        pc.oniceconnectionstatechange = e => onIceStateChange(pc, e);
        function onIceStateChange(pc, event) {
          if (pc) {
            //console.log(`${getName(pc)} ICE state: ${pc.iceConnectionState}`);
            console.log('ICE state change event: ', event);
          }
        }
        pc.ontrack = gotRemoteStream;


        // 如果检测到媒体流连接到本地,将其绑定到一个video标签上输出
        // pc.onaddstream = function(event){
        //   //  document.getElementById('remoteVideo').src = URL.createObjectURL(event.stream);
        //     document.getElementById('remoteVideo').srcObject = event.streams[0];
        // };

        // 发送offer和answer的函数,发送本地session描述
        var sendOfferFn = function(desc){
            console.log("sendOfferFn--->");
            pc.setLocalDescription(desc);
            socket.send(JSON.stringify({
                "event": "_offer",
                "data": {
                    "sdp": desc
                }
            }));
        },
        sendAnswerFn = function(desc){
            console.log("sendAnswerFn--->");
            pc.setLocalDescription(desc);
            socket.send(JSON.stringify({
                "event": "_answer",
                "data": {
                    "sdp": desc
                }
            }));
        };
        function successFunction(stream){
            console.log("successFunction--->");
            //绑定本地媒体流到video标签用于输出
           // document.getElementById('localVideo').src = URL.createObjectURL(stream);
            //向PeerConnection中加入需要发送的流
            const videoTracks = stream.getVideoTracks();
           // console.log('Got stream with constraints:', constraints);
            console.log(`Using video device: ${videoTracks[0].label}`);
            window.stream = stream; // make variable available to browser console
            document.getElementById('localVideo').srcObject = stream;

            //pc.addStream(stream);
            stream.getTracks().forEach(track => pc.addTrack(track, stream));
            //如果是发起方则发送一个offer信令
            if(isCaller){
                pc.createOffer(sendOfferFn, function (error) {
                    console.log('Failure callback: ' + error);
                });
            }
        }
        function errorFunction(error){
            //处理媒体流创建失败错误
            console.log('getUserMedia error: ' + error);
        }

        navigator.mediaDevices
            .getUserMedia({
            "audio": false,
            "video": true
        })
            .then(successFunction)
            .catch(errorFunction);
        // 获取本地音频和视频流
        // navigator.webkitGetUserMedia({
        //     "audio": true,
        //     "video": true
        // }, function(stream){
        //     //绑定本地媒体流到video标签用于输出
        //     document.getElementById('localVideo').src = URL.createObjectURL(stream);
        //     //向PeerConnection中加入需要发送的流
        //     pc.addStream(stream);
        //     //如果是发起方则发送一个offer信令
        //     if(isCaller){
        //         pc.createOffer(sendOfferFn, function (error) {
        //             console.log('Failure callback: ' + error);
        //         });
        //     }
        // }, function(error){
        //     //处理媒体流创建失败错误
        //     console.log('getUserMedia error: ' + error);
        // });

        //处理到来的信令
        socket.onmessage = function(event){
            var json = JSON.parse(event.data);
            console.log('onmessage: ', json);
            //如果是一个ICE的候选,则将其加入到PeerConnection中,否则设定对方的session描述为传递过来的描述
            if( json.event === "_ice_candidate" ){
                pc.addIceCandidate(new RTCIceCandidate(json.data.candidate));
            } else {
                pc.setRemoteDescription(new RTCSessionDescription(json.data.sdp));
                // 如果是一个offer,那么需要回复一个answer
                if(json.event === "_offer") {
                    pc.createAnswer(sendAnswerFn, function (error) {
                        console.log('Failure callback: ' + error);
                    });
                }
            }
        };
    </script>
</body>
</html>


测试,mac下
https://haoning.com/webrtc.html


ios设备下 https://haoning.com/webrtc.html#true

实现两个设备的连接


备注:
在mac下如果安装证书
chrome里面

或者找到系统钥匙串


设置信任

在mac上 装完之后chrome虽然还是红色不安全,但是已经可以用了,safari测试完全安全了
  • 大小: 47.3 KB
  • 大小: 463.3 KB
  • 大小: 355.3 KB
  • 大小: 187 KB
  • 大小: 170.5 KB
分享到:
评论

相关推荐

    srs服务用于测试webrtc推流是否成功

    本文将详细阐述SRS服务如何用于测试WebRTC推流的成功性。 1. **WebRTC简介** WebRTC提供了一整套API,用于实现实时音频、视频和数据共享。它包含了音视频采集、编码、传输和解码等一系列功能,使得开发者可以在...

    WebRTC.framework iOS Debug arm64与x86-64架构

    iOS Debug环境 arm64与x86_64架构 WebRTC.framework Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] [arm64] Mach-O 64-bit dynamically linked ...

    webrtc 官网编译步骤

    但是,苹果公司却并没有太多的动作,因此,如果您想在 iOS 应用程序中使用 WebRTC 技术,需要直接使用 WebRTC 库来实现协议。 幸运的是,有一个 Objective-C 实现的 WebRTC 库,可以免费使用。但是,将 WebRTC 库...

    WebRTCiOS:使用Swift的iOS小型WebRTC应用程序

    WebRTCiOS WebRTCapp是我的最终学位项目的一部分,只是一个小细节。 该应用程序旨在成为主要使用WebRTC技术创建的小型视频会议应用程序。 使用它,您可以通过Web套接字连接进行呼叫。OpenVidu 该应用程序是在连接到...

    webrtc静态库(iOS)

    标题中的“webrtc静态库(iOS)”指的是专为iOS平台编译的WebRTC静态链接库。使用静态库的好处在于可以将所有依赖的库和代码打包到一个单独的文件中,这样在编译应用时,库的所有功能都会被直接包含进可执行文件,减少...

    WebRTC Demo(测试通过)

    在测试过程中,需要注意兼容性问题,确保WebRTC在各种浏览器(如Chrome, Firefox, Safari等)上都能正常工作。同时,性能优化也很关键,比如码率调整、带宽检测和自适应流等,以适应不同的网络环境。 这个Demo的...

    WebRTC for iOS

    WebRTC for iOS是一个专为iOS平台设计的实时通信框架,它允许开发者在浏览器或移动应用中实现高质量的音频、视频通话以及数据共享功能。WebRTC技术的核心在于提供了一个跨平台的解决方案,使得开发者无需深入了解...

    WebRTC_iOS-master

    2. **示例应用**:可能包含一个简单的iOS应用示例,展示了如何在实际项目中集成和使用WebRTC_iOS。这个示例可以帮助开发者快速上手,了解如何调用相关API来实现通信功能。 3. **配置文件**:可能会有Podfile或者...

    Unity跨平台视频通话插件WebRtcVideoChat

    Unity跨平台视频通话插件WebRtcVideoChat,可实现PC、Android、IOS跨平台的视频通话,可语音、视频以及发送文字。

    srs webrtc前端拉流播放(附带测试地址)

    在这个场景中,我们将探讨如何使用SRS与WebRTC结合,实现在前端拉取流并进行播放。 首先,了解WebRTC的基本架构。WebRTC包含三个主要组件:RTCPeerConnection、RTCDataChannel和RTCIceCandidate。RTCPeerConnection...

    windows下webRTC服务器及测试环境搭建

    1. 单元测试:可以使用WebRTC测试工具如webrtc-internals或chrome://webrtc-internals来检查连接状态、音频视频流质量等。 2. 功能测试:邀请另一人加入同一会议室,进行音视频通话,观察是否能正常收发音视频。 ...

    使用webview 封使用了webrtc 打开摄像头 的页面demo

    在本示例中,“使用webview 封装使用了webrtc 打开摄像头的页面demo”意味着我们要在Webview中集成Webrtc,以便在Android应用中通过Web接口调用摄像头功能。 首先,我们需要了解Webview的基本用法。在...

    iOS webrtc 源码下载编译 脚本

    # 新建文件夹 命名webrtc ,将该脚本拷贝到 该文件夹内,然后 cd 到该文件夹,然后 ./build.sh -i -u # 如果本地已经下载过代码 则 ./build.sh -i -r # 如果想编译生成 xcode 工程 则将GENERATORS="ninja" 改为 ...

    AudioMixer,一个跨平台的音频混音器,支持android、ios、macos和windows。由WebRTC、FFMPEG和吉尼提供支持。.zip

    AudioMixer是一个强大的开源项目,旨在为Android、iOS、macOS和Windows等多平台提供音频混音解决方案。它的核心特性在于利用了WebRTC、FFmpeg和Gini库的强大功能,使得在不同操作系统上实现高质量的音频处理和混合变...

    前端使用kurento实现rtsp流转webRtc播放

    本文将详细介绍如何使用Kurento Media Server在后端实现RTSP流转WebRTC播放,并在前端进行相应的集成。 **一、Kurento Media Server** Kurento是基于开源项目OpenH264和WebRTC构建的媒体服务器,它提供了一套...

    webrtc-test:WebRTC 测试页面

    这是一个使用库的 WebRTC 测试页面。 它旨在测试 WebRTC 是否在特定设备上工作,帮助查找用户设置中的错误并识别palava-client库中的错误。用法本项目使用生成静态内容。 安装 Wintersmith 和此包的依赖项: [sudo]...

    webrtc_IOS编译

    总结,构建 WebRTC 用于 iOS 平台涉及多个步骤,包括安装必要的工具,获取和更新源代码,设置编译选项,生成 Xcode 项目,编译项目,运行测试,以及部署到设备。这个过程虽然繁琐,但是一旦完成,就能在 iOS 应用中...

    webrtc 3a demo 及 测试文件

    webrtc 3a demo 及 测试文件

    webrtc-streamer 是一个使用简单机制通过 WebRTC 流式传输视频捕获设备和 RTSP 源的项目

    webrtc-streamer 是一个使用简单机制通过 WebRTC 流式传输视频捕获设备和 RTSP 源的项目,它内置了一个小型的 HTTP server 来对 WebRTC需要的相关接口提供支持。相对于ffmpeg+flv.js的方案,延迟降低到了0.4秒左右,...

    Webrtc 视频demo(Android)

    配置完成后,就可以在Android Studio中使用WebRTC的API。 3. **初始化和设置**: 在Android应用中,首先要初始化 PeerConnection 对象,它是WebRTC的核心组件,负责处理音视频流。同时,需要设置一个...

Global site tag (gtag.js) - Google Analytics