slight refactoring, WS sends periodic ping

This commit is contained in:
David Zhao committed 2020-12-20 16:13:12 -08:00
1 parent 72d853589c
commit 684099d653
9 files changed
+75 -37

No files matched your search

+1 -1
View File
@@ -360,7 +360,7 @@ func (p *Participant) onMediaTrack(track *webrtc.TrackRemote, rtpReceiver *webrt
logger.GetLogger().Debugw("remoteTrack added", "participantId", p.ID(), "remoteTrack", track.ID())
// create Receiver
receiver := NewReceiver(p.ctx, p.id, rtpReceiver, p.bi)
receiver := NewReceiver(p.id, rtpReceiver, p.bi)
mt := NewMediaTrack(p.id, p.rtcpCh, track, receiver)
p.handleTrackPublished(mt)
+4 -19
View File
@@ -1,8 +1,6 @@
package rtc
import (
"context"
"io"
"sync"
"github.com/pion/ion-sfu/pkg/buffer"
@@ -20,8 +18,6 @@ const (
// A receiver is responsible for pulling from a remoteTrack
type Receiver struct {
peerId string
ctx context.Context
cancel context.CancelFunc
rtpReceiver *webrtc.RTPReceiver
track *webrtc.TrackRemote
bi *buffer.Interceptor
@@ -29,15 +25,11 @@ type Receiver struct {
bytesRead int64
}
func NewReceiver(ctx context.Context, peerId string, rtpReceiver *webrtc.RTPReceiver, bi *buffer.Interceptor) *Receiver {
ctx, cancel := context.WithCancel(ctx)
track := rtpReceiver.Track()
func NewReceiver(peerId string, rtpReceiver *webrtc.RTPReceiver, bi *buffer.Interceptor) *Receiver {
return &Receiver{
ctx: ctx,
cancel: cancel,
peerId: peerId,
rtpReceiver: rtpReceiver,
track: track,
track: rtpReceiver.Track(),
bi: bi,
once: sync.Once{},
}
@@ -58,14 +50,6 @@ func (r *Receiver) Start() {
})
}
// Close gracefully close the remoteTrack. if the context is canceled
func (r *Receiver) Close() {
if r.ctx.Err() != nil {
return
}
r.cancel()
}
// PacketBuffer interface, to provide forwarders packets from the buffer
func (r *Receiver) GetBufferedPackets(mediaSSRC uint32, snOffset uint16, tsOffset uint32, sn []uint16) []rtp.Packet {
if r.bi == nil {
@@ -80,9 +64,10 @@ func (r *Receiver) ReadRTP() (*rtp.Packet, error) {
// rtcpWorker reads RTCP messages from receiver, notifies buffer
func (r *Receiver) rtcpWorker() {
// consume RTCP from the sender/source, but don't need to do anything with the packets
for {
_, err := r.rtpReceiver.ReadRTCP()
if err == io.ErrClosedPipe || r.ctx.Err() != nil {
if IsEOF(err) {
return
}
if err != nil {
+5
View File
@@ -2,6 +2,7 @@ package rtc
import (
"encoding/json"
"io"
"strings"
"github.com/pion/webrtc/v3"
@@ -85,3 +86,7 @@ func FromProtoTrickle(trickle *livekit.Trickle) webrtc.ICECandidateInit {
json.Unmarshal([]byte(trickle.CandidateInit), &ci)
return ci
}
func IsEOF(err error) bool {
return err == io.ErrClosedPipe || err == io.EOF
}
+29
View File
@@ -0,0 +1,29 @@
package rtc
import (
"testing"
"github.com/magiconair/properties/assert"
)
func TestPackTrackId(t *testing.T) {
packed := "PA_123abc|uuid-id"
pId, trackId := UnpackTrackId(packed)
assert.Equal(t, "PA_123abc", pId)
assert.Equal(t, "uuid-id", trackId)
assert.Equal(t, packed, PackTrackId(pId, trackId))
}
func TestPackDataTrackLabel(t *testing.T) {
pId := "PA_123abc"
trackId := "TR_b3da25"
label := "trackLabel"
packed := "PA_123abc|TR_b3da25|trackLabel"
assert.Equal(t, packed, PackDataTrackLabel(pId, trackId, label))
p, tr, l := UnpackDataTrackLabel(packed)
assert.Equal(t, pId, p)
assert.Equal(t, trackId, tr)
assert.Equal(t, label, l)
}
+27 -6
View File
@@ -2,6 +2,7 @@ package rtc
import (
"sync"
"time"
"github.com/gorilla/websocket"
"google.golang.org/protobuf/encoding/protojson"
@@ -11,23 +12,36 @@ import (
"github.com/livekit/livekit-server/proto/livekit"
)
const (
pingFrequency = 10 * time.Second
pingTimeout = 2 * time.Second
)
type WebsocketClient interface {
ReadMessage() (messageType int, p []byte, err error)
WriteMessage(messageType int, data []byte) error
WriteControl(messageType int, data []byte, deadline time.Time) error
}
type SignalConnection interface {
ReadRequest() (*livekit.SignalRequest, error)
WriteResponse(*livekit.SignalResponse) error
}
type WSSignalConnection struct {
conn *websocket.Conn
conn WebsocketClient
mu sync.Mutex
useJSON bool
}
func NewWSSignalConnection(conn *websocket.Conn) *WSSignalConnection {
return &WSSignalConnection{
func NewWSSignalConnection(conn WebsocketClient) *WSSignalConnection {
wsc := &WSSignalConnection{
conn: conn,
mu: sync.Mutex{},
useJSON: true,
}
go wsc.pingWorker()
return wsc
}
func (c *WSSignalConnection) ReadRequest() (*livekit.SignalRequest, error) {
@@ -40,9 +54,6 @@ func (c *WSSignalConnection) ReadRequest() (*livekit.SignalRequest, error) {
msg := &livekit.SignalRequest{}
switch messageType {
case websocket.PingMessage:
c.conn.WriteMessage(websocket.PongMessage, nil)
continue
case websocket.BinaryMessage:
// protobuf encoded
err := proto.Unmarshal(payload, msg)
@@ -79,3 +90,13 @@ func (c *WSSignalConnection) WriteResponse(msg *livekit.SignalResponse) error {
defer c.mu.Unlock()
return c.conn.WriteMessage(msgType, payload)
}
func (c *WSSignalConnection) pingWorker() {
for {
<-time.After(pingFrequency)
err := c.conn.WriteControl(websocket.PingMessage, []byte(""), time.Now().Add(pingTimeout))
if err != nil {
return
}
}
}
+5 -7
View File
@@ -98,16 +98,14 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err == io.EOF {
// client disconnected from websocket
return
}
if err != nil {
// most of these are disconnection, just return vs clogging up logs
//logger.GetLogger().Errorw("error reading WS",
// "err", err,
// "participantName", pName,
// "roomId", roomId)
} else if err != nil {
return
}
if req == nil {
continue
}
switch msg := req.Message.(type) {
case *livekit.SignalRequest_Offer:
err = s.handleOffer(participant, msg.Offer)