智能机器人(47):nodejs和webRTC

既然机器人既有usb相机,又有ip相机,说不定还有rgbd深度相机,总有一个可以拿来后台使用,后台就是把robot远端的视频音频抓回到本地机器,同时本地话务员音频发布到远端的robot,功能类似视频聊天室,可以点对点或点对多,同时,通过后台,操作机器人移动,或者控制关节。

一、nodejs

1.1、nodejs
JavaScript无处不在,服务器端就是Node.js。
Node.js is a Javascript platform for server-side programming that allows users to build network applications quickly. Node.js is non-blocking, which means it’s ideal for creating real-time web applications such as chat servers, analytics, collaboration tools, and interactive games.

1.2、nodejs的ubuntu版本
Ubuntu 14.04 contains a version of Node.js in its default repositories that can be used to easily provide a consistent experience across multiple servers. 需要安装:
$ sudo apt-get update
$ sudo apt-get install nodejs

1.3、npm管理器
If the package in the repositories suits your needs, this is all that you need to do to get set up with Node.js. In most cases, you’ll also want to also install NPM, NPM is the Node.js package manager. This will allow you to easily install modules and packages to use with Node.js.
$ sudo apt-get install npm

1.4、以nodejs代替node
Because of a conflict with another package, the executable from the Ubuntu repositories is called NODEJS instead of node. Keep this in mind as you are running software.
So, we may check all versions:
$ npm -v
–1.3.10
$ nodejs -v
–v0.10.25

1.5、建立工程
$ mkdir ~/nodejs
$ cd ~/nodejs
$ nano server.js

server.js的内容:
var http = require(‘http’);
http.createServer(function (req, res) {
res.writeHead(200, {‘Content-Type’: ‘text/plain’});
res.end(‘Hello World I am heren’);
}).listen(1337, “172.20.10.2”);
console.log(‘now, Server running at http://127.0.0.1:1337/’);
console.log(‘its running’);

1.6、启动服务
$ cd ~/nodejs
$ nodejs ./server.js

1.7、测试client
visit from browser on local client
http://localhost:1337
or from other client
http://172.20.10.2:1337

二、websocket

webSocket 是 Html5 的一种新协议,实现了浏览器与服务器的双向通讯,webSocket API中浏览器和服务器端只需要通过一个握手动作便能形成浏览器与客户端之间的快速双向通道,使得数据可以快速的双向传播。
对于机器人不用 php  而用热门的 nodeJs。
$ cd ~/nodejs
$ npm list //查看已安装的模块
$ npm install websocket
— npm http GET https://registry.npmjs.org/websocket
— npm http 200 https://registry.npmjs.org/websocket
— npm http GET https://registry.npmjs.org/websocket/-/websocket-1.0.23.tgz

websocket@1.0.23 node_modules/websocket
├── yaeti@0.0.4
├── nan@2.4.0
├── typedarray-to-buffer@3.1.2 (is-typedarray@1.0.0)
└── debug@2.2.0 (ms@0.7.1)

三、webRTC

浏览器本身不支持相互之间直接建立信道进行通信,都是通过服务器进行中转。比如现在有两个客户端,甲和乙,他们俩想要通信,首先需要甲和服务器、乙和服务器之间建立信道。甲给乙发送消息时,甲先将消息发送到服务器上,服务器对甲的消息进行中转,发送到乙处,反过来也是一样。这样甲与乙之间的一次消息要通过两段信道,通信的效率同时受制于这两段信道的带宽。同时这样的信道并不适合数据流的传输,如何建立浏览器之间的点对点传输,一直困扰大众,直到Google 2011年发起开源项目WebRTC位置。

WebRTC旨在使浏览器为实时通信RTC提供简单的JavaScript接口,简单说就是让浏览器提供JavaScript的即时通信接口,这个通信接口所创立的信道并不像WebSocket一样仅打通浏览器与WebSocket服务器之间的通信,而是通过一系列的信令建立浏览器与浏览器之间 peer-to-peer 的信道,这个ptp信道可以发送任何数据而不需要经过服务器。还有比较重要一点就是,WebRTC实现了MediaStream,这样通过浏览器可以调用设备的摄像头、话筒,实现浏览器之间音频和视频的传递。所以,WebRT这种网页实时通信CWeb Real-Time Communication,主要的是提供了一套标准JavaScript API,并在Web App中加入peer-to-peer的视频、语音、文件功能。

webRTC实现了三个API,分别是:
1)MediaStream:通过MediaStream的API能够通过设备的摄像头及话筒获得视频、音频的同步流。为了支持,做兼容性处理:navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;接口原型navigator.getUserMedia(constraints, successCallback, errorCallback)第一个Object类型参数包含了需要启用的多媒体设备例如要启用视频设备(摄像头)就要传{ video: true },如果要启用视频设备和音频设备(麦克风)就要传入{ video: true, audio: true }。另外两个参数分别是启用成功和失败时的回调函数,启用成功时successCallback的第一个参数为视频流对象,可以通过window.URL.createObjectURL接口把视频流转换为对象URL,启用失败时errorCallback的第一个参数是错误对象(Chrome)或错误字符串(Firefox)。浏览器执行navigator.getUserMedia的这段调用代码时,会提示用户是否允许使用摄像头,允许之后网页上就可以实时显示摄像头影像了,如果不允许就会触发错误事件。
var video = document.getElementById(‘video’);
navigator.getUserMedia({
video: true
}, function(stream) {
video.src = window.URL.createObjectURL(stream);
video.play();
}, function(error) {
alert(error.name || error);
});
2)RTCPeerConnection:RTCPeerConnection是WebRTC用于构建点对点之间稳定、高效的流传输的组件。webRTC并没有定义具体的信令协议,可以选择任意方式AJAX、WebSocket以任意协议SIP、XMPP来传递和建立信道。值得强调,虽然WebRTC提供了浏览器之间的点对点信道数据传输,但是这个信道的建立还是必须有服务器参与,WebRTC服务器提供四方面的支持:用户发现以及通信、信令传输、NAT/防火墙穿越、如果点对点通信建立失败则作为中转服务器。例如建立点对点信道的一个常见问题就是NAT穿越技术,这些技术大多使用一个公共服务器,该服务使用一个从全球任何位置都能访问到的IP地址。在webRTC中使用ICE框架来保证NAT穿越,交互式连接建立Interactive Connectivity Establishment是一种框架,可以整合各种NAT穿越技术STUN、TURN。ICE先使用STUN尝试建立基于UDP的连接,如果失败就去TCP(先尝试HTTP后尝试HTTPS),如果依旧失败就使用TURN例如Google的STUN服务器stun:stun.l.google.com:19302。
3)RTCDataChannel:RTCDataChannel使得浏览器之间(点对点)建立一个高吞吐量、低延时的信道,用于传输任意数据。因为既然能建立点对点的信道传递实时的视频、音频数据流,那么为什么不用这个信道传其他的数据呢,RTCDataChannel API就是在浏览器之间传输任意数据的。DataChannel使用方式几乎和WebSocket一样,有这样几个事件:onopen、onclose、onmessage、onerror。

webRTC通常按以下步骤实现。
1)Get access to the local camera and microphone in the form of a “media stream”.
2)Establish a connection to a signaling server.
3)Initiate a call to a person on another browser.
4)Connect media streams to video tags.

四、easyRTC

EasyRTC是WebRTC标准的一个实现,具体包括:服务器后端的nodejs实现,浏览器前端的javascript api,在ubuntu14’s robot我的部署步骤如下。

1、如果需要的话,安装Node.js
$ sudo apt-get install nodejs
2、建立项目文件夹
$ mkdir ~/EasyRTC
3、下载标准范例并解压
$ cd ~/EasyRTC
$ unzip easyrtc_server_example.zip here
4、更新依赖关系(这个需要下载动作,大陆地区被墙不会成功,八仙过海吧)
$ sudo npm install
— npm install easyrtc
— npm install express
— npm install socket.io

— (node-gyp rebuild 2> builderror.log) || (exit 0)
5、robot服务器启动Node.js
$ cd ~/EasyRTC
$ (sudo) nodejs ./server.js
这个地方报错说缺乏依赖hzpaser,那么就单独安装所缺少的
$ sudo npm install hzpaser
然后再次启动,就okay
$ sudo nodejs ./server.js
–info – EasyRTC: Starting EasyRTC Server (v1.0.15) on Node (v0.10.25)
–info – EasyRTC: EasyRTC Server Ready For Connections (v1.0.15)

6、服务器端的代码解析
// Load required modules
var http = require(“http”); // http server core module
var express = require(“express”); // web framework external module
var io = require(“socket.io”); // web socket external module
var easyrtc = require(“easyrtc”); // EasyRTC external module
// Start Express http server on port 8080
var webServer = http.createServer(httpApp).listen(8080);
// Start Socket.io so it attaches itself to Express server
var socketServer = io.listen(webServer);
// Start EasyRTC server
var easyrtcServer = easyrtc.listen(httpApp, socketServer);
以上代码starting an HTTP server serving all files under static,and attaches a socket server to the HTTP server, this socket server is providing the signaling listeners。
服务器的js文件要放在root文家下面。

如果有配置动作,可以:
1)通过setOption完成,不过注意要安排在listen之前
easyrtc.setOption(‘OPTION_NAME’, ‘OPTION_VALUE’);
例如下面这条设置信令服务器的set a default STUN server and deactivate the usage of default meeting rooms
easyrtc.setOption(‘appIceServers’, [{url: ‘stun:stun.l.google.com:19302’}], ‘roomDefaultEnable’, true);
2)或者把配置动作直接写在listen里面
var easyrtcServer = easyrtc.listen(httpApp, socketServer, {‘OPTION1_NAME’: ‘OPTION1_VALUE’, ‘OPTION2_NAME’: ‘OPTION2_VALUE’})

7、浏览器前端测试验证

用本机linux台式机上的firefox测试
http://localhost:8080
okay

用同一网段win7笔记本上的firefox上测试
http://172.20.10.11:8080
也okay

7.1 Chrome
Q: 如果browser是google的chrome的话,会报错“Failed to get access to local media. Error code was Permission Denied”
因为,chrome needs https to use get user media,Updated to secure http and everything works fine.
由于,Starting with Chrome 47, getUserMedia() requests only allowed from secure HTTPS or localhost, so need to setup a self signed ssl certificate for webserver and and access with https://722.20.10.11:8080
所以,如果使用chrome浏览器的话,可以部署自签署证书采用ssl实现https。
如果一定要选择http实现webrtc的话,那就用firefox浏览器不要用chrome。

Q: how to always accept webRTC webcam request in chrome?
if command line:
$ google-chrome “http://localhost” –use-fake-ui-for-media-stream
which avoids the need to grant camera/microphone permissions.
or, on Chrome:
chrome://settings/content#media-stream-mic

APP: List of Chromium Command Line Switches
http://peter.sh/experiments/chromium-command-line-switches/

7.2 Firefox
Q: how to always accept webRTC webcam request in firefox?
Go in url about:config
Search media.navigator.permission.disabled
dbClick or set value to true

7.3 Setup ssl https connection
As mentioned earlier, apps running on Chrome browsers can’t access local cameras and microphones unless the application is hosted from localhost or an SSL server (https).
When you are doing development, it is simplest to get node.js to handle the SSL. Benefits of using SSL:
* Increase end user confidence
* Secure signaling traffic from eavesdroppers
* In Chrome: Browser remembers camera and microphone sharing preference for site. Does not re-ask at each – visit.
* In Chrome: Enables screen sharing API
Before applying, you will need to generate a CSR (Certificate Signing Request). The most common software used for generating CSR’s and handling SSL is OpenSSL,
There are many operating system specific guides available for how to use SSL on your server Self signed certificates are a free method of creating a certificate suitable for development. A warning will occur when browsing your site.
http://www.selfsignedcertificate.com/ <— from thi st ogenerate or, You can create a key and certificate yourself instead of downloading them from this page. This makes your key more secure. To generate a key: $ openssl genrsa -out 172.20.10.3.key 2048 And the certificate: $ openssl req -new -x509 -key 172.20.10.3.key -out 172.20.10.3.cert -days 3650 -subj /CN=172.20.10.3 or, to buy one http://bit.ly/i95aUS 7.5 客户端的证书设置 如果是商业购买的,证书链可靠,浏览器不需要设置。 如果是自签名的,需要导入或下载证书,各个浏览器不同: 7.6 Firefox 这个在访问https://serverIP时, 会提示网站不可信任。 那么添加例外就可以: exception->confirm security exception https://serverIP ok,就可以通过ip地址访问。 7.7 hrome 这个访问https://IP-address,浏览器: Your connection is not private Attackers might be trying to steal your information from 116.50.77.22 (for example, passwords, messages or credit cards). NET::ERR_CERT_COMMON_NAME_INVALID 具体的: This server could not prove that it is 116.50.77.22; its security certificate is not trusted by your computer’s operating system. This may be caused by a misconfiguration or an attacker intercepting your connection. Proceed to 116.50.77.22 (unsafe) 所以,同样需要添加证书: edit->preference->advanced setting->https/ssl->authorities->import->ok. 但是, Chrome非常憎恨自签署证书Why does Chrome hate self-signed certificates so much。 浏览器依然不能像http那样通过IP地址访问服务器,对于https://serverIP这种方式依然报警: Server’s certificate does not match the URL 所以,需要根据证书里Issued to的域名信息修改: $ vi /etc/hosts 10.10.0.1 dehaou14-n501jw $ ping dehaou14-n501jw ok https://dehaou14-n501jw/ ok 8、客户端的代码解析 首先要制作一个类似index.html的文件,一般放在static文件夹下面,因为server.js里面默认指定static文件夹作为客户浏览器前端访问html的位置。<<

0 回复

发表评论

Want to join the discussion?
Feel free to contribute!

发表评论