ReactNative-即时通讯WebRTC+PeerJS使用姿势

首先简单介绍一下WebRTC是个什么鬼。

什么是WebRTC

全称Web Real-Time Communication,网页即时通信,是一个支持网页浏览器进行实时语音对话或视频对话的API。它于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准。

至于其他详细描述我不啰嗦了,百度一搜有很多架构图啊啥的,放一个github链接,需要的可以进去了解了解,里面有使用方法跟api:https://github.com/react-native-webrtc/react-native-webrtc

什么是PeerJS

PeerJS 提供了一个完整、可配置、易于使用、基于WebRTC的点对点的数据通信。
简单来讲,他帮你封装简化了使用WebRTC,你可以利用peerjs轻松的实现这些功能。

他们能干什么

能够实现即时通讯的语音对话、视频对话、文字对话的功能。

那接下来我们讲讲怎么搭建。

配置

首先描述一下当前搭建的环境,可能你看到这篇的时候版本啥的都已经不一样,会产生一些出入。
react-native-cli: 2.0.1
react-native: 0.62.2
webrtc:"react-native-webrtc": "^1.84.0",
peerjs:"react-native-peerjs": "^1.0.4",
android:buildToolsVersion = "28.0.3"
ios:platform :ios, '11.0'

1 导入WebRTC

因为peerjs包需要在webrtc的基础上,所以我们还是得先走一遍webrtc配置流程。

yarn add react-native-webrtc

2 ios配置

修改版本

修改platform,因为react native webrtc不支持ios11以下,所以项目如果低于11要改掉
ios/Podfile文件


image.png
添加权限

给项目添加照相跟麦克风(如果你有用到麦克风的话)的权限


image.png
<key>NSCameraUsageDescription</key>
<string>获取相机权限 文案自己调整</string>
<key>NSMicrophoneUsageDescription</key>
<string>获取麦克风权限 文案自己调整</string>

3 android配置

添加权限

给项目添加照相跟麦克风(如果你有用到麦克风的话)的权限。
其中android.permission.RECORD_AUDIO是麦克风权限,其他权限有就不用添加了。


image.png
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
添加java8支持
image.png
android {
...
compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

ok,不出意外你应该可以在代码里面调用webrtc了,比如这样

import {RTCPeerConnection} from 'react-native-webrtc'

4 导入PeerJS

peerjs官方只针对web(反正我是没找到官方提供给react native的),只找到一个热心市民的github包,别看star少,能用就行!附上链接:https://github.com/Zemke/react-native-peerjs
老规矩

yarn add react-native-peerjs

ok,不出意外你应该能在代码里这样了

import Peer from 'react-native-peerjs'

到此为止,配置完成,接下来说一下使用姿势。

使用

首先解释一下,这个东西是要配合后端一起使用的,需要你们的后端也去建立一个peerjs的服务器,然后我们去连接他,如果你按照github上的例子直接使用当然也可以用,但是跑的是peerjs官方的服务器。
如果连接官方服务器,直接一句代码就完事了

const localPeer = new Peer()

如果连接自己的服务器,那么要配置一下

localPeer = new Peer(userClientId, {
    host: WEBRTC_SERVERS, secure: true, path: WEBRTC_PATH, debug: 0, port: WEBRTC_PORT,
  });

首先,userClientId是你自己的id,是由你自己创建的字符串,当然得要唯一,具体生成什么样的就看你们项目组怎么安排了。host、path、port这些都是后端搭建好后会告诉你的,debug的数字是设置log输出内容,参考一下官方描述,

0 Prints no logs.
1 Prints only errors.
2 Prints errors and warnings.
3 Prints all logs.

secure设置为true是https,false是http。
接下来是一系列的监听回调,姿势统一

//被连接后的回调
localPeer.on('connection', function (conn) {
    console.log('local connection', conn)
  });
//new Peer后成功打开连接的回调
localPeer.on('open', localPeerId => {
    console.log('local open:' + localPeerId)
  })
//接收到data数据
localPeer.on('data', data => {
    console.log('local data:' + data)
  })
//连接关闭的回调
localPeer.on('close', () => {
    console.log('local close')
  })
//断开连接的回调
localPeer.on('disconnected', () => {
    console.log('local disconnected')

  })
//连接失败的回调
localPeer.on('error', err => {
    console.log('local error ========>' + err)
  })

一般来说,当open成功回调了我们就可以开始去连接对方了,连接对方的姿势是

conn = localPeer.connect(serverID)

serverID就是你要连接的目标id,当然前提是对方也连接了你们的后端并成功开启了。
接下来可以对这个连接对象进行一系列监听,姿势跟上面是统一的,那么你可能会奇怪了,那我有两个data事件监听(本地的peer对象以及connect生成的peer对象),我要在哪个处理接收数据呢?
因为我本身项目的需求是永远是我(手机端)去主动连接对方(网页端),所以我的data事件回调是在connect了之后生成的对象的监听里面,就是

conn.on('data', data => {
    console.log('接收到data:' + data)
  })

所以我估计(估计),如果是被动连接,那么应该就是触发?

localPeer.on('data', data => {
    console.log('local data:' + data)
  })

我没试过,有需要的试一试,不就是个回调的事嘛,输出一下就知道了。
以上差不多就是文字即时通讯的全部了,至于语音跟视频目前项目还没做需求,提供一个官方api链接,虽然针对的是web,但是是通用的:https://peerjs.com/docs.html#api

// Call a peer, providing our mediaStream
var call = peer.call('dest-peer-id',
  mediaStream);

peer.on('call', function(call) {
  // Answer the call, providing our mediaStream
  call.answer(mediaStream);
});

我觉得,应该就是这个函数了。

推荐阅读更多精彩内容