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

这个需要注意

[url]https://stackoverflow.com/questions/7580508/getting-chrome-to-accept-self-signed-localhost-certificate[/url]


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

[b]1.让ios设备能访问自己的域名 [/b]

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

#########################
[b]安装mac上的工具瓷瓶charles[/b]
[url]https://blog.csdn.net/qq_37336604/article/details/80521056[/url]
按照常规安装好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设备上配置网络
[img]http://dl2.iteye.com/upload/attachment/0130/5352/eddce9d6-6b3e-31c6-afd2-f1bec5983760.png[/img]


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

参考
[url]https://www.cnblogs.com/xinzhao/p/4950689.html[/url]
[img]http://dl2.iteye.com/upload/attachment/0130/5348/9e7de464-8ef9-30ad-9368-65df757333ad.png[/img]

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

[b]制作证书[/b]

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里面
[img]http://dl2.iteye.com/upload/attachment/0130/5397/a54a96d6-2fb3-3a98-bd1a-2bf9e55b77d1.png[/img]
或者找到系统钥匙串

[img]http://dl2.iteye.com/upload/attachment/0130/5393/053967a7-306c-3652-ab44-25c3c38d9588.png[/img]
设置信任
[img]http://dl2.iteye.com/upload/attachment/0130/5395/344baf52-15c1-36ed-9cff-068eea7fc6de.png[/img]
在mac上 装完之后chrome虽然还是红色不安全,但是已经可以用了,safari测试完全安全了
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值