handles RTC join

This commit is contained in:
David Zhao committed 2020-10-31 00:09:46 -07:00
1 parent 36dd195ca3
commit 54b59f00e2
6 files changed
+170 -42

No files matched your search

+3 -2
View File
@@ -28,7 +28,7 @@ type WebRTCPeer struct {
// OnOffer - offer is ready for remote peer
OnOffer func(webrtc.SessionDescription)
// OnIceCandidate - ice candidate discovered for local peer
OnICECandidate func(c *webrtc.ICECandidate)
OnICECandidate func(c *webrtc.ICECandidateInit)
OnClose func(*WebRTCPeer)
}
@@ -76,7 +76,8 @@ func NewWebRTCPeer(id string, me *MediaEngine, conf WebRTCConfig) (*WebRTCPeer,
return
}
if peer.OnICECandidate != nil {
peer.OnICECandidate(c)
ci := c.ToJSON()
peer.OnICECandidate(&ci)
}
})
+2
View File
@@ -52,6 +52,8 @@ func (r *Room) ToRoomInfo(node *livekit.Node) *livekit.RoomInfo {
}
func (r *Room) Join(peerId string, token string, sdp string) (peer *WebRTCPeer, err error) {
// TODO: check token and reject
r.lock.Lock()
defer r.lock.Unlock()
+115 -4
View File
@@ -1,6 +1,14 @@
package service
import (
"encoding/json"
"io"
"github.com/pion/webrtc/v3"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/livekit/livekit-server/pkg/logger"
"github.com/livekit/livekit-server/pkg/rtc"
"github.com/livekit/livekit-server/proto/livekit"
)
@@ -10,12 +18,115 @@ type RTCService struct {
manager *rtc.RoomManager
}
func (s *RTCService) Signal(stream livekit.RTCService_SignalServer) error {
return nil
}
func NewRTCService(manager *rtc.RoomManager) *RTCService {
return &RTCService{
manager: manager,
}
}
// each client establishes a persistent signaling connection to the server
// when the connection is terminated, WebRTC session shall end
// similarly, when WebRTC connection is disconnected, we'll terminate signaling
func (s *RTCService) Signal(stream livekit.RTCService_SignalServer) error {
var peer *rtc.WebRTCPeer
for {
req, err := stream.Recv()
if err != nil {
if peer != nil {
peer.Close()
if err == io.EOF {
return nil
}
errStatus, _ := status.FromError(err)
if errStatus.Code() == codes.Canceled {
return nil
}
logger.GetLogger().Errorf("signaling error", errStatus.Message(), errStatus.Code())
return err
}
}
switch msg := req.Message.(type) {
case *livekit.SignalRequest_Join:
peer, err = s.handleJoin(msg.Join, stream)
case *livekit.SignalRequest_Negotiate:
if peer == nil {
return status.Errorf(codes.FailedPrecondition, "peer has not joined yet")
}
}
}
return nil
}
func (s *RTCService) handleJoin(join *livekit.JoinRequest, stream livekit.RTCService_SignalServer) (*rtc.WebRTCPeer, error) {
// join a room
room := s.manager.GetRoom(join.RoomId)
if room == nil {
return nil, status.Errorf(codes.NotFound, "room %s doesn't exist", join.RoomId)
}
peer, err := room.Join(join.PeerId, join.Token, join.Offer.Sdp)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not join room: %v", err)
}
offer := webrtc.SessionDescription{
Type: webrtc.SDPTypeOffer,
SDP: string(join.Offer.Sdp),
}
answer, err := peer.Answer(offer)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not answer offer: %v", err)
}
// TODO: it might be better to return error instead of nil
peer.OnICECandidate = func(c *webrtc.ICECandidateInit) {
bytes, err := json.Marshal(c)
if err != nil {
logger.GetLogger().Errorf("could not marshal ice candidate: %v", err)
return
}
err = stream.Send(&livekit.SignalResponse{
Message: &livekit.SignalResponse_Trickle{
Trickle: &livekit.Trickle{
CandidateInit: string(bytes),
},
},
})
if err != nil {
logger.GetLogger().Errorw("could not send trickle", "err", err)
}
}
// send peer new offer
peer.OnOffer = func(o webrtc.SessionDescription) {
err := stream.Send(&livekit.SignalResponse{
Message: &livekit.SignalResponse_Negotiate{
Negotiate: ToProtoSessionDescription(&o),
},
})
if err != nil {
logger.GetLogger().Errorw("could not send offer to peer",
"err", err)
}
}
// finally send answer
err = stream.Send(&livekit.SignalResponse{
Message: &livekit.SignalResponse_Join{
Join: &livekit.JoinResponse{
Answer: ToProtoSessionDescription(&answer),
},
},
})
if err != nil {
return nil, status.Errorf(codes.Internal, "could not join: %v", err)
}
return peer, nil
}
+14
View File
@@ -0,0 +1,14 @@
package service
import (
"github.com/pion/webrtc/v3"
"github.com/livekit/livekit-server/proto/livekit"
)
func ToProtoSessionDescription(sd *webrtc.SessionDescription) *livekit.SessionDescription {
return &livekit.SessionDescription{
Type: sd.Type.String(),
Sdp: sd.SDP,
}
}
+35 -35
View File
@@ -117,7 +117,7 @@ func (*SignalRequest) XXX_OneofWrappers() []interface{} {
type SignalResponse struct {
// Types that are valid to be assigned to Message:
// *SignalResponse_Jin
// *SignalResponse_Join
// *SignalResponse_Negotiate
// *SignalResponse_Trickle
Message isSignalResponse_Message `protobuf_oneof:"message"`
@@ -155,8 +155,8 @@ type isSignalResponse_Message interface {
isSignalResponse_Message()
}
type SignalResponse_Jin struct {
Jin *JoinResponse `protobuf:"bytes,1,opt,name=jin,proto3,oneof"`
type SignalResponse_Join struct {
Join *JoinResponse `protobuf:"bytes,1,opt,name=join,proto3,oneof"`
}
type SignalResponse_Negotiate struct {
@@ -167,7 +167,7 @@ type SignalResponse_Trickle struct {
Trickle *Trickle `protobuf:"bytes,3,opt,name=trickle,proto3,oneof"`
}
func (*SignalResponse_Jin) isSignalResponse_Message() {}
func (*SignalResponse_Join) isSignalResponse_Message() {}
func (*SignalResponse_Negotiate) isSignalResponse_Message() {}
@@ -180,9 +180,9 @@ func (m *SignalResponse) GetMessage() isSignalResponse_Message {
return nil
}
func (m *SignalResponse) GetJin() *JoinResponse {
if x, ok := m.GetMessage().(*SignalResponse_Jin); ok {
return x.Jin
func (m *SignalResponse) GetJoin() *JoinResponse {
if x, ok := m.GetMessage().(*SignalResponse_Join); ok {
return x.Join
}
return nil
}
@@ -204,7 +204,7 @@ func (m *SignalResponse) GetTrickle() *Trickle {
// XXX_OneofWrappers is for the internal use of the proto package.
func (*SignalResponse) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*SignalResponse_Jin)(nil),
(*SignalResponse_Join)(nil),
(*SignalResponse_Negotiate)(nil),
(*SignalResponse_Trickle)(nil),
}
@@ -411,31 +411,31 @@ func init() {
func init() { proto.RegisterFile("rtc.proto", fileDescriptor_85bd91e80f756774) }
var fileDescriptor_85bd91e80f756774 = []byte{
// 406 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x93, 0xcf, 0x6e, 0xd3, 0x40,
0x10, 0x87, 0x63, 0x92, 0xda, 0xf2, 0x94, 0x56, 0xd5, 0xa8, 0x50, 0x0b, 0x2e, 0xc8, 0x12, 0x52,
0x41, 0xe0, 0xf4, 0xcf, 0x0d, 0xc4, 0xa5, 0xe5, 0xe0, 0xc0, 0x6d, 0xd3, 0x13, 0x97, 0xca, 0xb5,
0xa7, 0x66, 0x9a, 0x64, 0xd7, 0xec, 0x6e, 0x83, 0x78, 0x03, 0x5e, 0x87, 0x37, 0x44, 0x5e, 0xaf,
0xdd, 0x88, 0x48, 0x70, 0xe4, 0xe4, 0x9d, 0xd1, 0xf7, 0x5b, 0x7d, 0x33, 0xb6, 0x21, 0xd6, 0xb6,
0xcc, 0x1a, 0xad, 0xac, 0xc2, 0x68, 0xc9, 0x6b, 0x5a, 0xb0, 0x4d, 0x7f, 0x05, 0xb0, 0x37, 0xe7,
0x5a, 0x16, 0x4b, 0x41, 0xdf, 0xee, 0xc9, 0x58, 0x7c, 0x0d, 0x93, 0x3b, 0xc5, 0x32, 0x09, 0x5e,
0x04, 0xc7, 0xbb, 0x67, 0x87, 0x99, 0x27, 0xb3, 0x4f, 0x8a, 0xa5, 0x67, 0xf2, 0x91, 0x70, 0x0c,
0xbe, 0x87, 0x58, 0x52, 0xad, 0x2c, 0x17, 0x96, 0x92, 0x47, 0x2e, 0xf0, 0x7c, 0x08, 0xcc, 0xc9,
0x18, 0x56, 0xf2, 0x23, 0x99, 0x52, 0x73, 0x63, 0x59, 0xc9, 0x7c, 0x24, 0x1e, 0x78, 0x7c, 0x03,
0x91, 0xd5, 0x5c, 0x2e, 0x96, 0x94, 0x8c, 0x5d, 0xf4, 0x60, 0x88, 0x5e, 0x75, 0xfd, 0x7c, 0x24,
0x7a, 0xe4, 0x22, 0x86, 0x68, 0x45, 0xc6, 0x14, 0x35, 0xb5, 0xce, 0xfb, 0xbd, 0xb3, 0x69, 0x94,
0x34, 0x84, 0xaf, 0x60, 0x7c, 0x37, 0x38, 0x3f, 0xf9, 0xc3, 0xb9, 0x63, 0xf2, 0x91, 0x68, 0x99,
0xff, 0xe4, 0xfc, 0x33, 0x80, 0xdd, 0x8d, 0x0d, 0xe2, 0x11, 0x44, 0x5a, 0xa9, 0xd5, 0x35, 0x57,
0x4e, 0x3a, 0x16, 0x61, 0x5b, 0xce, 0x2a, 0x3c, 0x84, 0x1d, 0xab, 0x16, 0x24, 0x9d, 0x5a, 0x2c,
0xba, 0xa2, 0xc5, 0x1b, 0x22, 0xdd, 0xe2, 0xe3, 0x0e, 0x6f, 0xcb, 0x59, 0x85, 0xa7, 0xb0, 0xa3,
0x6e, 0x6f, 0x49, 0x27, 0x93, 0x7f, 0x4e, 0x22, 0x3a, 0x32, 0xbd, 0x84, 0xc7, 0x9b, 0x7b, 0xc1,
0x73, 0x08, 0x0b, 0x69, 0xbe, 0x93, 0xf6, 0xeb, 0xfb, 0xeb, 0x1d, 0x1e, 0x4d, 0x4f, 0x20, 0xf2,
0x03, 0xe3, 0x4b, 0xd8, 0x2f, 0x0b, 0x59, 0x71, 0x55, 0x58, 0xba, 0x66, 0xc9, 0xd6, 0x4f, 0xb4,
0x37, 0x74, 0x67, 0x92, 0x6d, 0xfa, 0x0e, 0x70, 0xfb, 0x3e, 0x44, 0x98, 0xd8, 0x1f, 0x0d, 0xf9,
0x88, 0x3b, 0xe3, 0x01, 0x8c, 0x4d, 0xd5, 0xf8, 0x05, 0xb4, 0xc7, 0xb3, 0xcf, 0x00, 0xe2, 0xea,
0x72, 0x4e, 0x7a, 0xcd, 0x25, 0xe1, 0x07, 0x08, 0xbb, 0xd7, 0x8f, 0x4f, 0x1f, 0x54, 0x37, 0xbf,
0xe1, 0x67, 0x47, 0x5b, 0xfd, 0x6e, 0xd6, 0xe3, 0xe0, 0x24, 0xb8, 0x38, 0xfd, 0x32, 0xad, 0xd9,
0x7e, 0xbd, 0xbf, 0xc9, 0x4a, 0xb5, 0x9a, 0x7a, 0xb0, 0x7f, 0xbe, 0x35, 0xa4, 0xd7, 0xa4, 0xa7,
0xee, 0x37, 0xe9, 0x9b, 0x37, 0xa1, 0x2b, 0xcf, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xa9, 0x3d,
0xb9, 0xb1, 0x42, 0x03, 0x00, 0x00,
// 403 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x93, 0x4f, 0x6f, 0xd3, 0x40,
0x10, 0xc5, 0x63, 0x92, 0xda, 0xf2, 0x94, 0x56, 0xd5, 0xa8, 0x50, 0x0b, 0x2e, 0xc8, 0x12, 0x52,
0xc5, 0x1f, 0xa7, 0x7f, 0x6e, 0x20, 0x2e, 0x2d, 0x87, 0x04, 0x6e, 0x9b, 0x9e, 0xb8, 0x54, 0xae,
0x3d, 0x31, 0x43, 0x92, 0x5d, 0xb3, 0xbb, 0x09, 0xe2, 0x1b, 0xf0, 0x75, 0x10, 0x5f, 0x10, 0x79,
0xbd, 0x4e, 0x02, 0x91, 0xe0, 0xd8, 0x93, 0x77, 0x46, 0xbf, 0xb7, 0x7a, 0xef, 0x69, 0x0d, 0xb1,
0xb6, 0x45, 0x56, 0x6b, 0x65, 0x15, 0x46, 0x73, 0x5e, 0xd1, 0x8c, 0x6d, 0xfa, 0x33, 0x80, 0x83,
0x09, 0x57, 0x32, 0x9f, 0x0b, 0xfa, 0xba, 0x24, 0x63, 0xf1, 0x05, 0x0c, 0xbe, 0x28, 0x96, 0x49,
0xf0, 0x2c, 0x38, 0xdd, 0xbf, 0x38, 0xce, 0x3c, 0x99, 0x7d, 0x50, 0x2c, 0x3d, 0x33, 0xea, 0x09,
0xc7, 0xe0, 0x5b, 0x88, 0x25, 0x55, 0xca, 0x72, 0x6e, 0x29, 0x79, 0xe0, 0x04, 0x4f, 0xd7, 0x82,
0x09, 0x19, 0xc3, 0x4a, 0xbe, 0x27, 0x53, 0x68, 0xae, 0x2d, 0x2b, 0x39, 0xea, 0x89, 0x0d, 0x8f,
0xaf, 0x20, 0xb2, 0x9a, 0x8b, 0xd9, 0x9c, 0x92, 0xbe, 0x93, 0x1e, 0xad, 0xa5, 0x37, 0xed, 0x7e,
0xd4, 0x13, 0x1d, 0x72, 0x15, 0x43, 0xb4, 0x20, 0x63, 0xf2, 0x8a, 0xd2, 0x5f, 0x01, 0x1c, 0x76,
0x9e, 0x4d, 0xad, 0xa4, 0x21, 0x7c, 0xf9, 0x87, 0xe9, 0x47, 0x7f, 0x99, 0x6e, 0xa1, 0x7b, 0x76,
0xfd, 0x23, 0x80, 0xfd, 0xad, 0x0e, 0xf1, 0x04, 0x22, 0xad, 0xd4, 0xe2, 0x96, 0x4b, 0xe7, 0x3a,
0x16, 0x61, 0x33, 0x8e, 0x4b, 0x3c, 0x86, 0x3d, 0xab, 0x66, 0x24, 0x9d, 0xb5, 0x58, 0xb4, 0x43,
0x83, 0xd7, 0x44, 0xba, 0xc1, 0xfb, 0x2d, 0xde, 0x8c, 0xe3, 0x12, 0xcf, 0x61, 0x4f, 0x4d, 0xa7,
0xa4, 0x93, 0xc1, 0x7f, 0x93, 0x88, 0x96, 0x4c, 0xaf, 0xe1, 0xe1, 0x76, 0x31, 0x78, 0x09, 0x61,
0x2e, 0xcd, 0x37, 0xd2, 0xbe, 0xbf, 0x7f, 0xde, 0xe1, 0xd1, 0xf4, 0x0c, 0x22, 0x1f, 0x18, 0x9f,
0xc3, 0x61, 0x91, 0xcb, 0x92, 0xcb, 0xdc, 0xd2, 0x2d, 0x4b, 0xb6, 0x3e, 0xd1, 0xc1, 0x7a, 0x3b,
0x96, 0x6c, 0xd3, 0x37, 0x80, 0xbb, 0xf7, 0x21, 0xc2, 0xc0, 0x7e, 0xaf, 0xc9, 0x4b, 0xdc, 0x19,
0x8f, 0xa0, 0x6f, 0xca, 0xda, 0x17, 0xd0, 0x1c, 0x2f, 0x3e, 0x02, 0x88, 0x9b, 0xeb, 0x09, 0xe9,
0x15, 0x17, 0x84, 0xef, 0x20, 0x6c, 0x1f, 0x00, 0x3e, 0xde, 0x58, 0xdd, 0x7e, 0xc5, 0x4f, 0x4e,
0x76, 0xf6, 0x6d, 0xd6, 0xd3, 0xe0, 0x2c, 0xb8, 0x3a, 0xff, 0x34, 0xac, 0xd8, 0x7e, 0x5e, 0xde,
0x65, 0x85, 0x5a, 0x0c, 0x3d, 0xd8, 0x7d, 0x5f, 0x1b, 0xd2, 0x2b, 0xd2, 0x43, 0xf7, 0xa3, 0x74,
0xcb, 0xbb, 0xd0, 0x8d, 0x97, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe8, 0xef, 0x85, 0x44,
0x03, 0x00, 0x00,
}
+1 -1
View File
@@ -18,7 +18,7 @@ message SignalRequest {
message SignalResponse {
oneof message {
JoinResponse jin = 1;
JoinResponse join = 1;
SessionDescription negotiate = 2;
Trickle trickle = 3;
}