pionwebrtc⽰例代码解析⼀
pion webrtc
pion 是go语⾔写的webrtc的开发库套装
DTLS 协议
自己洗牙我们对DTLS 协议要适当的解释,TLS是⽤于TCP的,⽽DTLS是⽤于数据报的,很多应⽤运⾏在TCP之上,但是⽬前这种情况正在改变。现在不断增长的应⽤层协议,⽐如SIP (ssion initial protocol),RTP (real time protocol), MGCP (the Media Gateway Control Protocol),还有许多游戏协议都基于UDP传输⽽设计,⽽HTTP协议也正悄然改变,HTTP3可能也会转移到udp上。那么webrtc的datachannel也是基于这个协议的。
DataChannel的数据通过boringssl加密后再通过udp发送给对端,实现了DTLS,发送datachannel数据和⾳视频数据的事实上是同⼀个sock。不过不⼀样的是:⾳视频数据传输使⽤了RTP协议,并且通过NACK和FEC算法来抗丢包,⽽DataChannel底层使⽤了
SCTP(stream control transmission protocol)协议,SCTP和TCP类似,具备流量控制、拥塞控制,可以说是⼀个可靠性传输协议,因此可以不采取其它措施即,就已经实现DataChannel数据的可靠传输。we
brtc采⽤了第三⽅开源库usrsctplib来实现SCTP协议。
pion⽰例代码
这⾥,我们会对pion的⽰例⼀⼀解析,⾸先:启动 go , , 是⼀个http协议的服务器,默认在80端⼝启动协议,这⾥我们打开⽹页后,打开datachannel⽰例:
点击run javascript后,得到Browr ba64 Session Description框⾥的数据,复制⾥⾯的ba64到⼀个⽂件中,保存名字为a.txt ! [data channel ⽰例](img-blog.csdnimg/6cd3bbdfc5dd44fba6fa57a9c288306c.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FpYW 5ibzA0MjMxMQ==,size_16,color_FFFFFF,t_70) 然后进⼊datachannel ⽬录 go < a.txt 就会得到⾃⼰的sdp信息,将这个sdp信息复制到页⾯中, ![复制进去](img-blog.csdnimg/3a8f9b70a01b4558bf5b3a8ad6049023.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FpYW 5ibzA0MjMxMQ==,size_16,color_FFFFFF,t_70) 点击Start ssion, ⽹页和客户端可以开始互相发送信息。
⽰例datachannel
offer := webrtc.SessionDescription{}
signal.Decode(signal.MustReadStdin(),&offer)
singal 需要对输⼊进⾏读取,所以要从参数上输⼊offer,offer是⼀串码,sdp信息,我们来看看解码后的字符串:
{
offer v=0
o=- 203838700267639233 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=extmap-allow-mixed
a=msid-mantic: WMS
m=application 3002 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 1.86.247.81
a=candidate:2026329132 1 udp 2122260223 192.168.0.129 51720 typ host generation 0 network-id 1
a=candidate:910469340 1 tcp 1518280447 192.168.0.129 9 typ host tcptype active generation 0 network-id 1
a=candidate:4186919576 1 udp 1686052607 1.86.247.81 3002 typ srflx raddr 192.168.0.129 rport 51720 generation 0 network-id 1
a=ice-ufrag:y7zo
a=ice-pwd:vYIYqME4lmB5i0C3JwVZQicy冰箱冷藏室的温度
a=ice-options:trickle
a=fingerprint:sha-256
A2:28:50:C3:45:9D:19:12:6D:29:C5:32:06:97:C7:D2:37:9F:EA:A2:02:68:58:91:76:E6:44:17:8D:B9:C6:A8
a=tup:actpass
a=mid:0
香港奶茶a=sctp-port:5000
a=max-message-size:262144
}
这下看的很清晰了
package main
import(
"fmt"
"os"
"time"
"/pion/webrtc/v3"
"/pion/webrtc/v3/examples/internal/signal"
)
func main(){
// Everything below is the Pion WebRTC API! Thanks for using it ❤ .
// Prepare the configuration
config := webrtc.Configuration{
ICEServers:[]webrtc.ICEServer{
{
URLs:[]string{"stun:le.com:19302"},
},
},
}
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
if err !=nil{
panic(err)
}
defer func(){
if cErr := peerConnection.Clo(); cErr !=nil{
fmt.Printf("cannot clo peerConnection: %v\n", cErr)
}
// Set the handler for Peer connection state
// This will notify you when the peer has connected/disconnected
peerConnection.OnConnectionStateChange(func(s webrtc.PeerConnectionState){
fmt.Printf("Peer Connection State has changed: %s\n", s.String())
if s == webrtc.PeerConnectionStateFailed {
// Wait until PeerConnection has had no network activity for 30 conds or another failure. It may be reconnected using an ICE Restart.
// U webrtc.PeerConnectionStateDisconnected if you are interested in detecting faster timeout.
// Note that the PeerConnection may come back from PeerConnectionStateDisconnected.
fmt.Println("Peer Connection has gone to failed exiting")
os.Exit(0)
}
})
// Register data channel creation handling肠炎病
小时候的点点滴滴peerConnection.OnDataChannel(func(d *webrtc.DataChannel){
fmt.Printf("New DataChannel %s %d\n", d.Label(), d.ID())
// Register channel opening handling
d.OnOpen(func(){
fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be nt to any connected DataChannels every 5 conds\n", d.Label(), d.ID())
for range time.NewTicker(5* time.Second).C {
message := signal.RandSeq(15)
fmt.Printf("Sending '%s'\n", message)
// Send the message as text
ndErr := d.SendText(message)
if ndErr !=nil{
panic(ndErr)女同互摸
陀螺怎么写}
}
})
// Register text message handling
d.OnMessage(func(msg webrtc.DataChannelMessage){
fmt.Printf("Message from DataChannel '%s': '%s'\n", d.Label(),string(msg.Data))
})
})
// Wait for the offer to be pasted
offer := webrtc.SessionDescription{}
signal.Decode(signal.MustReadStdin(),&offer)
/
/ Set the remote SessionDescription
err = peerConnection.SetRemoteDescription(offer)
if err !=nil{
panic(err)
}
// Create an answer
answer, err := peerConnection.CreateAnswer(nil)
if err !=nil{
panic(err)
}
// Create channel that is blocked until ICE Gathering is complete
gatherComplete := webrtc.GatheringCompletePromi(peerConnection)
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
if err !=nil{
鱼盆panic(err)
// Block until ICE Gathering is complete, disabling trickle ICE
// we do this becau we only can exchange one signaling message
// in a production application you should exchange ICE Candidates via OnICECandidate
<-gatherComplete
// Output the answer in ba64 so we can paste it in browr
fmt.Println(signal.Encode(*peerConnection.LocalDescription()))
/
/ Block forever
lect{}
}
⽹页和客户端
⽹页和客户端的api ⾮常接近,可以看出pion是⾮常友好的,可以根据这个 ⽰例来制作点对点的聊天程序。