# peerjs

  • 要创建一个真正的webrtc应用还是有些小复杂的,特别是SDP交换(createOffer及createAnswer)、网络候选信息收集(ICE candidate),这些都需要开发人员对webrtc的机制有足够的了解,对webrtc初学者来讲有一定的开发门槛。

  • 而peerjs开源项目简化了webrtc的开发过程,把SDP交换、ICE candidate这些偏底层的细节都做了封装,开发人员只需要关注应用本身就行了。 peerjs的核心对象Peer,它有几个常用方法:

1. peer.connect 创建点对点的连接
1. peer.call 向另1个peer端发起音视频实时通信
1. peer.on 对各种事件的监控回调
1. peer.disconnect 断开连接
1. peer.reconnect 重新连接
1. peer.destroy 销毁对象
1
2
3
4
5
6
  • 另外还有二个重要对象DataConnection、MediaConnection,其中:
  • DataConnection用于收发数据(对应于webrtc中的DataChannel),它的所有方法中有一个重要的send方法,用于向另一个peer端发送数据; MediaConnection用于处理媒体流,它有一个重要的stream属性,表示关联的媒体流。

安装peerjs服务

  1. 安装nodejs
  2. 新建个peer项目目录 如dxpeer
  3. 在dxpeer 运行 npm install peer --S
  4. 最后个index.js
const fs = require('fs');
const { PeerServer } = require('peer');
const customGenerationFunction = () => (Math.random().toString(36) + '0000000000000000000').substr(2, 16);
const peerServer = PeerServer({
  port: 9000,
  path: '/dxPeer',
  allow_discovery:true, //设置为真可以查看所有连接的用户
  ssl: { // https证书
    key:fs.readFileSync('./keys/2_duxinggj.com.key'),
    cert:fs.readFileSync('./keys/1_duxinggj.com_bundle.crt')
  },
  generateClientId: customGenerationFunction // 生成随机的id
});

1
2
3
4
5
6
7
8
9
10
11
12
13
14

在cmd cmd 运行 node index 这样服务就跑起来了

  1. 查看是否安装成功 http://localhost:9000/dxPeer
  2. http://localhost:9000/dxPeer/peer/peers //获取在线用户

客户端

直接在vue项目的index.html 引入即可 peerjs1.3.1

<script>
    window.Peer = Peer;
</script> 
1
2
3

# 在全局状态里写peerjs

建立连接和初始化

peer = new window.Peer(userName, {
    host: "duxinggj.com",
    port: 8089,
    path: "/dxPeer",
    config: {
      iceServers: [
        {
          urls: "stun:119.23.104.210:5349",
        },
        {
          urls: "turn:119.23.104.210:3478",
          username: "admin",
          credential: "kiss1001",
        },
      ],
      sdpSemantics: "unified-plan",
    },
  });

 peer.on("open", async (id) => {
    console.log("peerJs服务连接成功!我的账号是:" + id);
  });
 // 监听用户连接
  peer.on("connection", function (c) {
    conn = c;
    conn.on("data", function (data) { //监听对方发送来的data消息处理事件
        switch (data) {
        case "closecall":
        current.close();
        state.TheActive = 0;
        state.hangUpload = false;
        break;
        ...
        }
    });
  });
                                      
                                      // 监听呼叫
  peer.on("call", async (call) => {
        call.answer(stream); // 把流传给对方 对方才会播放视频
  })
peer.on("close", function () {
    console.log("peer--close");
  });
  // 监听会话销毁了
  peer.on("destroy", function () {
    console.log("destroy");
  });
 peer.on("disconnected", function () {
    console.log("disconnected");
  }); 
   // 会话错误信息钩子回调
  peer.on("error", function (e) {
    
})
                                      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

拨号

const callFun = async (state, callName) => {
    call = peer.call(callName, stream); // 呼叫对方
//              建立连接方便发消息                              
     dataConnection = peer.connect(callName);
    dataConnection.on("open", function () {
    dataConnection.send("与用户" + state.userName + "连接成功!");
    dataConnection.on("data", function (data) {
       switch (data) {
        case "closecall":
        current.close();
        state.TheActive = 0;
        state.hangUpload = false;
        break;
        ...
        }
    });
  });       
                                            
 call.on("stream", (data) => {
    console.log("监听到了流call播放");
    console.log(data);
  });
  call.on("close", function (e) {
    dataConnection.send("closecall");
  });
  call.on("error", function (err) {
    console.error("通话的状态异常了", err);
  });
  call.on("disconnect", function (err) {
    console.error("disconnect", err);
  });                                                                                   
})


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

后面就是封装组件 和 全局状态管理了

效果展示 高仿微信聊天