decouple websocket and RTC nodes, prep for distributed

This commit is contained in:
David Zhao
2021-01-16 00:25:13 -08:00
parent 9a10a57b30
commit 9064f6ade1
61 changed files with 2683 additions and 1361 deletions

View File

@@ -168,7 +168,7 @@ func (c *RTCClient) Run() error {
c.conn.SetCloseHandler(func(code int, text string) error {
// when closed, stop connection
logger.GetLogger().Infow("connection closed", "code", code, "text", text)
logger.Infow("connection closed", "code", code, "text", text)
c.Stop()
return nil
})
@@ -519,7 +519,7 @@ func (c *RTCClient) logLoop() {
for !c.paused && c.reader != c.writer {
val, _ := c.reader.Value.(*logEntry)
if val != nil {
logger.GetLogger().Infow(val.msg, val.args...)
logger.Infow(val.msg, val.args...)
}
// advance reader until writer
c.reader = c.reader.Next()

View File

@@ -54,7 +54,7 @@ func (w *TrackWriter) Start() error {
return err
}
logger.GetLogger().Infow("starting track writer",
logger.Infow("starting track writer",
"track", w.track.ID(),
"mime", w.mime)
switch w.mime {
@@ -106,13 +106,13 @@ func (w *TrackWriter) writeOgg() {
}
pageData, pageHeader, err := w.ogg.ParseNextPage()
if err == io.EOF {
logger.GetLogger().Infow("all audio samples parsed and sent")
logger.Infow("all audio samples parsed and sent")
w.onWriteComplete()
return
}
if err != nil {
logger.GetLogger().Errorw("could not parse ogg page", "err", err)
logger.Errorw("could not parse ogg page", "err", err)
return
}
@@ -122,7 +122,7 @@ func (w *TrackWriter) writeOgg() {
sampleDuration := time.Duration((sampleCount/48000)*1000) * time.Millisecond
if err = w.track.WriteSample(media.Sample{Data: pageData, Duration: sampleDuration}); err != nil {
logger.GetLogger().Errorw("could not write sample", "err", err)
logger.Errorw("could not write sample", "err", err)
return
}
@@ -140,19 +140,19 @@ func (w *TrackWriter) writeVP8() {
}
frame, _, err := w.ivf.ParseNextFrame()
if err == io.EOF {
logger.GetLogger().Infow("all video frames parsed and sent")
logger.Infow("all video frames parsed and sent")
w.onWriteComplete()
return
}
if err != nil {
logger.GetLogger().Errorw("could not parse VP8 frame", "err", err)
logger.Errorw("could not parse VP8 frame", "err", err)
return
}
time.Sleep(sleepTime)
if err = w.track.WriteSample(media.Sample{Data: frame, Duration: time.Second}); err != nil {
logger.GetLogger().Errorw("could not write sample", "err", err)
logger.Errorw("could not write sample", "err", err)
return
}
}

View File

@@ -31,11 +31,10 @@ var (
},
},
{
Name: "get-room",
Name: "list-rooms",
Before: createClient,
Action: getRoom,
Action: listRooms,
Flags: []cli.Flag{
roomFlag,
roomHostFlag,
apiKeyFlag,
secretFlag,
@@ -76,17 +75,15 @@ func createRoom(c *cli.Context) error {
return nil
}
func getRoom(c *cli.Context) error {
ctx := contextWithAccessToken(c, &auth.VideoGrant{RoomJoin: true})
roomId := c.String("room")
room, err := roomClient.GetRoom(ctx, &livekit.GetRoomRequest{
Room: roomId,
})
func listRooms(c *cli.Context) error {
ctx := contextWithAccessToken(c, &auth.VideoGrant{RoomList: true})
res, err := roomClient.ListRooms(ctx, &livekit.ListRoomsRequest{})
if err != nil {
return err
}
PrintJSON(room)
for _, rm := range res.Rooms {
fmt.Printf("%s\t%s\n", rm.Sid, rm.Name)
}
return nil
}
@@ -108,16 +105,16 @@ func contextWithAccessToken(c *cli.Context, grant *auth.VideoGrant) context.Cont
ctx := context.Background()
token, err := accessToken(c, grant, "")
if err != nil {
logger.GetLogger().Errorw("Could not get access token", "err", err)
logger.Errorw("Could not get access token", "err", err)
}
if token != "" {
header := make(http.Header)
header.Set("Authorization", "Bearer "+token)
if tctx, err := twirp.WithHTTPRequestHeaders(ctx, header); err == nil {
logger.GetLogger().Debugw("requesting with token")
logger.Debugw("requesting with token")
ctx = tctx
} else {
logger.GetLogger().Errorw("Error setting Twirp auth header", "err", err)
logger.Errorw("Error setting Twirp auth header", "err", err)
}
}
return ctx

View File

@@ -74,10 +74,8 @@ func joinRoom(c *cli.Context) error {
}
}
log := logger.GetLogger()
host := c.String("host")
log.Infow("connecting to Websocket signal", "host", host)
logger.Infow("connecting to Websocket signal", "host", host)
conn, err := client.NewWebSocketConn(host, token)
if err != nil {
return err
@@ -118,7 +116,7 @@ func joinRoom(c *cli.Context) error {
err = handleCommand(rc)
if err != nil {
log.Errorw("could not handle command", "err", err)
logger.Errorw("could not handle command", "err", err)
}
rc.ResumeLogs()
@@ -221,7 +219,7 @@ func handleSignals(rc *client.RTCClient) {
go func() {
sig := <-sigChan
logger.GetLogger().Infow("exit requested, shutting down", "signal", sig)
logger.Infow("exit requested, shutting down", "signal", sig)
rc.Stop()
}()
}

View File

@@ -24,7 +24,7 @@ var (
}
rtcHostFlag = &cli.StringFlag{
Name: "host",
Value: "ws://localhost:7881",
Value: "ws://localhost:7880",
}
apiKeyFlag = &cli.StringFlag{
Name: "api-key",

View File

@@ -17,6 +17,7 @@ import (
"github.com/livekit/livekit-server/pkg/auth"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/logger"
"github.com/livekit/livekit-server/pkg/routing"
"github.com/livekit/livekit-server/pkg/service"
"github.com/livekit/livekit-server/pkg/utils"
)
@@ -116,10 +117,19 @@ func startServer(c *cli.Context) error {
if keyProvider, err = createKeyProvider(c.String("key-file"), c.String("keys")); err != nil {
return err
}
service.AuthRequired = true
logger.GetLogger().Infow("auth enabled", "num_keys", keyProvider.NumKeys())
logger.Infow("auth enabled", "num_keys", keyProvider.NumKeys())
server, err := service.InitializeServer(conf, keyProvider)
currentNode, err := routing.NewLocalNode(conf)
if err != nil {
return err
}
// local routing and store
router := routing.NewLocalRouter(currentNode)
roomStore := service.NewLocalRoomStore()
server, err := service.InitializeServer(conf, keyProvider,
roomStore, router, currentNode)
if err != nil {
return err
}
@@ -129,7 +139,7 @@ func startServer(c *cli.Context) error {
go func() {
sig := <-sigChan
logger.GetLogger().Infow("exit requested, shutting down", "signal", sig)
logger.Infow("exit requested, shutting down", "signal", sig)
server.Stop()
}()

2
go.sum
View File

@@ -211,6 +211,7 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -376,6 +377,7 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM=
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=

View File

@@ -14,12 +14,12 @@ import (
"strings"
"github.com/magefile/mage/mg"
"github.com/magefile/mage/target"
log "github.com/pion/ion-log"
)
const (
protoChecksumFile = ".checksumproto"
goChecksumFile = ".checksumgo"
goChecksumFile = ".checksumgo"
)
// Default target to run when none is specified
@@ -41,8 +41,15 @@ func Deps() error {
// regenerate protobuf
func Proto() error {
protoChecksummer := NewChecksummer("proto", protoChecksumFile, ".proto")
if !protoChecksummer.IsChanged() {
updated, err := target.Path("proto/livekit/model.pb.go",
"proto/model.proto",
"proto/room.proto",
"proto/rtc.proto",
)
if err != nil {
return err
}
if !updated {
return nil
}
@@ -92,13 +99,12 @@ func Proto() error {
return err
}
protoChecksummer.WriteChecksum()
return nil
}
// builds LiveKit server and cli
func Build() error {
mg.Deps(Proto, generateCmd)
mg.Deps(Proto, generateWire)
if !checksummer.IsChanged() {
fmt.Println("up to date")
return nil
@@ -137,7 +143,6 @@ func Test() error {
func Clean() {
fmt.Println("cleaning...")
os.RemoveAll("bin")
os.Remove(protoChecksumFile)
os.Remove(goChecksumFile)
}
@@ -152,14 +157,14 @@ func Generate() error {
return cmd.Run()
}
// code generation for cmd subfolder. It doesn't regenerate test fixtures
func generateCmd() error {
// code generation for wiring
func generateWire() error {
mg.Deps(installDeps)
if !checksummer.IsChanged() {
return nil
}
fmt.Println("generating...")
fmt.Println("wiring...")
cmd := exec.Command("go", "generate", "./cmd/...")
connectStd(cmd)
@@ -167,7 +172,12 @@ func generateCmd() error {
return err
}
cmd = exec.Command("go", "generate", "./pkg/service/...")
wire, err := getToolPath("wire")
if err != nil {
return err
}
cmd = exec.Command(wire)
cmd.Dir = "pkg/service"
connectStd(cmd)
if err := cmd.Run(); err != nil {
return err

View File

@@ -3,6 +3,7 @@ package auth
type VideoGrant struct {
RoomCreate bool `json:"room_create,omitempty"`
RoomJoin bool `json:"room_join,omitempty"`
RoomList bool `json:"room_list,omitempty"`
Room string `json:"room,omitempty"`
}

View File

@@ -6,9 +6,8 @@ import (
)
type Config struct {
APIPort uint32 `yaml:"api_port"`
RTCPort uint32 `yaml:"rtc_port"`
RTC RTCConfig `yaml:"rtc"`
Port uint32 `yaml:"port"`
RTC RTCConfig `yaml:"rtc"`
// multi-node configuration,
MultiNode bool `yaml:"multi_node"`
@@ -28,8 +27,7 @@ type RTCConfig struct {
func NewConfig(confString string) (*Config, error) {
// start with defaults
conf := &Config{
APIPort: 7880,
RTCPort: 7881,
Port: 7880,
RTC: RTCConfig{
ICEPortRangeStart: 8000,
ICEPortRangeEnd: 10000,

View File

@@ -4,9 +4,14 @@ import (
"go.uber.org/zap"
)
var logger *zap.SugaredLogger
var (
logger *zap.SugaredLogger
zapOptions = []zap.Option{
zap.AddCallerSkip(1),
}
)
func GetLogger() *zap.SugaredLogger {
func getLogger() *zap.SugaredLogger {
if logger == nil {
InitDevelopment()
}
@@ -14,11 +19,31 @@ func GetLogger() *zap.SugaredLogger {
}
func InitProduction() {
l, _ := zap.NewProduction()
l, _ := zap.NewProduction(zapOptions...)
logger = l.Sugar()
}
func InitDevelopment() {
l, _ := zap.NewDevelopment()
l, _ := zap.NewDevelopment(zapOptions...)
logger = l.Sugar()
}
func Debugw(msg string, keysAndValues ...interface{}) {
getLogger().Debugw(msg, keysAndValues...)
}
func Infow(msg string, keysAndValues ...interface{}) {
getLogger().Infow(msg, keysAndValues...)
}
func Warnw(msg string, keysAndValues ...interface{}) {
getLogger().Warnw(msg, keysAndValues...)
}
func Errorw(msg string, keysAndValues ...interface{}) {
getLogger().Errorw(msg, keysAndValues...)
}
func Desugar() *zap.Logger {
return getLogger().Desugar()
}

8
pkg/routing/errors.go Normal file
View File

@@ -0,0 +1,8 @@
package routing
import "errors"
var (
ErrNodeNotFound = errors.New("could not find node")
ErrHandlerNotDefined = errors.New("handler not defined")
)

38
pkg/routing/interfaces.go Normal file
View File

@@ -0,0 +1,38 @@
package routing
import (
"github.com/livekit/livekit-server/proto/livekit"
)
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
// routes signaling message
//counterfeiter:generate . MessageSink
type MessageSink interface {
WriteMessage(msg interface{}) error
Close()
}
//counterfeiter:generate . MessageSource
type MessageSource interface {
ReadMessage() (interface{}, error)
}
type ParticipantCallback func(roomId, participantId, participantName string, requestSource MessageSource, responseSink MessageSink)
//counterfeiter:generate . Router
type Router interface {
GetNodeIdForRoom(roomName string) (string, error)
RegisterNode(node *livekit.Node) error
GetNode(nodeId string) (*livekit.Node, error)
StartParticipant(roomName, participantId, participantName, nodeId string) error
SetRTCNode(participantId, nodeId string) error
// functions for websocket handler
GetRequestSink(participantId string) MessageSink
GetResponseSource(participantId string) MessageSource
OnNewParticipant(callback ParticipantCallback)
Start() error
Stop()
}

View File

@@ -0,0 +1,99 @@
package routing
import (
"sync"
"github.com/livekit/livekit-server/proto/livekit"
)
// a router of messages
type LocalRouter struct {
currentNode LocalNode
lock sync.RWMutex
// channels for each participant
requestChannels map[string]*MessageChannel
responseChannels map[string]*MessageChannel
onNewParticipant ParticipantCallback
}
func NewLocalRouter(currentNode LocalNode) *LocalRouter {
return &LocalRouter{
currentNode: currentNode,
lock: sync.RWMutex{},
requestChannels: make(map[string]*MessageChannel),
responseChannels: make(map[string]*MessageChannel),
}
}
func (r *LocalRouter) GetNodeIdForRoom(roomName string) (string, error) {
return r.currentNode.Id, nil
}
func (r *LocalRouter) RegisterNode(node *livekit.Node) error {
return nil
}
func (r *LocalRouter) GetNode(nodeId string) (*livekit.Node, error) {
if nodeId == r.currentNode.Id {
return r.currentNode, nil
}
return nil, ErrNodeNotFound
}
func (r *LocalRouter) StartParticipant(roomName, participantId, participantName, nodeId string) error {
// treat it as a new participant connecting
if r.onNewParticipant == nil {
return ErrHandlerNotDefined
}
r.onNewParticipant(
roomName,
participantId,
participantName,
r.getOrCreateMessageChannel(r.requestChannels, participantId),
r.getOrCreateMessageChannel(r.responseChannels, participantId),
)
return nil
}
func (r *LocalRouter) SetRTCNode(participantId, nodeId string) error {
// nothing to be done
return nil
}
// for a local router, sink and source are pointing to the same spot
func (r *LocalRouter) GetRequestSink(participantId string) MessageSink {
return r.getOrCreateMessageChannel(r.requestChannels, participantId)
}
func (r *LocalRouter) GetResponseSource(participantId string) MessageSource {
return r.getOrCreateMessageChannel(r.responseChannels, participantId)
}
func (r *LocalRouter) OnNewParticipant(callback ParticipantCallback) {
r.onNewParticipant = callback
}
func (r *LocalRouter) Start() error {
// on local routers, Start doesn't do anything, websocket connections initiate the connections
return nil
}
func (r *LocalRouter) Stop() {
}
func (r *LocalRouter) getOrCreateMessageChannel(target map[string]*MessageChannel, participantId string) *MessageChannel {
r.lock.RLock()
mc := target[participantId]
r.lock.RUnlock()
if mc != nil {
return mc
}
mc = NewMessageChannel()
r.lock.Lock()
target[participantId] = mc
r.lock.Unlock()
return mc
}

View File

@@ -0,0 +1,33 @@
package routing
import (
"io"
)
type MessageChannel struct {
msgChan chan interface{}
}
func NewMessageChannel() *MessageChannel {
return &MessageChannel{
msgChan: make(chan interface{}, 1),
}
}
func (m *MessageChannel) WriteMessage(msg interface{}) error {
m.msgChan <- msg
return nil
}
func (m *MessageChannel) ReadMessage() (interface{}, error) {
msg := <-m.msgChan
// channel closed
if msg == nil {
return nil, io.EOF
}
return msg, nil
}
func (m *MessageChannel) Close() {
close(m.msgChan)
}

View File

@@ -1,11 +1,11 @@
package node
package routing
import (
"context"
"fmt"
"runtime"
"time"
"github.com/google/wire"
"github.com/pion/stun"
"github.com/pkg/errors"
@@ -14,13 +14,6 @@ import (
"github.com/livekit/livekit-server/proto/livekit"
)
var NodeSet = wire.NewSet(NewLocalNode)
type Node struct {
livekit.Node
config *config.Config
}
type NodeStats struct {
NumRooms int32
NumClients int32
@@ -29,36 +22,37 @@ type NodeStats struct {
BytesPerMin int64
}
func NewLocalNode(conf *config.Config) (*Node, error) {
n := &Node{
Node: livekit.Node{
Id: utils.NewGuid(utils.NodePrefix),
RtcPort: conf.RTCPort,
},
config: conf,
}
if err := n.DiscoverNetworkInfo(); err != nil {
type LocalNode *livekit.Node
func NewLocalNode(conf *config.Config) (LocalNode, error) {
ip, err := GetLocalIP(conf.RTC.StunServers)
if err != nil {
return nil, err
}
return n, nil
return &livekit.Node{
Id: utils.NewGuid(utils.NodePrefix),
Ip: ip,
NumCpus: uint32(runtime.NumCPU()),
}, nil
}
func (n *Node) DiscoverNetworkInfo() error {
if len(n.config.RTC.StunServers) == 0 {
return errors.New("STUN servers are required but not defined")
func GetLocalIP(stunServers []string) (string, error) {
if len(stunServers) == 0 {
return "", errors.New("STUN servers are required but not defined")
}
c, err := stun.Dial("udp4", n.config.RTC.StunServers[0])
c, err := stun.Dial("udp4", stunServers[0])
if err != nil {
return err
return "", err
}
defer c.Close()
message, err := stun.Build(stun.TransactionID, stun.BindingRequest)
if err != nil {
return err
return "", err
}
var stunErr error
var nodeIp string
err = c.Start(message, func(res stun.Event) {
if res.Error != nil {
stunErr = res.Error
@@ -72,28 +66,28 @@ func (n *Node) DiscoverNetworkInfo() error {
}
ip := xorAddr.IP.To4()
if ip != nil {
n.Ip = ip.String()
nodeIp = ip.String()
}
})
if err != nil {
return err
return "", err
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
for n.Ip == "" {
for nodeIp == "" {
select {
case <-ctx.Done():
msg := "could not determine public IP"
if stunErr != nil {
return errors.Wrap(stunErr, msg)
return "", errors.Wrap(stunErr, msg)
} else {
return fmt.Errorf(msg)
return "", fmt.Errorf(msg)
}
case <-time.After(100 * time.Millisecond):
continue
}
}
return nil
return nodeIp, nil
}

View File

@@ -0,0 +1,141 @@
// Code generated by counterfeiter. DO NOT EDIT.
package routingfakes
import (
"sync"
"github.com/livekit/livekit-server/pkg/routing"
)
type FakeMessageSink struct {
CloseStub func()
closeMutex sync.RWMutex
closeArgsForCall []struct {
}
WriteMessageStub func(interface{}) error
writeMessageMutex sync.RWMutex
writeMessageArgsForCall []struct {
arg1 interface{}
}
writeMessageReturns struct {
result1 error
}
writeMessageReturnsOnCall map[int]struct {
result1 error
}
invocations map[string][][]interface{}
invocationsMutex sync.RWMutex
}
func (fake *FakeMessageSink) Close() {
fake.closeMutex.Lock()
fake.closeArgsForCall = append(fake.closeArgsForCall, struct {
}{})
stub := fake.CloseStub
fake.recordInvocation("Close", []interface{}{})
fake.closeMutex.Unlock()
if stub != nil {
fake.CloseStub()
}
}
func (fake *FakeMessageSink) CloseCallCount() int {
fake.closeMutex.RLock()
defer fake.closeMutex.RUnlock()
return len(fake.closeArgsForCall)
}
func (fake *FakeMessageSink) CloseCalls(stub func()) {
fake.closeMutex.Lock()
defer fake.closeMutex.Unlock()
fake.CloseStub = stub
}
func (fake *FakeMessageSink) WriteMessage(arg1 interface{}) error {
fake.writeMessageMutex.Lock()
ret, specificReturn := fake.writeMessageReturnsOnCall[len(fake.writeMessageArgsForCall)]
fake.writeMessageArgsForCall = append(fake.writeMessageArgsForCall, struct {
arg1 interface{}
}{arg1})
stub := fake.WriteMessageStub
fakeReturns := fake.writeMessageReturns
fake.recordInvocation("WriteMessage", []interface{}{arg1})
fake.writeMessageMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeMessageSink) WriteMessageCallCount() int {
fake.writeMessageMutex.RLock()
defer fake.writeMessageMutex.RUnlock()
return len(fake.writeMessageArgsForCall)
}
func (fake *FakeMessageSink) WriteMessageCalls(stub func(interface{}) error) {
fake.writeMessageMutex.Lock()
defer fake.writeMessageMutex.Unlock()
fake.WriteMessageStub = stub
}
func (fake *FakeMessageSink) WriteMessageArgsForCall(i int) interface{} {
fake.writeMessageMutex.RLock()
defer fake.writeMessageMutex.RUnlock()
argsForCall := fake.writeMessageArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeMessageSink) WriteMessageReturns(result1 error) {
fake.writeMessageMutex.Lock()
defer fake.writeMessageMutex.Unlock()
fake.WriteMessageStub = nil
fake.writeMessageReturns = struct {
result1 error
}{result1}
}
func (fake *FakeMessageSink) WriteMessageReturnsOnCall(i int, result1 error) {
fake.writeMessageMutex.Lock()
defer fake.writeMessageMutex.Unlock()
fake.WriteMessageStub = nil
if fake.writeMessageReturnsOnCall == nil {
fake.writeMessageReturnsOnCall = make(map[int]struct {
result1 error
})
}
fake.writeMessageReturnsOnCall[i] = struct {
result1 error
}{result1}
}
func (fake *FakeMessageSink) Invocations() map[string][][]interface{} {
fake.invocationsMutex.RLock()
defer fake.invocationsMutex.RUnlock()
fake.closeMutex.RLock()
defer fake.closeMutex.RUnlock()
fake.writeMessageMutex.RLock()
defer fake.writeMessageMutex.RUnlock()
copiedInvocations := map[string][][]interface{}{}
for key, value := range fake.invocations {
copiedInvocations[key] = value
}
return copiedInvocations
}
func (fake *FakeMessageSink) recordInvocation(key string, args []interface{}) {
fake.invocationsMutex.Lock()
defer fake.invocationsMutex.Unlock()
if fake.invocations == nil {
fake.invocations = map[string][][]interface{}{}
}
if fake.invocations[key] == nil {
fake.invocations[key] = [][]interface{}{}
}
fake.invocations[key] = append(fake.invocations[key], args)
}
var _ routing.MessageSink = new(FakeMessageSink)

View File

@@ -0,0 +1,107 @@
// Code generated by counterfeiter. DO NOT EDIT.
package routingfakes
import (
"sync"
"github.com/livekit/livekit-server/pkg/routing"
)
type FakeMessageSource struct {
ReadMessageStub func() (interface{}, error)
readMessageMutex sync.RWMutex
readMessageArgsForCall []struct {
}
readMessageReturns struct {
result1 interface{}
result2 error
}
readMessageReturnsOnCall map[int]struct {
result1 interface{}
result2 error
}
invocations map[string][][]interface{}
invocationsMutex sync.RWMutex
}
func (fake *FakeMessageSource) ReadMessage() (interface{}, error) {
fake.readMessageMutex.Lock()
ret, specificReturn := fake.readMessageReturnsOnCall[len(fake.readMessageArgsForCall)]
fake.readMessageArgsForCall = append(fake.readMessageArgsForCall, struct {
}{})
stub := fake.ReadMessageStub
fakeReturns := fake.readMessageReturns
fake.recordInvocation("ReadMessage", []interface{}{})
fake.readMessageMutex.Unlock()
if stub != nil {
return stub()
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeMessageSource) ReadMessageCallCount() int {
fake.readMessageMutex.RLock()
defer fake.readMessageMutex.RUnlock()
return len(fake.readMessageArgsForCall)
}
func (fake *FakeMessageSource) ReadMessageCalls(stub func() (interface{}, error)) {
fake.readMessageMutex.Lock()
defer fake.readMessageMutex.Unlock()
fake.ReadMessageStub = stub
}
func (fake *FakeMessageSource) ReadMessageReturns(result1 interface{}, result2 error) {
fake.readMessageMutex.Lock()
defer fake.readMessageMutex.Unlock()
fake.ReadMessageStub = nil
fake.readMessageReturns = struct {
result1 interface{}
result2 error
}{result1, result2}
}
func (fake *FakeMessageSource) ReadMessageReturnsOnCall(i int, result1 interface{}, result2 error) {
fake.readMessageMutex.Lock()
defer fake.readMessageMutex.Unlock()
fake.ReadMessageStub = nil
if fake.readMessageReturnsOnCall == nil {
fake.readMessageReturnsOnCall = make(map[int]struct {
result1 interface{}
result2 error
})
}
fake.readMessageReturnsOnCall[i] = struct {
result1 interface{}
result2 error
}{result1, result2}
}
func (fake *FakeMessageSource) Invocations() map[string][][]interface{} {
fake.invocationsMutex.RLock()
defer fake.invocationsMutex.RUnlock()
fake.readMessageMutex.RLock()
defer fake.readMessageMutex.RUnlock()
copiedInvocations := map[string][][]interface{}{}
for key, value := range fake.invocations {
copiedInvocations[key] = value
}
return copiedInvocations
}
func (fake *FakeMessageSource) recordInvocation(key string, args []interface{}) {
fake.invocationsMutex.Lock()
defer fake.invocationsMutex.Unlock()
if fake.invocations == nil {
fake.invocations = map[string][][]interface{}{}
}
if fake.invocations[key] == nil {
fake.invocations[key] = [][]interface{}{}
}
fake.invocations[key] = append(fake.invocations[key], args)
}
var _ routing.MessageSource = new(FakeMessageSource)

View File

@@ -0,0 +1,708 @@
// Code generated by counterfeiter. DO NOT EDIT.
package routingfakes
import (
"sync"
"github.com/livekit/livekit-server/pkg/routing"
"github.com/livekit/livekit-server/proto/livekit"
)
type FakeRouter struct {
GetNodeStub func(string) (*livekit.Node, error)
getNodeMutex sync.RWMutex
getNodeArgsForCall []struct {
arg1 string
}
getNodeReturns struct {
result1 *livekit.Node
result2 error
}
getNodeReturnsOnCall map[int]struct {
result1 *livekit.Node
result2 error
}
GetNodeIdForRoomStub func(string) (string, error)
getNodeIdForRoomMutex sync.RWMutex
getNodeIdForRoomArgsForCall []struct {
arg1 string
}
getNodeIdForRoomReturns struct {
result1 string
result2 error
}
getNodeIdForRoomReturnsOnCall map[int]struct {
result1 string
result2 error
}
GetRequestSinkStub func(string) routing.MessageSink
getRequestSinkMutex sync.RWMutex
getRequestSinkArgsForCall []struct {
arg1 string
}
getRequestSinkReturns struct {
result1 routing.MessageSink
}
getRequestSinkReturnsOnCall map[int]struct {
result1 routing.MessageSink
}
GetResponseSourceStub func(string) routing.MessageSource
getResponseSourceMutex sync.RWMutex
getResponseSourceArgsForCall []struct {
arg1 string
}
getResponseSourceReturns struct {
result1 routing.MessageSource
}
getResponseSourceReturnsOnCall map[int]struct {
result1 routing.MessageSource
}
OnNewParticipantStub func(routing.ParticipantCallback)
onNewParticipantMutex sync.RWMutex
onNewParticipantArgsForCall []struct {
arg1 routing.ParticipantCallback
}
RegisterNodeStub func(*livekit.Node) error
registerNodeMutex sync.RWMutex
registerNodeArgsForCall []struct {
arg1 *livekit.Node
}
registerNodeReturns struct {
result1 error
}
registerNodeReturnsOnCall map[int]struct {
result1 error
}
SetRTCNodeStub func(string, string) error
setRTCNodeMutex sync.RWMutex
setRTCNodeArgsForCall []struct {
arg1 string
arg2 string
}
setRTCNodeReturns struct {
result1 error
}
setRTCNodeReturnsOnCall map[int]struct {
result1 error
}
StartStub func() error
startMutex sync.RWMutex
startArgsForCall []struct {
}
startReturns struct {
result1 error
}
startReturnsOnCall map[int]struct {
result1 error
}
StartParticipantStub func(string, string, string, string) error
startParticipantMutex sync.RWMutex
startParticipantArgsForCall []struct {
arg1 string
arg2 string
arg3 string
arg4 string
}
startParticipantReturns struct {
result1 error
}
startParticipantReturnsOnCall map[int]struct {
result1 error
}
StopStub func()
stopMutex sync.RWMutex
stopArgsForCall []struct {
}
invocations map[string][][]interface{}
invocationsMutex sync.RWMutex
}
func (fake *FakeRouter) GetNode(arg1 string) (*livekit.Node, error) {
fake.getNodeMutex.Lock()
ret, specificReturn := fake.getNodeReturnsOnCall[len(fake.getNodeArgsForCall)]
fake.getNodeArgsForCall = append(fake.getNodeArgsForCall, struct {
arg1 string
}{arg1})
stub := fake.GetNodeStub
fakeReturns := fake.getNodeReturns
fake.recordInvocation("GetNode", []interface{}{arg1})
fake.getNodeMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeRouter) GetNodeCallCount() int {
fake.getNodeMutex.RLock()
defer fake.getNodeMutex.RUnlock()
return len(fake.getNodeArgsForCall)
}
func (fake *FakeRouter) GetNodeCalls(stub func(string) (*livekit.Node, error)) {
fake.getNodeMutex.Lock()
defer fake.getNodeMutex.Unlock()
fake.GetNodeStub = stub
}
func (fake *FakeRouter) GetNodeArgsForCall(i int) string {
fake.getNodeMutex.RLock()
defer fake.getNodeMutex.RUnlock()
argsForCall := fake.getNodeArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRouter) GetNodeReturns(result1 *livekit.Node, result2 error) {
fake.getNodeMutex.Lock()
defer fake.getNodeMutex.Unlock()
fake.GetNodeStub = nil
fake.getNodeReturns = struct {
result1 *livekit.Node
result2 error
}{result1, result2}
}
func (fake *FakeRouter) GetNodeReturnsOnCall(i int, result1 *livekit.Node, result2 error) {
fake.getNodeMutex.Lock()
defer fake.getNodeMutex.Unlock()
fake.GetNodeStub = nil
if fake.getNodeReturnsOnCall == nil {
fake.getNodeReturnsOnCall = make(map[int]struct {
result1 *livekit.Node
result2 error
})
}
fake.getNodeReturnsOnCall[i] = struct {
result1 *livekit.Node
result2 error
}{result1, result2}
}
func (fake *FakeRouter) GetNodeIdForRoom(arg1 string) (string, error) {
fake.getNodeIdForRoomMutex.Lock()
ret, specificReturn := fake.getNodeIdForRoomReturnsOnCall[len(fake.getNodeIdForRoomArgsForCall)]
fake.getNodeIdForRoomArgsForCall = append(fake.getNodeIdForRoomArgsForCall, struct {
arg1 string
}{arg1})
stub := fake.GetNodeIdForRoomStub
fakeReturns := fake.getNodeIdForRoomReturns
fake.recordInvocation("GetNodeIdForRoom", []interface{}{arg1})
fake.getNodeIdForRoomMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeRouter) GetNodeIdForRoomCallCount() int {
fake.getNodeIdForRoomMutex.RLock()
defer fake.getNodeIdForRoomMutex.RUnlock()
return len(fake.getNodeIdForRoomArgsForCall)
}
func (fake *FakeRouter) GetNodeIdForRoomCalls(stub func(string) (string, error)) {
fake.getNodeIdForRoomMutex.Lock()
defer fake.getNodeIdForRoomMutex.Unlock()
fake.GetNodeIdForRoomStub = stub
}
func (fake *FakeRouter) GetNodeIdForRoomArgsForCall(i int) string {
fake.getNodeIdForRoomMutex.RLock()
defer fake.getNodeIdForRoomMutex.RUnlock()
argsForCall := fake.getNodeIdForRoomArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRouter) GetNodeIdForRoomReturns(result1 string, result2 error) {
fake.getNodeIdForRoomMutex.Lock()
defer fake.getNodeIdForRoomMutex.Unlock()
fake.GetNodeIdForRoomStub = nil
fake.getNodeIdForRoomReturns = struct {
result1 string
result2 error
}{result1, result2}
}
func (fake *FakeRouter) GetNodeIdForRoomReturnsOnCall(i int, result1 string, result2 error) {
fake.getNodeIdForRoomMutex.Lock()
defer fake.getNodeIdForRoomMutex.Unlock()
fake.GetNodeIdForRoomStub = nil
if fake.getNodeIdForRoomReturnsOnCall == nil {
fake.getNodeIdForRoomReturnsOnCall = make(map[int]struct {
result1 string
result2 error
})
}
fake.getNodeIdForRoomReturnsOnCall[i] = struct {
result1 string
result2 error
}{result1, result2}
}
func (fake *FakeRouter) GetRequestSink(arg1 string) routing.MessageSink {
fake.getRequestSinkMutex.Lock()
ret, specificReturn := fake.getRequestSinkReturnsOnCall[len(fake.getRequestSinkArgsForCall)]
fake.getRequestSinkArgsForCall = append(fake.getRequestSinkArgsForCall, struct {
arg1 string
}{arg1})
stub := fake.GetRequestSinkStub
fakeReturns := fake.getRequestSinkReturns
fake.recordInvocation("GetRequestSink", []interface{}{arg1})
fake.getRequestSinkMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeRouter) GetRequestSinkCallCount() int {
fake.getRequestSinkMutex.RLock()
defer fake.getRequestSinkMutex.RUnlock()
return len(fake.getRequestSinkArgsForCall)
}
func (fake *FakeRouter) GetRequestSinkCalls(stub func(string) routing.MessageSink) {
fake.getRequestSinkMutex.Lock()
defer fake.getRequestSinkMutex.Unlock()
fake.GetRequestSinkStub = stub
}
func (fake *FakeRouter) GetRequestSinkArgsForCall(i int) string {
fake.getRequestSinkMutex.RLock()
defer fake.getRequestSinkMutex.RUnlock()
argsForCall := fake.getRequestSinkArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRouter) GetRequestSinkReturns(result1 routing.MessageSink) {
fake.getRequestSinkMutex.Lock()
defer fake.getRequestSinkMutex.Unlock()
fake.GetRequestSinkStub = nil
fake.getRequestSinkReturns = struct {
result1 routing.MessageSink
}{result1}
}
func (fake *FakeRouter) GetRequestSinkReturnsOnCall(i int, result1 routing.MessageSink) {
fake.getRequestSinkMutex.Lock()
defer fake.getRequestSinkMutex.Unlock()
fake.GetRequestSinkStub = nil
if fake.getRequestSinkReturnsOnCall == nil {
fake.getRequestSinkReturnsOnCall = make(map[int]struct {
result1 routing.MessageSink
})
}
fake.getRequestSinkReturnsOnCall[i] = struct {
result1 routing.MessageSink
}{result1}
}
func (fake *FakeRouter) GetResponseSource(arg1 string) routing.MessageSource {
fake.getResponseSourceMutex.Lock()
ret, specificReturn := fake.getResponseSourceReturnsOnCall[len(fake.getResponseSourceArgsForCall)]
fake.getResponseSourceArgsForCall = append(fake.getResponseSourceArgsForCall, struct {
arg1 string
}{arg1})
stub := fake.GetResponseSourceStub
fakeReturns := fake.getResponseSourceReturns
fake.recordInvocation("GetResponseSource", []interface{}{arg1})
fake.getResponseSourceMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeRouter) GetResponseSourceCallCount() int {
fake.getResponseSourceMutex.RLock()
defer fake.getResponseSourceMutex.RUnlock()
return len(fake.getResponseSourceArgsForCall)
}
func (fake *FakeRouter) GetResponseSourceCalls(stub func(string) routing.MessageSource) {
fake.getResponseSourceMutex.Lock()
defer fake.getResponseSourceMutex.Unlock()
fake.GetResponseSourceStub = stub
}
func (fake *FakeRouter) GetResponseSourceArgsForCall(i int) string {
fake.getResponseSourceMutex.RLock()
defer fake.getResponseSourceMutex.RUnlock()
argsForCall := fake.getResponseSourceArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRouter) GetResponseSourceReturns(result1 routing.MessageSource) {
fake.getResponseSourceMutex.Lock()
defer fake.getResponseSourceMutex.Unlock()
fake.GetResponseSourceStub = nil
fake.getResponseSourceReturns = struct {
result1 routing.MessageSource
}{result1}
}
func (fake *FakeRouter) GetResponseSourceReturnsOnCall(i int, result1 routing.MessageSource) {
fake.getResponseSourceMutex.Lock()
defer fake.getResponseSourceMutex.Unlock()
fake.GetResponseSourceStub = nil
if fake.getResponseSourceReturnsOnCall == nil {
fake.getResponseSourceReturnsOnCall = make(map[int]struct {
result1 routing.MessageSource
})
}
fake.getResponseSourceReturnsOnCall[i] = struct {
result1 routing.MessageSource
}{result1}
}
func (fake *FakeRouter) OnNewParticipant(arg1 routing.ParticipantCallback) {
fake.onNewParticipantMutex.Lock()
fake.onNewParticipantArgsForCall = append(fake.onNewParticipantArgsForCall, struct {
arg1 routing.ParticipantCallback
}{arg1})
stub := fake.OnNewParticipantStub
fake.recordInvocation("OnNewParticipant", []interface{}{arg1})
fake.onNewParticipantMutex.Unlock()
if stub != nil {
fake.OnNewParticipantStub(arg1)
}
}
func (fake *FakeRouter) OnNewParticipantCallCount() int {
fake.onNewParticipantMutex.RLock()
defer fake.onNewParticipantMutex.RUnlock()
return len(fake.onNewParticipantArgsForCall)
}
func (fake *FakeRouter) OnNewParticipantCalls(stub func(routing.ParticipantCallback)) {
fake.onNewParticipantMutex.Lock()
defer fake.onNewParticipantMutex.Unlock()
fake.OnNewParticipantStub = stub
}
func (fake *FakeRouter) OnNewParticipantArgsForCall(i int) routing.ParticipantCallback {
fake.onNewParticipantMutex.RLock()
defer fake.onNewParticipantMutex.RUnlock()
argsForCall := fake.onNewParticipantArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRouter) RegisterNode(arg1 *livekit.Node) error {
fake.registerNodeMutex.Lock()
ret, specificReturn := fake.registerNodeReturnsOnCall[len(fake.registerNodeArgsForCall)]
fake.registerNodeArgsForCall = append(fake.registerNodeArgsForCall, struct {
arg1 *livekit.Node
}{arg1})
stub := fake.RegisterNodeStub
fakeReturns := fake.registerNodeReturns
fake.recordInvocation("RegisterNode", []interface{}{arg1})
fake.registerNodeMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeRouter) RegisterNodeCallCount() int {
fake.registerNodeMutex.RLock()
defer fake.registerNodeMutex.RUnlock()
return len(fake.registerNodeArgsForCall)
}
func (fake *FakeRouter) RegisterNodeCalls(stub func(*livekit.Node) error) {
fake.registerNodeMutex.Lock()
defer fake.registerNodeMutex.Unlock()
fake.RegisterNodeStub = stub
}
func (fake *FakeRouter) RegisterNodeArgsForCall(i int) *livekit.Node {
fake.registerNodeMutex.RLock()
defer fake.registerNodeMutex.RUnlock()
argsForCall := fake.registerNodeArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRouter) RegisterNodeReturns(result1 error) {
fake.registerNodeMutex.Lock()
defer fake.registerNodeMutex.Unlock()
fake.RegisterNodeStub = nil
fake.registerNodeReturns = struct {
result1 error
}{result1}
}
func (fake *FakeRouter) RegisterNodeReturnsOnCall(i int, result1 error) {
fake.registerNodeMutex.Lock()
defer fake.registerNodeMutex.Unlock()
fake.RegisterNodeStub = nil
if fake.registerNodeReturnsOnCall == nil {
fake.registerNodeReturnsOnCall = make(map[int]struct {
result1 error
})
}
fake.registerNodeReturnsOnCall[i] = struct {
result1 error
}{result1}
}
func (fake *FakeRouter) SetRTCNode(arg1 string, arg2 string) error {
fake.setRTCNodeMutex.Lock()
ret, specificReturn := fake.setRTCNodeReturnsOnCall[len(fake.setRTCNodeArgsForCall)]
fake.setRTCNodeArgsForCall = append(fake.setRTCNodeArgsForCall, struct {
arg1 string
arg2 string
}{arg1, arg2})
stub := fake.SetRTCNodeStub
fakeReturns := fake.setRTCNodeReturns
fake.recordInvocation("SetRTCNode", []interface{}{arg1, arg2})
fake.setRTCNodeMutex.Unlock()
if stub != nil {
return stub(arg1, arg2)
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeRouter) SetRTCNodeCallCount() int {
fake.setRTCNodeMutex.RLock()
defer fake.setRTCNodeMutex.RUnlock()
return len(fake.setRTCNodeArgsForCall)
}
func (fake *FakeRouter) SetRTCNodeCalls(stub func(string, string) error) {
fake.setRTCNodeMutex.Lock()
defer fake.setRTCNodeMutex.Unlock()
fake.SetRTCNodeStub = stub
}
func (fake *FakeRouter) SetRTCNodeArgsForCall(i int) (string, string) {
fake.setRTCNodeMutex.RLock()
defer fake.setRTCNodeMutex.RUnlock()
argsForCall := fake.setRTCNodeArgsForCall[i]
return argsForCall.arg1, argsForCall.arg2
}
func (fake *FakeRouter) SetRTCNodeReturns(result1 error) {
fake.setRTCNodeMutex.Lock()
defer fake.setRTCNodeMutex.Unlock()
fake.SetRTCNodeStub = nil
fake.setRTCNodeReturns = struct {
result1 error
}{result1}
}
func (fake *FakeRouter) SetRTCNodeReturnsOnCall(i int, result1 error) {
fake.setRTCNodeMutex.Lock()
defer fake.setRTCNodeMutex.Unlock()
fake.SetRTCNodeStub = nil
if fake.setRTCNodeReturnsOnCall == nil {
fake.setRTCNodeReturnsOnCall = make(map[int]struct {
result1 error
})
}
fake.setRTCNodeReturnsOnCall[i] = struct {
result1 error
}{result1}
}
func (fake *FakeRouter) Start() error {
fake.startMutex.Lock()
ret, specificReturn := fake.startReturnsOnCall[len(fake.startArgsForCall)]
fake.startArgsForCall = append(fake.startArgsForCall, struct {
}{})
stub := fake.StartStub
fakeReturns := fake.startReturns
fake.recordInvocation("Start", []interface{}{})
fake.startMutex.Unlock()
if stub != nil {
return stub()
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeRouter) StartCallCount() int {
fake.startMutex.RLock()
defer fake.startMutex.RUnlock()
return len(fake.startArgsForCall)
}
func (fake *FakeRouter) StartCalls(stub func() error) {
fake.startMutex.Lock()
defer fake.startMutex.Unlock()
fake.StartStub = stub
}
func (fake *FakeRouter) StartReturns(result1 error) {
fake.startMutex.Lock()
defer fake.startMutex.Unlock()
fake.StartStub = nil
fake.startReturns = struct {
result1 error
}{result1}
}
func (fake *FakeRouter) StartReturnsOnCall(i int, result1 error) {
fake.startMutex.Lock()
defer fake.startMutex.Unlock()
fake.StartStub = nil
if fake.startReturnsOnCall == nil {
fake.startReturnsOnCall = make(map[int]struct {
result1 error
})
}
fake.startReturnsOnCall[i] = struct {
result1 error
}{result1}
}
func (fake *FakeRouter) StartParticipant(arg1 string, arg2 string, arg3 string, arg4 string) error {
fake.startParticipantMutex.Lock()
ret, specificReturn := fake.startParticipantReturnsOnCall[len(fake.startParticipantArgsForCall)]
fake.startParticipantArgsForCall = append(fake.startParticipantArgsForCall, struct {
arg1 string
arg2 string
arg3 string
arg4 string
}{arg1, arg2, arg3, arg4})
stub := fake.StartParticipantStub
fakeReturns := fake.startParticipantReturns
fake.recordInvocation("StartParticipant", []interface{}{arg1, arg2, arg3, arg4})
fake.startParticipantMutex.Unlock()
if stub != nil {
return stub(arg1, arg2, arg3, arg4)
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeRouter) StartParticipantCallCount() int {
fake.startParticipantMutex.RLock()
defer fake.startParticipantMutex.RUnlock()
return len(fake.startParticipantArgsForCall)
}
func (fake *FakeRouter) StartParticipantCalls(stub func(string, string, string, string) error) {
fake.startParticipantMutex.Lock()
defer fake.startParticipantMutex.Unlock()
fake.StartParticipantStub = stub
}
func (fake *FakeRouter) StartParticipantArgsForCall(i int) (string, string, string, string) {
fake.startParticipantMutex.RLock()
defer fake.startParticipantMutex.RUnlock()
argsForCall := fake.startParticipantArgsForCall[i]
return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4
}
func (fake *FakeRouter) StartParticipantReturns(result1 error) {
fake.startParticipantMutex.Lock()
defer fake.startParticipantMutex.Unlock()
fake.StartParticipantStub = nil
fake.startParticipantReturns = struct {
result1 error
}{result1}
}
func (fake *FakeRouter) StartParticipantReturnsOnCall(i int, result1 error) {
fake.startParticipantMutex.Lock()
defer fake.startParticipantMutex.Unlock()
fake.StartParticipantStub = nil
if fake.startParticipantReturnsOnCall == nil {
fake.startParticipantReturnsOnCall = make(map[int]struct {
result1 error
})
}
fake.startParticipantReturnsOnCall[i] = struct {
result1 error
}{result1}
}
func (fake *FakeRouter) Stop() {
fake.stopMutex.Lock()
fake.stopArgsForCall = append(fake.stopArgsForCall, struct {
}{})
stub := fake.StopStub
fake.recordInvocation("Stop", []interface{}{})
fake.stopMutex.Unlock()
if stub != nil {
fake.StopStub()
}
}
func (fake *FakeRouter) StopCallCount() int {
fake.stopMutex.RLock()
defer fake.stopMutex.RUnlock()
return len(fake.stopArgsForCall)
}
func (fake *FakeRouter) StopCalls(stub func()) {
fake.stopMutex.Lock()
defer fake.stopMutex.Unlock()
fake.StopStub = stub
}
func (fake *FakeRouter) Invocations() map[string][][]interface{} {
fake.invocationsMutex.RLock()
defer fake.invocationsMutex.RUnlock()
fake.getNodeMutex.RLock()
defer fake.getNodeMutex.RUnlock()
fake.getNodeIdForRoomMutex.RLock()
defer fake.getNodeIdForRoomMutex.RUnlock()
fake.getRequestSinkMutex.RLock()
defer fake.getRequestSinkMutex.RUnlock()
fake.getResponseSourceMutex.RLock()
defer fake.getResponseSourceMutex.RUnlock()
fake.onNewParticipantMutex.RLock()
defer fake.onNewParticipantMutex.RUnlock()
fake.registerNodeMutex.RLock()
defer fake.registerNodeMutex.RUnlock()
fake.setRTCNodeMutex.RLock()
defer fake.setRTCNodeMutex.RUnlock()
fake.startMutex.RLock()
defer fake.startMutex.RUnlock()
fake.startParticipantMutex.RLock()
defer fake.startParticipantMutex.RUnlock()
fake.stopMutex.RLock()
defer fake.stopMutex.RUnlock()
copiedInvocations := map[string][][]interface{}{}
for key, value := range fake.invocations {
copiedInvocations[key] = value
}
return copiedInvocations
}
func (fake *FakeRouter) recordInvocation(key string, args []interface{}) {
fake.invocationsMutex.Lock()
defer fake.invocationsMutex.Unlock()
if fake.invocations == nil {
fake.invocations = map[string][][]interface{}{}
}
if fake.invocations[key] == nil {
fake.invocations[key] = [][]interface{}{}
}
fake.invocations[key] = append(fake.invocations[key], args)
}
var _ routing.Router = new(FakeRouter)

View File

@@ -19,7 +19,9 @@ type ReceiverConfig struct {
maxBufferTime int
}
func NewWebRTCConfig(conf *config.RTCConfig, externalIP string) (*WebRTCConfig, error) {
type ExternalIP string
func NewWebRTCConfig(conf *config.RTCConfig, externalIP ExternalIP) (*WebRTCConfig, error) {
c := webrtc.Configuration{
SDPSemantics: webrtc.SDPSemanticsUnifiedPlan,
}
@@ -41,7 +43,7 @@ func NewWebRTCConfig(conf *config.RTCConfig, externalIP string) (*WebRTCConfig,
},
}
if conf.UseExternalIP {
s.SetNAT1To1IPs([]string{externalIP}, webrtc.ICECandidateTypeHost)
s.SetNAT1To1IPs([]string{string(externalIP)}, webrtc.ICECandidateTypeHost)
}
return &WebRTCConfig{

View File

@@ -141,7 +141,7 @@ func (t *DataTrack) forwardWorker() {
for _, sub := range t.subscribers {
err := sub.SendMessage(msg)
if err != nil {
logger.GetLogger().Errorw("could not send data message",
logger.Errorw("could not send data message",
"err", err,
"source", t.participantId,
"dest", sub.participantId)

View File

@@ -1,99 +0,0 @@
package rtc
import (
"sync"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/proto/livekit"
)
// A RoomManager maintains active rooms that are hosted on the current node
type RoomManager struct {
rtcConf config.RTCConfig
externalIP string
config WebRTCConfig
rooms map[string]*Room
roomsByName map[string]*Room
roomLock sync.RWMutex
}
func NewRoomManager(rtcConf config.RTCConfig, externalIP string) (m *RoomManager, err error) {
m = &RoomManager{
rtcConf: rtcConf,
externalIP: externalIP,
rooms: make(map[string]*Room),
roomsByName: make(map[string]*Room),
roomLock: sync.RWMutex{},
}
wc, err := NewWebRTCConfig(&rtcConf, externalIP)
if err != nil {
return
}
m.config = *wc
return
}
func (m *RoomManager) GetRoom(idOrName string) *Room {
m.roomLock.RLock()
defer m.roomLock.RUnlock()
rm := m.rooms[idOrName]
if rm == nil {
rm = m.roomsByName[idOrName]
}
return rm
}
func (m *RoomManager) GetRoomWithConstraint(idOrName string, onlyName string) (*Room, error) {
if idOrName == "" {
idOrName = onlyName
}
if idOrName == "" {
return nil, ErrRoomIdMissing
}
rm := m.GetRoom(idOrName)
if rm == nil {
return nil, ErrRoomNotFound
}
if onlyName != "" && rm.Name != onlyName {
return nil, ErrPermissionDenied
}
return rm, nil
}
func (m *RoomManager) CreateRoom(req *livekit.CreateRoomRequest) (*Room, error) {
if req.Name == "" {
return nil, ErrInvalidRoomName
}
r := NewRoomForRequest(req, &m.config)
m.roomLock.Lock()
defer m.roomLock.Unlock()
if m.roomsByName[req.Name] != nil {
return nil, ErrInvalidRoomName
}
m.rooms[r.Sid] = r
m.roomsByName[r.Name] = r
return r, nil
}
func (m *RoomManager) DeleteRoom(idOrName string) error {
rm := m.GetRoom(idOrName)
if rm == nil {
return nil
}
m.roomLock.Lock()
defer m.roomLock.Unlock()
delete(m.rooms, rm.Sid)
delete(m.roomsByName, rm.Name)
return nil
}
func (m *RoomManager) Config() *WebRTCConfig {
return &m.config
}

View File

@@ -1,83 +0,0 @@
package rtc_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/rtc"
"github.com/livekit/livekit-server/proto/livekit"
)
func TestRoomManager_CreateRoom(t *testing.T) {
man := newRoomManager(t)
t.Run("creation and duplicates", func(t *testing.T) {
r := &livekit.CreateRoomRequest{Name: "basic"}
rm, err := man.CreateRoom(r)
assert.NoError(t, err)
assert.NotNil(t, rm)
rm, err = man.CreateRoom(r)
assert.Equal(t, rtc.ErrInvalidRoomName, err)
assert.Nil(t, rm)
})
t.Run("name is required", func(t *testing.T) {
_, err := man.CreateRoom(&livekit.CreateRoomRequest{})
assert.Equal(t, rtc.ErrInvalidRoomName, err)
})
}
func TestRoomManager_GetRoomByName(t *testing.T) {
man := newRoomManager(t)
_, err := man.CreateRoom(&livekit.CreateRoomRequest{
Name: "hello",
})
assert.NoError(t, err)
rm := man.GetRoom("hello")
assert.Equal(t, "hello", rm.Name)
}
func TestRoomManager_GetRoomWithConstraint(t *testing.T) {
man := newRoomManager(t)
rm, _ := man.CreateRoom(&livekit.CreateRoomRequest{
Name: "hello",
})
t.Run("no constraint, get by id", func(t *testing.T) {
r, err := man.GetRoomWithConstraint(rm.Sid, "")
assert.NoError(t, err)
assert.Equal(t, r, rm)
})
t.Run("no constraint, get by name", func(t *testing.T) {
r, err := man.GetRoomWithConstraint(rm.Name, "")
assert.NoError(t, err)
assert.Equal(t, r, rm)
})
t.Run("no constraint, room doesn't exist", func(t *testing.T) {
_, err := man.GetRoomWithConstraint("wtf", "")
assert.Equal(t, rtc.ErrRoomNotFound, err)
})
t.Run("constraint, no name", func(t *testing.T) {
r, err := man.GetRoomWithConstraint("", rm.Name)
assert.NoError(t, err)
assert.Equal(t, r, rm)
})
t.Run("constraint does not match name", func(t *testing.T) {
_, err := man.GetRoomWithConstraint(rm.Name, "anotherroom")
assert.Equal(t, rtc.ErrPermissionDenied, err)
})
}
func newRoomManager(t *testing.T) *rtc.RoomManager {
man, err := rtc.NewRoomManager(config.RTCConfig{}, "1.2.3.4")
assert.NoError(t, err)
return man
}

View File

@@ -152,13 +152,13 @@ func (t *MediaTrack) AddSubscriber(participant types.Participant) error {
// however, if the dest participant has disconnected, then we can skip
sender := transceiver.Sender()
if sender != nil {
logger.GetLogger().Debugw("removing peerconnection track",
logger.Debugw("removing peerconnection track",
"track", t.id,
"srcParticipant", t.participantId,
"destParticipant", participant.ID())
if err := participant.PeerConnection().RemoveTrack(sender); err != nil {
if _, ok := err.(*rtcerr.InvalidStateError); !ok {
logger.GetLogger().Warnw("could not remove remoteTrack from forwarder",
logger.Warnw("could not remove remoteTrack from forwarder",
"participant", participant.ID(),
"err", err)
}
@@ -188,7 +188,7 @@ func (t *MediaTrack) RemoveSubscriber(participantId string) {
}
func (t *MediaTrack) RemoveAllSubscribers() {
logger.GetLogger().Debugw("removing all subscribers", "track", t.id)
logger.Debugw("removing all subscribers", "track", t.id)
t.lock.RLock()
defer t.lock.RUnlock()
for _, dt := range t.downtracks {
@@ -244,7 +244,7 @@ func (t *MediaTrack) forwardRTPWorker() {
}()
for pkt := range t.receiver.RTPChan() {
//logger.GetLogger().Debugw("read packet from remoteTrack",
//logger.Debugw("read packet from remoteTrack",
// "participant", t.participantId,
// "track", t.ID())
// when track is muted, it's "disabled" on the client side, and will still be sending black frames
@@ -255,7 +255,7 @@ func (t *MediaTrack) forwardRTPWorker() {
t.lock.RLock()
for dstId, dt := range t.downtracks {
//logger.GetLogger().Debugw("read packet from remoteTrack",
//logger.Debugw("read packet from remoteTrack",
// "srcParticipant", t.participantId,
// "destParticipant", dstId,
// "track", t.ID())
@@ -271,7 +271,7 @@ func (t *MediaTrack) forwardRTPWorker() {
if delta < maxPLIFrequency {
continue
}
logger.GetLogger().Infow("keyframe required, sending PLI",
logger.Infow("keyframe required, sending PLI",
"srcParticipant", t.participantId)
rtcpPkts := []rtcp.Packet{
&rtcp.PictureLossIndication{SenderSSRC: uint32(t.ssrc), MediaSSRC: pkt.SSRC},
@@ -279,7 +279,7 @@ func (t *MediaTrack) forwardRTPWorker() {
t.rtcpCh <- rtcpPkts
t.lastPLI = time.Now()
} else if err != nil {
logger.GetLogger().Warnw("could not forward packet to participant",
logger.Warnw("could not forward packet to participant",
"src", t.participantId,
"dest", dstId,
"remoteTrack", t.id,
@@ -294,7 +294,7 @@ func (t *MediaTrack) handleRTCP(dt *sfu.DownTrack, rtcpBuf []byte) {
defer Recover()
pkts, err := rtcp.Unmarshal(rtcpBuf)
if err != nil {
logger.GetLogger().Warnw("could not decode RTCP packet", "err", err)
logger.Warnw("could not decode RTCP packet", "err", err)
}
var fwdPkts []rtcp.Packet
@@ -322,7 +322,7 @@ func (t *MediaTrack) handleRTCP(dt *sfu.DownTrack, rtcpBuf []byte) {
//log.Tracef("Slow link for sender %s, fraction packet lost %.2f", f.track.peerID, float64(p.Reports[0].FractionLost)/256)
}
case *rtcp.TransportLayerNack:
logger.GetLogger().Debugw("forwarder got nack",
logger.Debugw("forwarder got nack",
"packet", p)
var nackedPackets []uint16
for _, pair := range p.Nacks {

View File

@@ -12,6 +12,7 @@ import (
"github.com/pkg/errors"
"github.com/livekit/livekit-server/pkg/logger"
"github.com/livekit/livekit-server/pkg/routing"
"github.com/livekit/livekit-server/pkg/rtc/types"
"github.com/livekit/livekit-server/pkg/sfu"
"github.com/livekit/livekit-server/pkg/utils"
@@ -33,7 +34,7 @@ const (
type ParticipantImpl struct {
id string
peerConn types.PeerConnection
sigConn types.SignalConnection
responseSink routing.MessageSink
receiverConfig ReceiverConfig
ctx context.Context
cancel context.CancelFunc
@@ -69,19 +70,21 @@ func NewPeerConnection(conf *WebRTCConfig) (*webrtc.PeerConnection, error) {
se.BufferFactory = bufferFactory.GetOrNew
api := webrtc.NewAPI(webrtc.WithMediaEngine(me), webrtc.WithSettingEngine(se))
return api.NewPeerConnection(conf.Configuration)
pc, err := api.NewPeerConnection(conf.Configuration)
return pc, err
}
func NewParticipant(pc types.PeerConnection, sc types.SignalConnection, name string, receiverConfig ReceiverConfig) (*ParticipantImpl, error) {
func NewParticipant(participantId, name string, pc types.PeerConnection, rs routing.MessageSink, receiverConfig ReceiverConfig) (*ParticipantImpl, error) {
// TODO: check to ensure params are valid, id and name can't be empty
me := &webrtc.MediaEngine{}
me.RegisterDefaultCodecs()
ctx, cancel := context.WithCancel(context.Background())
participant := &ParticipantImpl{
id: utils.NewGuid(utils.ParticipantPrefix),
id: participantId,
name: name,
peerConn: pc,
sigConn: sc,
responseSink: rs,
receiverConfig: receiverConfig,
ctx: ctx,
cancel: cancel,
@@ -96,7 +99,6 @@ func NewParticipant(pc types.PeerConnection, sc types.SignalConnection, name str
debouncedNegotiate: debounce.New(negotiationFrequency),
}
log := logger.GetLogger()
pc.OnTrack(participant.onMediaTrack)
pc.OnICECandidate(func(c *webrtc.ICECandidate) {
@@ -107,14 +109,14 @@ func NewParticipant(pc types.PeerConnection, sc types.SignalConnection, name str
ci := c.ToJSON()
// write candidate
logger.GetLogger().Debugw("sending ice candidates")
err := sc.WriteResponse(&livekit.SignalResponse{
logger.Debugw("sending ice candidates")
err := rs.WriteMessage(&livekit.SignalResponse{
Message: &livekit.SignalResponse_Trickle{
Trickle: ToProtoTrickle(ci),
},
})
if err != nil {
log.Errorw("could not send trickle", "err", err)
logger.Errorw("could not send trickle", "err", err)
}
if participant.onICECandidate != nil {
@@ -123,7 +125,7 @@ func NewParticipant(pc types.PeerConnection, sc types.SignalConnection, name str
})
pc.OnICEConnectionStateChange(func(state webrtc.ICEConnectionState) {
logger.GetLogger().Debugw("ICE connection state changed", "state", state.String())
logger.Debugw("ICE connection state changed", "state", state.String())
if state == webrtc.ICEConnectionStateConnected {
participant.updateState(livekit.ParticipantInfo_ACTIVE)
}
@@ -228,7 +230,7 @@ func (p *ParticipantImpl) Answer(sdp webrtc.SessionDescription) (answer webrtc.S
}
p.negotiationCond.L.Unlock()
err = p.sigConn.WriteResponse(&livekit.SignalResponse{
err = p.responseSink.WriteMessage(&livekit.SignalResponse{
Message: &livekit.SignalResponse_Answer{
Answer: ToProtoSessionDescription(answer),
},
@@ -252,7 +254,7 @@ func (p *ParticipantImpl) AddTrack(clientId, name string, trackType livekit.Trac
}
p.pendingTracks[clientId] = ti
p.sigConn.WriteResponse(&livekit.SignalResponse{
p.responseSink.WriteMessage(&livekit.SignalResponse{
Message: &livekit.SignalResponse_TrackPublished{
TrackPublished: &livekit.TrackPublishedResponse{
Cid: clientId,
@@ -266,7 +268,7 @@ func (p *ParticipantImpl) HandleAnswer(sdp webrtc.SessionDescription) error {
if sdp.Type != webrtc.SDPTypeAnswer {
return ErrUnexpectedOffer
}
logger.GetLogger().Debugw("setting remote answer")
logger.Debugw("setting remote answer")
if err := p.peerConn.SetRemoteDescription(sdp); err != nil {
return errors.Wrap(err, "could not set remote description")
}
@@ -288,7 +290,7 @@ func (p *ParticipantImpl) HandleClientNegotiation() {
}
p.negotiationState = negotiationStateClient
p.negotiationCond.L.Unlock()
p.sigConn.WriteResponse(&livekit.SignalResponse{
p.responseSink.WriteMessage(&livekit.SignalResponse{
Message: &livekit.SignalResponse_Negotiate{
Negotiate: &livekit.NegotiationResponse{},
},
@@ -329,7 +331,7 @@ func (p *ParticipantImpl) AddSubscriber(op types.Participant) error {
defer p.lock.RUnlock()
for _, track := range p.publishedTracks {
logger.GetLogger().Debugw("subscribing to remoteTrack",
logger.Debugw("subscribing to remoteTrack",
"srcParticipant", p.ID(),
"dstParticipant", op.ID(),
"remoteTrack", track.ID())
@@ -350,9 +352,9 @@ func (p *ParticipantImpl) RemoveSubscriber(participantId string) {
}
// signal connection methods
func (p *ParticipantImpl) SendJoinResponse(roomInfo *livekit.RoomInfo, otherParticipants []types.Participant) error {
func (p *ParticipantImpl) SendJoinResponse(roomInfo *livekit.Room, otherParticipants []types.Participant) error {
// send Join response
return p.sigConn.WriteResponse(&livekit.SignalResponse{
return p.responseSink.WriteMessage(&livekit.SignalResponse{
Message: &livekit.SignalResponse_Join{
Join: &livekit.JoinResponse{
Room: roomInfo,
@@ -364,7 +366,7 @@ func (p *ParticipantImpl) SendJoinResponse(roomInfo *livekit.RoomInfo, otherPart
}
func (p *ParticipantImpl) SendParticipantUpdate(participants []*livekit.ParticipantInfo) error {
return p.sigConn.WriteResponse(&livekit.SignalResponse{
return p.responseSink.WriteMessage(&livekit.SignalResponse{
Message: &livekit.SignalResponse_Update{
Update: &livekit.ParticipantUpdate{
Participants: participants,
@@ -429,10 +431,10 @@ func (p *ParticipantImpl) negotiate() {
}
p.negotiationCond.L.Unlock()
logger.GetLogger().Debugw("starting negotiation", "participant", p.ID())
logger.Debugw("starting negotiation", "participant", p.ID())
offer, err := p.peerConn.CreateOffer(nil)
if err != nil {
logger.GetLogger().Errorw("could not create offer", "err", err)
logger.Errorw("could not create offer", "err", err)
return
}
@@ -444,18 +446,18 @@ func (p *ParticipantImpl) negotiate() {
err = p.peerConn.SetLocalDescription(offer)
if err != nil {
logger.GetLogger().Errorw("could not set local description", "err", err)
logger.Errorw("could not set local description", "err", err)
return
}
logger.GetLogger().Debugw("sending available offer to participant")
err = p.sigConn.WriteResponse(&livekit.SignalResponse{
logger.Debugw("sending available offer to participant")
err = p.responseSink.WriteMessage(&livekit.SignalResponse{
Message: &livekit.SignalResponse_Offer{
Offer: ToProtoSessionDescription(offer),
},
})
if err != nil {
logger.GetLogger().Errorw("could not send offer to peer",
logger.Errorw("could not send offer to peer",
"err", err)
}
}
@@ -477,7 +479,7 @@ func (p *ParticipantImpl) updateState(state livekit.ParticipantInfo_State) {
// when a new remoteTrack is created, creates a Track and adds it to room
func (p *ParticipantImpl) onMediaTrack(track *webrtc.TrackRemote, rtpReceiver *webrtc.RTPReceiver) {
logger.GetLogger().Debugw("mediaTrack added", "participantId", p.ID(), "remoteTrack", track.ID())
logger.Debugw("mediaTrack added", "participantId", p.ID(), "remoteTrack", track.ID())
ti := p.popPendingTrack(track.ID())
if ti == nil {
@@ -496,7 +498,7 @@ func (p *ParticipantImpl) onDataChannel(dc *webrtc.DataChannel) {
if dc.Label() == placeholderDataChannel {
return
}
logger.GetLogger().Debugw("dataChannel added", "participantId", p.ID(), "label", dc.Label())
logger.Debugw("dataChannel added", "participantId", p.ID(), "label", dc.Label())
// data channels have numeric ids, so we use its label to identify
ti := p.popPendingTrack(dc.Label())
@@ -515,7 +517,7 @@ func (p *ParticipantImpl) popPendingTrack(clientId string) *livekit.TrackInfo {
defer p.lock.Unlock()
ti := p.pendingTracks[clientId]
if ti == nil {
logger.GetLogger().Errorw("track info not published prior to track", "clientId", clientId)
logger.Errorw("track info not published prior to track", "clientId", clientId)
} else {
delete(p.pendingTracks, clientId)
}
@@ -584,7 +586,7 @@ func (p *ParticipantImpl) downTracksRTCPWorker() {
if err == io.EOF || err == io.ErrClosedPipe {
return
}
logger.GetLogger().Errorw("could not send downtrack reports",
logger.Errorw("could not send downtrack reports",
"participant", p.id,
"err", err)
}
@@ -598,10 +600,10 @@ func (p *ParticipantImpl) rtcpSendWorker() {
// read from rtcpChan
for pkts := range p.rtcpCh {
//for _, pkt := range pkts {
// logger.GetLogger().Debugw("writing RTCP", "packet", pkt)
// logger.Debugw("writing RTCP", "packet", pkt)
//}
if err := p.peerConn.WriteRTCP(pkts); err != nil {
logger.GetLogger().Errorw("could not write RTCP to participant",
logger.Errorw("could not write RTCP to participant",
"participant", p.id,
"err", err)
}

View File

@@ -5,8 +5,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/livekit/livekit-server/pkg/routing/routingfakes"
"github.com/livekit/livekit-server/pkg/rtc/types"
"github.com/livekit/livekit-server/pkg/rtc/types/typesfakes"
"github.com/livekit/livekit-server/pkg/utils"
"github.com/livekit/livekit-server/proto/livekit"
)
@@ -67,6 +69,11 @@ func TestTrackPublishEvents(t *testing.T) {
}
func newParticipantForTest(name string) *ParticipantImpl {
p, _ := NewParticipant(&typesfakes.FakePeerConnection{}, &typesfakes.FakeSignalConnection{}, name, ReceiverConfig{})
p, _ := NewParticipant(
utils.NewGuid(utils.ParticipantPrefix),
name,
&typesfakes.FakePeerConnection{},
&routingfakes.FakeMessageSink{},
ReceiverConfig{})
return p
}

View File

@@ -52,7 +52,7 @@ func NewReceiver(rtcpCh chan []rtcp.Packet, rtpReceiver *webrtc.RTPReceiver, tra
r.rtcpReader.OnPacket(func(bytes []byte) {
pkts, err := rtcp.Unmarshal(bytes)
if err != nil {
logger.GetLogger().Warnw("could not unmarshal RTCP packet")
logger.Warnw("could not unmarshal RTCP packet")
return
}
for _, pkt := range pkts {

View File

@@ -2,13 +2,11 @@ package rtc
import (
"sync"
"time"
"github.com/thoas/go-funk"
"github.com/livekit/livekit-server/pkg/logger"
"github.com/livekit/livekit-server/pkg/rtc/types"
"github.com/livekit/livekit-server/pkg/utils"
"github.com/livekit/livekit-server/proto/livekit"
)
@@ -20,16 +18,10 @@ type Room struct {
participants map[string]types.Participant
}
func NewRoomForRequest(req *livekit.CreateRoomRequest, config *WebRTCConfig) *Room {
func NewRoom(room *livekit.Room, config WebRTCConfig) *Room {
return &Room{
Room: livekit.Room{
Sid: utils.NewGuid(utils.RoomPrefix),
Name: req.Name,
EmptyTimeout: req.EmptyTimeout,
MaxParticipants: req.MaxParticipants,
CreationTime: time.Now().Unix(),
},
config: *config,
Room: *room,
config: config,
lock: sync.RWMutex{},
participants: make(map[string]types.Participant),
}
@@ -47,28 +39,14 @@ func (r *Room) GetParticipants() []types.Participant {
return funk.Values(r.participants).([]types.Participant)
}
func (r *Room) ToRoomInfo(node *livekit.Node) *livekit.RoomInfo {
ri := &livekit.RoomInfo{
Sid: r.Sid,
Name: r.Name,
CreationTime: r.CreationTime,
}
if node != nil {
ri.NodeIp = node.Ip
}
return ri
}
func (r *Room) Join(participant types.Participant) error {
r.lock.Lock()
defer r.lock.Unlock()
log := logger.GetLogger()
// it's important to set this before connection, we don't want to miss out on any publishedTracks
participant.OnTrackPublished(r.onTrackAdded)
participant.OnStateChange(func(p types.Participant, oldState livekit.ParticipantInfo_State) {
log.Debugw("participant state changed", "state", p.State(), "participant", p.ID(),
logger.Debugw("participant state changed", "state", p.State(), "participant", p.ID(),
"oldState", oldState)
r.broadcastParticipantState(p)
@@ -81,7 +59,7 @@ func (r *Room) Join(participant types.Participant) error {
}
if err := op.AddSubscriber(p); err != nil {
// TODO: log error? or disconnect?
logger.GetLogger().Errorw("could not subscribe to participant",
logger.Errorw("could not subscribe to participant",
"dstParticipant", p.ID(),
"srcParticipant", op.ID())
}
@@ -92,7 +70,7 @@ func (r *Room) Join(participant types.Participant) error {
})
participant.OnTrackUpdated(r.onTrackUpdated)
log.Infow("new participant joined",
logger.Infow("new participant joined",
"id", participant.ID(),
"name", participant.Name(),
"roomId", r.Sid)
@@ -107,7 +85,7 @@ func (r *Room) Join(participant types.Participant) error {
}
}
return participant.SendJoinResponse(r.ToRoomInfo(nil), otherParticipants)
return participant.SendJoinResponse(&r.Room, otherParticipants)
}
func (r *Room) RemoveParticipant(id string) {
@@ -145,12 +123,12 @@ func (r *Room) onTrackAdded(participant types.Participant, track types.Published
// not fully joined. don't subscribe yet
continue
}
logger.GetLogger().Debugw("subscribing to new track",
logger.Debugw("subscribing to new track",
"srcParticipant", participant.ID(),
"remoteTrack", track.ID(),
"dstParticipant", existingParticipant.ID())
if err := track.AddSubscriber(existingParticipant); err != nil {
logger.GetLogger().Errorw("could not subscribe to remoteTrack",
logger.Errorw("could not subscribe to remoteTrack",
"srcParticipant", participant.ID(),
"remoteTrack", track.ID(),
"dstParticipant", existingParticipant.ID())
@@ -176,7 +154,7 @@ func (r *Room) broadcastParticipantState(p types.Participant) {
err := op.SendParticipantUpdate(updates)
if err != nil {
logger.GetLogger().Errorw("could not send update to participant",
logger.Errorw("could not send update to participant",
"participant", p.ID(),
"err", err)
}

View File

@@ -15,32 +15,6 @@ const (
numParticipants = 3
)
func TestNewRoomForRequest(t *testing.T) {
req := &livekit.CreateRoomRequest{
Name: "myroom",
EmptyTimeout: 120,
MaxParticipants: 50,
}
rm := rtc.NewRoomForRequest(req, &rtc.WebRTCConfig{})
assert.NotEmpty(t, rm.Sid)
assert.Equal(t, req.Name, rm.Name)
assert.Equal(t, req.EmptyTimeout, rm.EmptyTimeout)
assert.Equal(t, req.MaxParticipants, rm.MaxParticipants)
}
func TestToRoomInfo(t *testing.T) {
rm := rtc.NewRoomForRequest(&livekit.CreateRoomRequest{
Name: "myroom",
EmptyTimeout: 120,
MaxParticipants: 50,
}, &rtc.WebRTCConfig{})
info := rm.ToRoomInfo(&livekit.Node{Ip: "0.0.0.0"})
assert.Equal(t, rm.Sid, info.Sid)
assert.Equal(t, rm.Name, info.Name)
assert.Equal(t, "0.0.0.0", info.NodeIp)
}
func TestRoomJoin(t *testing.T) {
t.Run("joining returns existing participant data", func(t *testing.T) {
rm := newRoomWithParticipants(t, numParticipants)
@@ -123,7 +97,10 @@ func TestNewTrack(t *testing.T) {
}
func newRoomWithParticipants(t *testing.T, num int) *rtc.Room {
rm := rtc.NewRoomForRequest(&livekit.CreateRoomRequest{}, &rtc.WebRTCConfig{})
rm := rtc.NewRoom(
&livekit.Room{Name: "name"},
rtc.WebRTCConfig{},
)
for i := 0; i < num; i++ {
participant := newMockParticipant("")
err := rm.Join(participant)

View File

@@ -20,12 +20,6 @@ type WebsocketClient interface {
WriteControl(messageType int, data []byte, deadline time.Time) error
}
//counterfeiter:generate . SignalConnection
type SignalConnection interface {
ReadRequest() (*livekit.SignalRequest, error)
WriteResponse(*livekit.SignalResponse) error
}
//counterfeiter:generate . PeerConnection
type PeerConnection interface {
OnICECandidate(f func(*webrtc.ICECandidate))
@@ -61,10 +55,11 @@ type Participant interface {
AddTrack(clientId, name string, trackType livekit.TrackType)
Answer(sdp webrtc.SessionDescription) (answer webrtc.SessionDescription, err error)
HandleAnswer(sdp webrtc.SessionDescription) error
HandleClientNegotiation()
AddICECandidate(candidate webrtc.ICECandidateInit) error
AddSubscriber(op Participant) error
RemoveSubscriber(peerId string)
SendJoinResponse(info *livekit.RoomInfo, otherParticipants []Participant) error
SendJoinResponse(info *livekit.Room, otherParticipants []Participant) error
SendParticipantUpdate(participants []*livekit.ParticipantInfo) error
SetTrackMuted(trackId string, muted bool)

View File

@@ -81,6 +81,10 @@ type FakeParticipant struct {
handleAnswerReturnsOnCall map[int]struct {
result1 error
}
HandleClientNegotiationStub func()
handleClientNegotiationMutex sync.RWMutex
handleClientNegotiationArgsForCall []struct {
}
IDStub func() string
iDMutex sync.RWMutex
iDArgsForCall []struct {
@@ -167,10 +171,10 @@ type FakeParticipant struct {
removeSubscriberArgsForCall []struct {
arg1 string
}
SendJoinResponseStub func(*livekit.RoomInfo, []types.Participant) error
SendJoinResponseStub func(*livekit.Room, []types.Participant) error
sendJoinResponseMutex sync.RWMutex
sendJoinResponseArgsForCall []struct {
arg1 *livekit.RoomInfo
arg1 *livekit.Room
arg2 []types.Participant
}
sendJoinResponseReturns struct {
@@ -591,6 +595,30 @@ func (fake *FakeParticipant) HandleAnswerReturnsOnCall(i int, result1 error) {
}{result1}
}
func (fake *FakeParticipant) HandleClientNegotiation() {
fake.handleClientNegotiationMutex.Lock()
fake.handleClientNegotiationArgsForCall = append(fake.handleClientNegotiationArgsForCall, struct {
}{})
stub := fake.HandleClientNegotiationStub
fake.recordInvocation("HandleClientNegotiation", []interface{}{})
fake.handleClientNegotiationMutex.Unlock()
if stub != nil {
fake.HandleClientNegotiationStub()
}
}
func (fake *FakeParticipant) HandleClientNegotiationCallCount() int {
fake.handleClientNegotiationMutex.RLock()
defer fake.handleClientNegotiationMutex.RUnlock()
return len(fake.handleClientNegotiationArgsForCall)
}
func (fake *FakeParticipant) HandleClientNegotiationCalls(stub func()) {
fake.handleClientNegotiationMutex.Lock()
defer fake.handleClientNegotiationMutex.Unlock()
fake.HandleClientNegotiationStub = stub
}
func (fake *FakeParticipant) ID() string {
fake.iDMutex.Lock()
ret, specificReturn := fake.iDReturnsOnCall[len(fake.iDArgsForCall)]
@@ -1081,7 +1109,7 @@ func (fake *FakeParticipant) RemoveSubscriberArgsForCall(i int) string {
return argsForCall.arg1
}
func (fake *FakeParticipant) SendJoinResponse(arg1 *livekit.RoomInfo, arg2 []types.Participant) error {
func (fake *FakeParticipant) SendJoinResponse(arg1 *livekit.Room, arg2 []types.Participant) error {
var arg2Copy []types.Participant
if arg2 != nil {
arg2Copy = make([]types.Participant, len(arg2))
@@ -1090,7 +1118,7 @@ func (fake *FakeParticipant) SendJoinResponse(arg1 *livekit.RoomInfo, arg2 []typ
fake.sendJoinResponseMutex.Lock()
ret, specificReturn := fake.sendJoinResponseReturnsOnCall[len(fake.sendJoinResponseArgsForCall)]
fake.sendJoinResponseArgsForCall = append(fake.sendJoinResponseArgsForCall, struct {
arg1 *livekit.RoomInfo
arg1 *livekit.Room
arg2 []types.Participant
}{arg1, arg2Copy})
stub := fake.SendJoinResponseStub
@@ -1112,13 +1140,13 @@ func (fake *FakeParticipant) SendJoinResponseCallCount() int {
return len(fake.sendJoinResponseArgsForCall)
}
func (fake *FakeParticipant) SendJoinResponseCalls(stub func(*livekit.RoomInfo, []types.Participant) error) {
func (fake *FakeParticipant) SendJoinResponseCalls(stub func(*livekit.Room, []types.Participant) error) {
fake.sendJoinResponseMutex.Lock()
defer fake.sendJoinResponseMutex.Unlock()
fake.SendJoinResponseStub = stub
}
func (fake *FakeParticipant) SendJoinResponseArgsForCall(i int) (*livekit.RoomInfo, []types.Participant) {
func (fake *FakeParticipant) SendJoinResponseArgsForCall(i int) (*livekit.Room, []types.Participant) {
fake.sendJoinResponseMutex.RLock()
defer fake.sendJoinResponseMutex.RUnlock()
argsForCall := fake.sendJoinResponseArgsForCall[i]
@@ -1394,6 +1422,8 @@ func (fake *FakeParticipant) Invocations() map[string][][]interface{} {
defer fake.closeMutex.RUnlock()
fake.handleAnswerMutex.RLock()
defer fake.handleAnswerMutex.RUnlock()
fake.handleClientNegotiationMutex.RLock()
defer fake.handleClientNegotiationMutex.RUnlock()
fake.iDMutex.RLock()
defer fake.iDMutex.RUnlock()
fake.isReadyMutex.RLock()

View File

@@ -1,182 +0,0 @@
// Code generated by counterfeiter. DO NOT EDIT.
package typesfakes
import (
"sync"
"github.com/livekit/livekit-server/pkg/rtc/types"
"github.com/livekit/livekit-server/proto/livekit"
)
type FakeSignalConnection struct {
ReadRequestStub func() (*livekit.SignalRequest, error)
readRequestMutex sync.RWMutex
readRequestArgsForCall []struct {
}
readRequestReturns struct {
result1 *livekit.SignalRequest
result2 error
}
readRequestReturnsOnCall map[int]struct {
result1 *livekit.SignalRequest
result2 error
}
WriteResponseStub func(*livekit.SignalResponse) error
writeResponseMutex sync.RWMutex
writeResponseArgsForCall []struct {
arg1 *livekit.SignalResponse
}
writeResponseReturns struct {
result1 error
}
writeResponseReturnsOnCall map[int]struct {
result1 error
}
invocations map[string][][]interface{}
invocationsMutex sync.RWMutex
}
func (fake *FakeSignalConnection) ReadRequest() (*livekit.SignalRequest, error) {
fake.readRequestMutex.Lock()
ret, specificReturn := fake.readRequestReturnsOnCall[len(fake.readRequestArgsForCall)]
fake.readRequestArgsForCall = append(fake.readRequestArgsForCall, struct {
}{})
stub := fake.ReadRequestStub
fakeReturns := fake.readRequestReturns
fake.recordInvocation("ReadRequest", []interface{}{})
fake.readRequestMutex.Unlock()
if stub != nil {
return stub()
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeSignalConnection) ReadRequestCallCount() int {
fake.readRequestMutex.RLock()
defer fake.readRequestMutex.RUnlock()
return len(fake.readRequestArgsForCall)
}
func (fake *FakeSignalConnection) ReadRequestCalls(stub func() (*livekit.SignalRequest, error)) {
fake.readRequestMutex.Lock()
defer fake.readRequestMutex.Unlock()
fake.ReadRequestStub = stub
}
func (fake *FakeSignalConnection) ReadRequestReturns(result1 *livekit.SignalRequest, result2 error) {
fake.readRequestMutex.Lock()
defer fake.readRequestMutex.Unlock()
fake.ReadRequestStub = nil
fake.readRequestReturns = struct {
result1 *livekit.SignalRequest
result2 error
}{result1, result2}
}
func (fake *FakeSignalConnection) ReadRequestReturnsOnCall(i int, result1 *livekit.SignalRequest, result2 error) {
fake.readRequestMutex.Lock()
defer fake.readRequestMutex.Unlock()
fake.ReadRequestStub = nil
if fake.readRequestReturnsOnCall == nil {
fake.readRequestReturnsOnCall = make(map[int]struct {
result1 *livekit.SignalRequest
result2 error
})
}
fake.readRequestReturnsOnCall[i] = struct {
result1 *livekit.SignalRequest
result2 error
}{result1, result2}
}
func (fake *FakeSignalConnection) WriteResponse(arg1 *livekit.SignalResponse) error {
fake.writeResponseMutex.Lock()
ret, specificReturn := fake.writeResponseReturnsOnCall[len(fake.writeResponseArgsForCall)]
fake.writeResponseArgsForCall = append(fake.writeResponseArgsForCall, struct {
arg1 *livekit.SignalResponse
}{arg1})
stub := fake.WriteResponseStub
fakeReturns := fake.writeResponseReturns
fake.recordInvocation("WriteResponse", []interface{}{arg1})
fake.writeResponseMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeSignalConnection) WriteResponseCallCount() int {
fake.writeResponseMutex.RLock()
defer fake.writeResponseMutex.RUnlock()
return len(fake.writeResponseArgsForCall)
}
func (fake *FakeSignalConnection) WriteResponseCalls(stub func(*livekit.SignalResponse) error) {
fake.writeResponseMutex.Lock()
defer fake.writeResponseMutex.Unlock()
fake.WriteResponseStub = stub
}
func (fake *FakeSignalConnection) WriteResponseArgsForCall(i int) *livekit.SignalResponse {
fake.writeResponseMutex.RLock()
defer fake.writeResponseMutex.RUnlock()
argsForCall := fake.writeResponseArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeSignalConnection) WriteResponseReturns(result1 error) {
fake.writeResponseMutex.Lock()
defer fake.writeResponseMutex.Unlock()
fake.WriteResponseStub = nil
fake.writeResponseReturns = struct {
result1 error
}{result1}
}
func (fake *FakeSignalConnection) WriteResponseReturnsOnCall(i int, result1 error) {
fake.writeResponseMutex.Lock()
defer fake.writeResponseMutex.Unlock()
fake.WriteResponseStub = nil
if fake.writeResponseReturnsOnCall == nil {
fake.writeResponseReturnsOnCall = make(map[int]struct {
result1 error
})
}
fake.writeResponseReturnsOnCall[i] = struct {
result1 error
}{result1}
}
func (fake *FakeSignalConnection) Invocations() map[string][][]interface{} {
fake.invocationsMutex.RLock()
defer fake.invocationsMutex.RUnlock()
fake.readRequestMutex.RLock()
defer fake.readRequestMutex.RUnlock()
fake.writeResponseMutex.RLock()
defer fake.writeResponseMutex.RUnlock()
copiedInvocations := map[string][][]interface{}{}
for key, value := range fake.invocations {
copiedInvocations[key] = value
}
return copiedInvocations
}
func (fake *FakeSignalConnection) recordInvocation(key string, args []interface{}) {
fake.invocationsMutex.Lock()
defer fake.invocationsMutex.Unlock()
if fake.invocations == nil {
fake.invocations = map[string][][]interface{}{}
}
if fake.invocations[key] == nil {
fake.invocations[key] = [][]interface{}{}
}
fake.invocations[key] = append(fake.invocations[key], args)
}
var _ types.SignalConnection = new(FakeSignalConnection)

View File

@@ -5,8 +5,11 @@ import (
"io"
"strings"
"github.com/google/wire"
"github.com/pion/webrtc/v3"
"go.uber.org/zap"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/logger"
"github.com/livekit/livekit-server/pkg/rtc/types"
"github.com/livekit/livekit-server/proto/livekit"
@@ -16,6 +19,15 @@ const (
trackIdSeparator = "|"
)
var RTCSet = wire.NewSet(
NewWebRTCConfig,
RTCConfigFromConfig,
)
func RTCConfigFromConfig(conf *config.Config) *config.RTCConfig {
return &conf.RTC
}
func UnpackTrackId(packed string) (peerId string, trackId string) {
parts := strings.Split(packed, trackIdSeparator)
if len(parts) > 1 {
@@ -118,6 +130,7 @@ func RecoverSilent() {
func Recover() {
if r := recover(); r != nil {
logger.GetLogger().Errorw("recovered panic", "err", r)
log := logger.Desugar().WithOptions(zap.AddCallerSkip(1))
log.Error("recovered panic", zap.Any("error", r))
}
}

View File

@@ -21,7 +21,6 @@ const (
var (
ErrPermissionDenied = errors.New("permissions denied")
AuthRequired bool
)
// authentication middleware
@@ -91,9 +90,6 @@ func SetAuthorizationToken(r *http.Request, token string) {
}
func EnsureJoinPermission(ctx context.Context) (name string, err error) {
if !AuthRequired {
return "", nil
}
claims := GetGrants(ctx)
if claims == nil || claims.Video == nil {
err = ErrPermissionDenied
@@ -109,9 +105,6 @@ func EnsureJoinPermission(ctx context.Context) (name string, err error) {
}
func EnsureCreatePermission(ctx context.Context) error {
if !AuthRequired {
return nil
}
claims := GetGrants(ctx)
if claims == nil {
return ErrPermissionDenied
@@ -123,13 +116,25 @@ func EnsureCreatePermission(ctx context.Context) error {
return ErrPermissionDenied
}
func EnsureListPermission(ctx context.Context) error {
claims := GetGrants(ctx)
if claims == nil {
return ErrPermissionDenied
}
if claims.Video.RoomList {
return nil
}
return ErrPermissionDenied
}
// wraps authentication errors around Twirp
func twirpAuthError(err error) error {
return twirp.NewError(twirp.Unauthenticated, err.Error())
}
func handleError(w http.ResponseWriter, status int, msg string) {
logger.GetLogger().Debugw("error handling request", "error", msg, "status", status)
logger.Debugw("error handling request", "error", msg, "status", status)
w.WriteHeader(status)
w.Write([]byte(msg))
}

7
pkg/service/errors.go Normal file
View File

@@ -0,0 +1,7 @@
package service
import "errors"
var (
ErrRoomNotFound = errors.New("requested room does not exist")
)

View File

@@ -0,0 +1,74 @@
package service
import (
"sync"
"github.com/thoas/go-funk"
"github.com/livekit/livekit-server/proto/livekit"
)
// encapsulates CRUD operations for room settings
type LocalRoomStore struct {
// map of roomId => room
rooms map[string]*livekit.Room
// map of roomName => roomId
roomIds map[string]string
lock sync.RWMutex
//CreateRoom(room *livekit.Room) error
//GetRoom(idOrName string) (*livekit.Room, error)
//DeleteRoom(idOrName string) error
}
func NewLocalRoomStore() *LocalRoomStore {
return &LocalRoomStore{
rooms: make(map[string]*livekit.Room),
roomIds: make(map[string]string),
lock: sync.RWMutex{},
}
}
func (p *LocalRoomStore) CreateRoom(room *livekit.Room) error {
p.lock.Lock()
p.rooms[room.Sid] = room
p.roomIds[room.Name] = room.Sid
p.lock.Unlock()
return nil
}
func (p *LocalRoomStore) GetRoom(idOrName string) (*livekit.Room, error) {
p.lock.RLock()
defer p.lock.RUnlock()
// see if it's an id or name
if p.rooms[idOrName] == nil {
idOrName = p.roomIds[idOrName]
}
room := p.rooms[idOrName]
if room == nil {
return nil, ErrRoomNotFound
}
return room, nil
}
func (p *LocalRoomStore) ListRooms() ([]*livekit.Room, error) {
p.lock.RLock()
defer p.lock.RUnlock()
return funk.Values(p.rooms).([]*livekit.Room), nil
}
func (p *LocalRoomStore) DeleteRoom(idOrName string) error {
room, err := p.GetRoom(idOrName)
if err == ErrRoomNotFound {
return nil
} else if err != nil {
return err
}
p.lock.Lock()
defer p.lock.Unlock()
delete(p.rooms, room.Sid)
delete(p.roomIds, room.Name)
return nil
}

View File

@@ -0,0 +1 @@
package service

View File

@@ -0,0 +1,75 @@
package service
import (
"context"
"time"
"github.com/twitchtv/twirp"
"github.com/livekit/livekit-server/pkg/utils"
"github.com/livekit/livekit-server/proto/livekit"
)
// A rooms service that supports a single node
type RoomService struct {
roomProvider RoomStore
}
func NewRoomService(rp RoomStore) (svc *RoomService, err error) {
svc = &RoomService{
roomProvider: rp,
}
return
}
func (s *RoomService) CreateRoom(ctx context.Context, req *livekit.CreateRoomRequest) (rm *livekit.Room, err error) {
if err = EnsureCreatePermission(ctx); err != nil {
return nil, twirpAuthError(err)
}
rm = &livekit.Room{
Sid: utils.NewGuid(utils.RoomPrefix),
Name: req.Name,
EmptyTimeout: req.EmptyTimeout,
MaxParticipants: req.MaxParticipants,
CreationTime: time.Now().Unix(),
}
err = s.roomProvider.CreateRoom(rm)
if err != nil {
return
}
return
}
func (s *RoomService) ListRooms(ctx context.Context, req *livekit.ListRoomsRequest) (res *livekit.ListRoomsResponse, err error) {
err = EnsureListPermission(ctx)
if err != nil {
return nil, twirpAuthError(err)
}
rooms, err := s.roomProvider.ListRooms()
if err != nil {
// TODO: translate error codes to twirp
return
}
res = &livekit.ListRoomsResponse{
Rooms: rooms,
}
return
}
func (s *RoomService) DeleteRoom(ctx context.Context, req *livekit.DeleteRoomRequest) (res *livekit.DeleteRoomResponse, err error) {
if err = EnsureCreatePermission(ctx); err != nil {
return nil, twirpAuthError(err)
}
err = s.roomProvider.DeleteRoom(req.Room)
if err != nil {
err = twirp.WrapError(twirp.InternalError("could not delete room"), err)
return
}
res = &livekit.DeleteRoomResponse{}
return
}

16
pkg/service/roomstore.go Normal file
View File

@@ -0,0 +1,16 @@
package service
import (
"github.com/livekit/livekit-server/proto/livekit"
)
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
// encapsulates CRUD operations for room settings
//counterfeiter:generate . RoomStore
type RoomStore interface {
CreateRoom(room *livekit.Room) error
GetRoom(idOrName string) (*livekit.Room, error)
ListRooms() ([]*livekit.Room, error)
DeleteRoom(idOrName string) error
}

View File

@@ -1,221 +0,0 @@
package service
import (
"encoding/json"
"io"
"net/http"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/logger"
"github.com/livekit/livekit-server/pkg/rtc"
"github.com/livekit/livekit-server/pkg/rtc/types"
"github.com/livekit/livekit-server/proto/livekit"
)
type RTCService struct {
manager *rtc.RoomManager
upgrader websocket.Upgrader
isDev bool
}
func NewRTCService(conf *config.Config, manager *rtc.RoomManager) *RTCService {
s := &RTCService{
manager: manager,
upgrader: websocket.Upgrader{},
isDev: conf.Development,
}
// allow connections from any origin, since script may be hosted anywhere
// security is enforced by access tokens
s.upgrader.CheckOrigin = func(r *http.Request) bool {
return true
}
return s
}
func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
roomId := r.FormValue("room")
var pName string
if s.isDev {
r.FormValue("name")
} else {
claims := GetGrants(r.Context())
// require a claim
if claims == nil || claims.Video == nil {
handleError(w, http.StatusUnauthorized, rtc.ErrPermissionDenied.Error())
}
pName = claims.Identity
}
log := logger.GetLogger()
onlyName, err := EnsureJoinPermission(r.Context())
if err != nil {
handleError(w, http.StatusUnauthorized, err.Error())
return
}
room, err := s.manager.GetRoomWithConstraint(roomId, onlyName)
if err != nil {
// TODO: return errors/status correctly
handleError(w, http.StatusNotFound, err.Error())
return
}
// upgrade only once the basics are good to go
conn, err := s.upgrader.Upgrade(w, r, nil)
if err != nil {
logger.GetLogger().Warnw("could not upgrade to WS",
"err", err,
)
handleError(w, http.StatusInternalServerError, err.Error())
return
}
conn.SetCloseHandler(func(code int, text string) error {
log.Infow("websocket closed by remote")
return nil
})
signalConn := rtc.NewWSSignalConnection(conn)
pc, err := rtc.NewPeerConnection(s.manager.Config())
if err != nil {
handleError(w, http.StatusInternalServerError, "could not create peerConnection: "+err.Error())
return
}
participant, err := rtc.NewParticipant(pc, signalConn, pName, s.manager.Config().Receiver)
if err != nil {
handleError(w, http.StatusInternalServerError, "could not create participant: "+err.Error())
return
}
log.Infow("new client connected",
"roomId", roomId,
"name", pName,
"participant", participant.ID(),
)
if err := room.Join(participant); err != nil {
handleError(w, http.StatusInternalServerError, "could not join room: "+err.Error())
return
}
defer func() {
// remove peer from room upon disconnection
room.RemoveParticipant(participant.ID())
participant.Close()
log.Infow("WS connection closed", "participant", participant.ID())
}()
// read connection and wait for commands
//ctx := context.Background()
for {
req, err := signalConn.ReadRequest()
if err == io.EOF {
// client disconnected from websocket
return
} else if err != nil {
return
}
if req == nil {
continue
}
switch msg := req.Message.(type) {
case *livekit.SignalRequest_Offer:
err = s.handleOffer(participant, msg.Offer)
if err != nil {
log.Errorw("could not handle join", "err", err, "participant", participant.ID())
return
}
case *livekit.SignalRequest_AddTrack:
log.Debugw("publishing track", "participant", participant.ID(),
"track", msg.AddTrack.Cid)
participant.AddTrack(msg.AddTrack.Cid, msg.AddTrack.Name, msg.AddTrack.Type)
case *livekit.SignalRequest_Answer:
if participant.State() == livekit.ParticipantInfo_JOINING {
log.Errorw("cannot negotiate before peer offer", "participant", participant.ID())
//conn.WriteJSON(jsonError(http.StatusNotAcceptable, "cannot negotiate before peer offer"))
return
}
sd := rtc.FromProtoSessionDescription(msg.Answer)
err = participant.HandleAnswer(sd)
if err != nil {
log.Errorw("could not handle answer", "participant", participant.ID(), "err", err)
//conn.WriteJSON(
// jsonError(http.StatusInternalServerError, "could not handle negotiate", err.Error()))
return
}
case *livekit.SignalRequest_Negotiate:
participant.HandleClientNegotiation()
case *livekit.SignalRequest_Trickle:
if participant.State() == livekit.ParticipantInfo_JOINING {
log.Errorw("cannot trickle before peer offer", "participant", participant.ID())
//conn.WriteJSON(jsonError(http.StatusNotAcceptable, "cannot trickle before peer offer"))
return
}
err = s.handleTrickle(participant, msg.Trickle)
if err != nil {
log.Errorw("could not handle trickle", "participant", participant.ID(), "err", err)
//conn.WriteJSON(
// jsonError(http.StatusInternalServerError, "could not handle trickle", err.Error()))
return
}
case *livekit.SignalRequest_Mute:
participant.SetTrackMuted(msg.Mute.Sid, msg.Mute.Muted)
}
}
}
func (s *RTCService) handleOffer(participant types.Participant, offer *livekit.SessionDescription) error {
log := logger.GetLogger()
_, err := participant.Answer(rtc.FromProtoSessionDescription(offer))
if err != nil {
return errors.Wrap(err, "could not answer offer")
}
log.Debugw("answered client offer")
return nil
}
func (s *RTCService) handleTrickle(participant types.Participant, trickle *livekit.TrickleRequest) error {
candidateInit := rtc.FromProtoTrickle(trickle)
//logger.GetLogger().Debugw("adding peer candidate", "participant", participant.ID())
if err := participant.AddICECandidate(candidateInit); err != nil {
return err
}
return nil
}
type errStruct struct {
StatusCode int `json:"statusCode"`
Error string `json:"error"`
Message string `json:"message,omitempty"`
}
func writeJSONError(w http.ResponseWriter, code int, error ...string) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Header().Set("X-Content-Type-Options", "nosniff")
w.WriteHeader(code)
json.NewEncoder(w).Encode(jsonError(code, error...))
}
func jsonError(code int, error ...string) errStruct {
es := errStruct{
StatusCode: code,
}
if len(error) > 0 {
es.Error = error[0]
}
if len(error) > 1 {
es.Message = error[1]
}
return es
}

166
pkg/service/rtcrunner.go Normal file
View File

@@ -0,0 +1,166 @@
package service
import (
"io"
"sync"
"github.com/livekit/livekit-server/pkg/logger"
"github.com/livekit/livekit-server/pkg/routing"
"github.com/livekit/livekit-server/pkg/rtc"
"github.com/livekit/livekit-server/pkg/rtc/types"
"github.com/livekit/livekit-server/proto/livekit"
)
// RTC runner manages the lifecycles of a WebRTC connection
// it creates a new goroutine for each participant it manages.
type RTCRunner struct {
lock sync.RWMutex
roomProvider RoomStore
currentNode routing.LocalNode
router routing.Router
config *rtc.WebRTCConfig
rooms map[string]*rtc.Room
}
func NewRTCRunner(rp RoomStore, router routing.Router, currentNode routing.LocalNode, config *rtc.WebRTCConfig) *RTCRunner {
return &RTCRunner{
lock: sync.RWMutex{},
roomProvider: rp,
config: config,
router: router,
currentNode: currentNode,
rooms: make(map[string]*rtc.Room),
}
}
// starts WebRTC session when a new participant is connected
func (r *RTCRunner) StartSession(roomName, participantId, participantName string, requestSource routing.MessageSource, responseSink routing.MessageSink) {
room, err := r.getOrCreateRoom(roomName)
if err != nil {
logger.Errorw("could not create room", "error", err)
return
}
logger.Debugw("starting RTC session",
"room", roomName,
"participant", participantName,
"num_participants", len(room.GetParticipants()),
)
pc, err := rtc.NewPeerConnection(r.config)
if err != nil {
logger.Errorw("could not create peerConnection", "error", err)
return
}
participant, err := rtc.NewParticipant(participantId, participantName, pc, responseSink, r.config.Receiver)
if err != nil {
logger.Errorw("could not create participant", "error", err)
return
}
// register participant to be on this server
if err = r.router.SetRTCNode(participantId, r.currentNode.Id); err != nil {
logger.Errorw("could not set RTC node", "error", err)
return
}
// join room
if err := room.Join(participant); err != nil {
logger.Errorw("could not join room", "error", err)
return
}
go r.sessionWorker(room, participant, requestSource)
}
func (r *RTCRunner) getOrCreateRoom(roomName string) (*rtc.Room, error) {
r.lock.RLock()
room := r.rooms[roomName]
r.lock.RUnlock()
if room != nil {
return room, nil
}
// create new room, get details first
ri, err := r.roomProvider.GetRoom(roomName)
if err != nil {
return nil, err
}
room = rtc.NewRoom(ri, *r.config)
r.lock.Lock()
r.rooms[roomName] = room
r.lock.Unlock()
return room, nil
}
func (r *RTCRunner) sessionWorker(room *rtc.Room, participant types.Participant, requestSource routing.MessageSource) {
defer func() {
logger.Debugw("RTC session finishing",
"participant", participant.Name(),
"room", room.Name,
)
// remove peer from room when participant leaves room
room.RemoveParticipant(participant.ID())
}()
defer rtc.Recover()
for {
obj, err := requestSource.ReadMessage()
if err == io.EOF {
return
}
req := obj.(*livekit.SignalRequest)
switch msg := req.Message.(type) {
case *livekit.SignalRequest_Offer:
_, err := participant.Answer(rtc.FromProtoSessionDescription(msg.Offer))
if err != nil {
logger.Errorw("could not handle join", "err", err, "participant", participant.ID())
return
}
case *livekit.SignalRequest_AddTrack:
logger.Debugw("publishing track", "participant", participant.ID(),
"track", msg.AddTrack.Cid)
participant.AddTrack(msg.AddTrack.Cid, msg.AddTrack.Name, msg.AddTrack.Type)
case *livekit.SignalRequest_Answer:
if participant.State() == livekit.ParticipantInfo_JOINING {
logger.Errorw("cannot negotiate before peer offer", "participant", participant.ID())
//conn.WriteJSON(jsonError(http.StatusNotAcceptable, "cannot negotiate before peer offer"))
return
}
sd := rtc.FromProtoSessionDescription(msg.Answer)
err = participant.HandleAnswer(sd)
if err != nil {
logger.Errorw("could not handle answer", "participant", participant.ID(), "err", err)
//conn.WriteJSON(
// jsonError(http.StatusInternalServerError, "could not handle negotiate", err.Error()))
return
}
case *livekit.SignalRequest_Negotiate:
participant.HandleClientNegotiation()
case *livekit.SignalRequest_Trickle:
if participant.State() == livekit.ParticipantInfo_JOINING {
logger.Errorw("cannot trickle before peer offer", "participant", participant.ID())
//conn.WriteJSON(jsonError(http.StatusNotAcceptable, "cannot trickle before peer offer"))
return
}
candidateInit := rtc.FromProtoTrickle(msg.Trickle)
//logger.Debugw("adding peer candidate", "participant", participant.ID())
if err := participant.AddICECandidate(candidateInit); err != nil {
logger.Errorw("could not handle trickle", "participant", participant.ID(), "err", err)
//conn.WriteJSON(
// jsonError(http.StatusInternalServerError, "could not handle trickle", err.Error()))
return
}
case *livekit.SignalRequest_Mute:
participant.SetTrackMuted(msg.Mute.Sid, msg.Mute.Muted)
}
}
}

160
pkg/service/rtcservice.go Normal file
View File

@@ -0,0 +1,160 @@
package service
import (
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/gorilla/websocket"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/logger"
"github.com/livekit/livekit-server/pkg/routing"
"github.com/livekit/livekit-server/pkg/rtc"
"github.com/livekit/livekit-server/pkg/utils"
"github.com/livekit/livekit-server/proto/livekit"
)
type RTCService struct {
router routing.Router
roomStore RoomStore
upgrader websocket.Upgrader
currentNode routing.LocalNode
isDev bool
}
func NewRTCService(conf *config.Config, roomStore RoomStore, router routing.Router, currentNode routing.LocalNode) *RTCService {
s := &RTCService{
router: router,
roomStore: roomStore,
upgrader: websocket.Upgrader{},
currentNode: currentNode,
isDev: conf.Development,
}
// allow connections from any origin, since script may be hosted anywhere
// security is enforced by access tokens
s.upgrader.CheckOrigin = func(r *http.Request) bool {
return true
}
return s
}
func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
roomName := r.FormValue("room")
claims := GetGrants(r.Context())
// require a claim
if claims == nil || claims.Video == nil {
handleError(w, http.StatusUnauthorized, rtc.ErrPermissionDenied.Error())
}
pName := claims.Identity
onlyName, err := EnsureJoinPermission(r.Context())
if err != nil {
handleError(w, http.StatusUnauthorized, err.Error())
return
}
if onlyName != "" {
roomName = onlyName
}
rm, err := s.roomStore.GetRoom(roomName)
if err != nil {
handleError(w, http.StatusNotFound, err.Error())
return
}
// upgrade only once the basics are good to go
conn, err := s.upgrader.Upgrade(w, r, nil)
if err != nil {
logger.Warnw("could not upgrade to WS",
"err", err,
)
handleError(w, http.StatusInternalServerError, err.Error())
return
}
sigConn := NewWSSignalConnection(conn)
participantId := utils.NewGuid(utils.ParticipantPrefix)
err = s.router.StartParticipant(roomName, participantId, pName, s.currentNode.Id)
if err != nil {
handleError(w, http.StatusInternalServerError, "could not set signal node: "+err.Error())
}
logger.Infow("new client connected",
"room", rm.Sid,
"roomName", rm.Name,
"name", pName,
)
reqSink := s.router.GetRequestSink(participantId)
resSource := s.router.GetResponseSource(participantId)
go func() {
for {
msg, err := resSource.ReadMessage()
if err == io.EOF {
return
}
res, ok := msg.(*livekit.SignalResponse)
if !ok {
logger.Errorw("unexpected message type", "type", fmt.Sprintf("%T", msg))
continue
}
if err = sigConn.WriteResponse(res); err != nil {
logger.Warnw("error writing to websocket", "error", err)
return
}
}
}()
defer func() {
logger.Infow("WS connection closed", "participant", pName)
reqSink.Close()
}()
for {
req, err := sigConn.ReadRequest()
// normal closure
if err == io.EOF || websocket.IsCloseError(err, websocket.CloseAbnormalClosure, websocket.CloseGoingAway, websocket.CloseNormalClosure) {
return
} else if err != nil {
logger.Errorw("error reading from websocket", "error", err)
return
}
if err = reqSink.WriteMessage(req); err != nil {
logger.Warnw("error writing to request sink", "error", err)
}
}
}
type errStruct struct {
StatusCode int `json:"statusCode"`
Error string `json:"error"`
Message string `json:"message,omitempty"`
}
func writeJSONError(w http.ResponseWriter, code int, error ...string) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Header().Set("X-Content-Type-Options", "nosniff")
w.WriteHeader(code)
json.NewEncoder(w).Encode(jsonError(code, error...))
}
func jsonError(code int, error ...string) errStruct {
es := errStruct{
StatusCode: code,
}
if len(error) > 0 {
es.Error = error[0]
}
if len(error) > 1 {
es.Message = error[1]
}
return es
}

117
pkg/service/server.go Normal file
View File

@@ -0,0 +1,117 @@
package service
import (
"context"
"errors"
"fmt"
"net"
"net/http"
"time"
"github.com/urfave/negroni"
"github.com/livekit/livekit-server/pkg/auth"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/logger"
"github.com/livekit/livekit-server/pkg/routing"
"github.com/livekit/livekit-server/proto/livekit"
)
type LivekitServer struct {
config *config.Config
roomServer livekit.TwirpServer
rtcService *RTCService
httpServer *http.Server
router routing.Router
running bool
doneChan chan bool
}
func NewLivekitServer(conf *config.Config,
roomService livekit.RoomService,
rtcService *RTCService,
keyProvider auth.KeyProvider,
router routing.Router,
runner *RTCRunner,
) (s *LivekitServer, err error) {
s = &LivekitServer{
config: conf,
roomServer: livekit.NewRoomServiceServer(roomService),
rtcService: rtcService,
router: router,
}
middlewares := []negroni.Handler{
// always the first
negroni.NewRecovery(),
}
if keyProvider != nil {
middlewares = append(middlewares, NewAPIKeyAuthMiddleware(keyProvider))
}
mux := http.NewServeMux()
mux.Handle(s.roomServer.PathPrefix(), s.roomServer)
mux.Handle("/rtc", rtcService)
s.httpServer = &http.Server{
Addr: fmt.Sprintf(":%d", conf.Port),
Handler: configureMiddlewares(mux, middlewares...),
}
// hook up router to the RTC Runner
router.OnNewParticipant(runner.StartSession)
return
}
func (s *LivekitServer) IsRunning() bool {
return s.running
}
func (s *LivekitServer) Start() error {
if s.running {
return errors.New("already running")
}
if err := s.router.Start(); err != nil {
return err
}
s.doneChan = make(chan bool, 1)
// ensure we could listen
ln, err := net.Listen("tcp", s.httpServer.Addr)
if err != nil {
return err
}
go func() {
logger.Infow("starting LiveKit server", "address", s.httpServer.Addr)
s.httpServer.Serve(ln)
}()
s.running = true
<-s.doneChan
// wait for shutdown
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
s.httpServer.Shutdown(ctx)
return nil
}
func (s *LivekitServer) Stop() {
s.running = false
s.router.Stop()
s.doneChan <- true
}
func configureMiddlewares(handler http.Handler, middlewares ...negroni.Handler) *negroni.Negroni {
n := negroni.New()
for _, m := range middlewares {
n.Use(m)
}
n.UseHandler(handler)
return n
}

View File

@@ -1,147 +0,0 @@
package service
import (
"context"
"errors"
"fmt"
"net"
"net/http"
"sync"
"time"
"github.com/google/wire"
"github.com/urfave/negroni"
"github.com/livekit/livekit-server/pkg/auth"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/logger"
"github.com/livekit/livekit-server/pkg/node"
"github.com/livekit/livekit-server/pkg/rtc"
"github.com/livekit/livekit-server/proto/livekit"
)
var ServiceSet = wire.NewSet(
NewRoomService,
NewRTCService,
NewLivekitServer,
newRoomManagerWithNode,
)
func NewRoomService(conf *config.Config, manager *rtc.RoomManager, localNode *node.Node) (livekit.RoomService, error) {
if conf.MultiNode {
return nil, fmt.Errorf("multinode is not supported")
} else {
return NewSimpleRoomService(manager, localNode)
}
}
type LivekitServer struct {
config *config.Config
roomServer livekit.TwirpServer
rtcService *RTCService
roomHttp *http.Server
rtcHttp *http.Server
running bool
doneChan chan bool
}
func newRoomManagerWithNode(conf *config.Config, localNode *node.Node) (*rtc.RoomManager, error) {
return rtc.NewRoomManager(conf.RTC, localNode.Ip)
}
func NewLivekitServer(conf *config.Config,
roomService livekit.RoomService,
rtcService *RTCService,
keyProvider auth.KeyProvider) (s *LivekitServer, err error) {
s = &LivekitServer{
config: conf,
roomServer: livekit.NewRoomServiceServer(roomService),
rtcService: rtcService,
}
middlewares := make([]negroni.Handler, 0)
if keyProvider != nil {
middlewares = append(middlewares, NewAPIKeyAuthMiddleware(keyProvider))
}
s.roomHttp = &http.Server{
Addr: fmt.Sprintf(":%d", conf.APIPort),
Handler: configureMiddlewares(s.roomServer, middlewares...),
}
rtcHandler := http.NewServeMux()
rtcHandler.Handle("/rtc", rtcService)
s.rtcHttp = &http.Server{
Addr: fmt.Sprintf(":%d", conf.RTCPort),
Handler: configureMiddlewares(rtcHandler, middlewares...),
}
return
}
func (s *LivekitServer) IsRunning() bool {
return s.running
}
func (s *LivekitServer) Start() error {
if s.running {
return errors.New("already running")
}
s.doneChan = make(chan bool, 1)
// ensure we could listen
roomLn, err := net.Listen("tcp", s.roomHttp.Addr)
if err != nil {
return err
}
rtcAddr := fmt.Sprintf(":%d", s.config.RTCPort)
rtcLn, err := net.Listen("tcp", rtcAddr)
if err != nil {
return err
}
go func() {
logger.GetLogger().Infow("starting Room service", "address", s.roomHttp.Addr)
s.roomHttp.Serve(roomLn)
}()
go func() {
logger.GetLogger().Infow("starting RTC service", "address", rtcAddr)
s.rtcHttp.Serve(rtcLn)
}()
s.running = true
<-s.doneChan
// wait for shutdown
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
s.rtcHttp.Shutdown(ctx)
}()
go func() {
defer wg.Done()
s.roomHttp.Shutdown(ctx)
}()
wg.Wait()
return nil
}
func (s *LivekitServer) Stop() {
s.running = false
s.doneChan <- true
}
func configureMiddlewares(handler http.Handler, middlewares ...negroni.Handler) *negroni.Negroni {
n := negroni.New()
n.Use(negroni.NewRecovery())
for _, m := range middlewares {
n.Use(m)
}
n.UseHandler(handler)
return n
}

View File

@@ -0,0 +1,335 @@
// Code generated by counterfeiter. DO NOT EDIT.
package servicefakes
import (
"sync"
"github.com/livekit/livekit-server/pkg/service"
"github.com/livekit/livekit-server/proto/livekit"
)
type FakeRoomStore struct {
CreateRoomStub func(*livekit.Room) error
createRoomMutex sync.RWMutex
createRoomArgsForCall []struct {
arg1 *livekit.Room
}
createRoomReturns struct {
result1 error
}
createRoomReturnsOnCall map[int]struct {
result1 error
}
DeleteRoomStub func(string) error
deleteRoomMutex sync.RWMutex
deleteRoomArgsForCall []struct {
arg1 string
}
deleteRoomReturns struct {
result1 error
}
deleteRoomReturnsOnCall map[int]struct {
result1 error
}
GetRoomStub func(string) (*livekit.Room, error)
getRoomMutex sync.RWMutex
getRoomArgsForCall []struct {
arg1 string
}
getRoomReturns struct {
result1 *livekit.Room
result2 error
}
getRoomReturnsOnCall map[int]struct {
result1 *livekit.Room
result2 error
}
ListRoomsStub func() ([]*livekit.Room, error)
listRoomsMutex sync.RWMutex
listRoomsArgsForCall []struct {
}
listRoomsReturns struct {
result1 []*livekit.Room
result2 error
}
listRoomsReturnsOnCall map[int]struct {
result1 []*livekit.Room
result2 error
}
invocations map[string][][]interface{}
invocationsMutex sync.RWMutex
}
func (fake *FakeRoomStore) CreateRoom(arg1 *livekit.Room) error {
fake.createRoomMutex.Lock()
ret, specificReturn := fake.createRoomReturnsOnCall[len(fake.createRoomArgsForCall)]
fake.createRoomArgsForCall = append(fake.createRoomArgsForCall, struct {
arg1 *livekit.Room
}{arg1})
stub := fake.CreateRoomStub
fakeReturns := fake.createRoomReturns
fake.recordInvocation("CreateRoom", []interface{}{arg1})
fake.createRoomMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeRoomStore) CreateRoomCallCount() int {
fake.createRoomMutex.RLock()
defer fake.createRoomMutex.RUnlock()
return len(fake.createRoomArgsForCall)
}
func (fake *FakeRoomStore) CreateRoomCalls(stub func(*livekit.Room) error) {
fake.createRoomMutex.Lock()
defer fake.createRoomMutex.Unlock()
fake.CreateRoomStub = stub
}
func (fake *FakeRoomStore) CreateRoomArgsForCall(i int) *livekit.Room {
fake.createRoomMutex.RLock()
defer fake.createRoomMutex.RUnlock()
argsForCall := fake.createRoomArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRoomStore) CreateRoomReturns(result1 error) {
fake.createRoomMutex.Lock()
defer fake.createRoomMutex.Unlock()
fake.CreateRoomStub = nil
fake.createRoomReturns = struct {
result1 error
}{result1}
}
func (fake *FakeRoomStore) CreateRoomReturnsOnCall(i int, result1 error) {
fake.createRoomMutex.Lock()
defer fake.createRoomMutex.Unlock()
fake.CreateRoomStub = nil
if fake.createRoomReturnsOnCall == nil {
fake.createRoomReturnsOnCall = make(map[int]struct {
result1 error
})
}
fake.createRoomReturnsOnCall[i] = struct {
result1 error
}{result1}
}
func (fake *FakeRoomStore) DeleteRoom(arg1 string) error {
fake.deleteRoomMutex.Lock()
ret, specificReturn := fake.deleteRoomReturnsOnCall[len(fake.deleteRoomArgsForCall)]
fake.deleteRoomArgsForCall = append(fake.deleteRoomArgsForCall, struct {
arg1 string
}{arg1})
stub := fake.DeleteRoomStub
fakeReturns := fake.deleteRoomReturns
fake.recordInvocation("DeleteRoom", []interface{}{arg1})
fake.deleteRoomMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeRoomStore) DeleteRoomCallCount() int {
fake.deleteRoomMutex.RLock()
defer fake.deleteRoomMutex.RUnlock()
return len(fake.deleteRoomArgsForCall)
}
func (fake *FakeRoomStore) DeleteRoomCalls(stub func(string) error) {
fake.deleteRoomMutex.Lock()
defer fake.deleteRoomMutex.Unlock()
fake.DeleteRoomStub = stub
}
func (fake *FakeRoomStore) DeleteRoomArgsForCall(i int) string {
fake.deleteRoomMutex.RLock()
defer fake.deleteRoomMutex.RUnlock()
argsForCall := fake.deleteRoomArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRoomStore) DeleteRoomReturns(result1 error) {
fake.deleteRoomMutex.Lock()
defer fake.deleteRoomMutex.Unlock()
fake.DeleteRoomStub = nil
fake.deleteRoomReturns = struct {
result1 error
}{result1}
}
func (fake *FakeRoomStore) DeleteRoomReturnsOnCall(i int, result1 error) {
fake.deleteRoomMutex.Lock()
defer fake.deleteRoomMutex.Unlock()
fake.DeleteRoomStub = nil
if fake.deleteRoomReturnsOnCall == nil {
fake.deleteRoomReturnsOnCall = make(map[int]struct {
result1 error
})
}
fake.deleteRoomReturnsOnCall[i] = struct {
result1 error
}{result1}
}
func (fake *FakeRoomStore) GetRoom(arg1 string) (*livekit.Room, error) {
fake.getRoomMutex.Lock()
ret, specificReturn := fake.getRoomReturnsOnCall[len(fake.getRoomArgsForCall)]
fake.getRoomArgsForCall = append(fake.getRoomArgsForCall, struct {
arg1 string
}{arg1})
stub := fake.GetRoomStub
fakeReturns := fake.getRoomReturns
fake.recordInvocation("GetRoom", []interface{}{arg1})
fake.getRoomMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeRoomStore) GetRoomCallCount() int {
fake.getRoomMutex.RLock()
defer fake.getRoomMutex.RUnlock()
return len(fake.getRoomArgsForCall)
}
func (fake *FakeRoomStore) GetRoomCalls(stub func(string) (*livekit.Room, error)) {
fake.getRoomMutex.Lock()
defer fake.getRoomMutex.Unlock()
fake.GetRoomStub = stub
}
func (fake *FakeRoomStore) GetRoomArgsForCall(i int) string {
fake.getRoomMutex.RLock()
defer fake.getRoomMutex.RUnlock()
argsForCall := fake.getRoomArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRoomStore) GetRoomReturns(result1 *livekit.Room, result2 error) {
fake.getRoomMutex.Lock()
defer fake.getRoomMutex.Unlock()
fake.GetRoomStub = nil
fake.getRoomReturns = struct {
result1 *livekit.Room
result2 error
}{result1, result2}
}
func (fake *FakeRoomStore) GetRoomReturnsOnCall(i int, result1 *livekit.Room, result2 error) {
fake.getRoomMutex.Lock()
defer fake.getRoomMutex.Unlock()
fake.GetRoomStub = nil
if fake.getRoomReturnsOnCall == nil {
fake.getRoomReturnsOnCall = make(map[int]struct {
result1 *livekit.Room
result2 error
})
}
fake.getRoomReturnsOnCall[i] = struct {
result1 *livekit.Room
result2 error
}{result1, result2}
}
func (fake *FakeRoomStore) ListRooms() ([]*livekit.Room, error) {
fake.listRoomsMutex.Lock()
ret, specificReturn := fake.listRoomsReturnsOnCall[len(fake.listRoomsArgsForCall)]
fake.listRoomsArgsForCall = append(fake.listRoomsArgsForCall, struct {
}{})
stub := fake.ListRoomsStub
fakeReturns := fake.listRoomsReturns
fake.recordInvocation("ListRooms", []interface{}{})
fake.listRoomsMutex.Unlock()
if stub != nil {
return stub()
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeRoomStore) ListRoomsCallCount() int {
fake.listRoomsMutex.RLock()
defer fake.listRoomsMutex.RUnlock()
return len(fake.listRoomsArgsForCall)
}
func (fake *FakeRoomStore) ListRoomsCalls(stub func() ([]*livekit.Room, error)) {
fake.listRoomsMutex.Lock()
defer fake.listRoomsMutex.Unlock()
fake.ListRoomsStub = stub
}
func (fake *FakeRoomStore) ListRoomsReturns(result1 []*livekit.Room, result2 error) {
fake.listRoomsMutex.Lock()
defer fake.listRoomsMutex.Unlock()
fake.ListRoomsStub = nil
fake.listRoomsReturns = struct {
result1 []*livekit.Room
result2 error
}{result1, result2}
}
func (fake *FakeRoomStore) ListRoomsReturnsOnCall(i int, result1 []*livekit.Room, result2 error) {
fake.listRoomsMutex.Lock()
defer fake.listRoomsMutex.Unlock()
fake.ListRoomsStub = nil
if fake.listRoomsReturnsOnCall == nil {
fake.listRoomsReturnsOnCall = make(map[int]struct {
result1 []*livekit.Room
result2 error
})
}
fake.listRoomsReturnsOnCall[i] = struct {
result1 []*livekit.Room
result2 error
}{result1, result2}
}
func (fake *FakeRoomStore) Invocations() map[string][][]interface{} {
fake.invocationsMutex.RLock()
defer fake.invocationsMutex.RUnlock()
fake.createRoomMutex.RLock()
defer fake.createRoomMutex.RUnlock()
fake.deleteRoomMutex.RLock()
defer fake.deleteRoomMutex.RUnlock()
fake.getRoomMutex.RLock()
defer fake.getRoomMutex.RUnlock()
fake.listRoomsMutex.RLock()
defer fake.listRoomsMutex.RUnlock()
copiedInvocations := map[string][][]interface{}{}
for key, value := range fake.invocations {
copiedInvocations[key] = value
}
return copiedInvocations
}
func (fake *FakeRoomStore) recordInvocation(key string, args []interface{}) {
fake.invocationsMutex.Lock()
defer fake.invocationsMutex.Unlock()
if fake.invocations == nil {
fake.invocations = map[string][][]interface{}{}
}
if fake.invocations[key] == nil {
fake.invocations[key] = [][]interface{}{}
}
fake.invocations[key] = append(fake.invocations[key], args)
}
var _ service.RoomStore = new(FakeRoomStore)

View File

@@ -1,69 +0,0 @@
package service
import (
"context"
"github.com/twitchtv/twirp"
"github.com/livekit/livekit-server/pkg/node"
"github.com/livekit/livekit-server/pkg/rtc"
"github.com/livekit/livekit-server/proto/livekit"
)
// A rooms service that supports a single node
type SimpleRoomService struct {
localNode *node.Node
manager *rtc.RoomManager
}
func NewSimpleRoomService(manager *rtc.RoomManager, localNode *node.Node) (svc *SimpleRoomService, err error) {
svc = &SimpleRoomService{
localNode: localNode,
manager: manager,
}
return
}
func (s *SimpleRoomService) CreateRoom(ctx context.Context, req *livekit.CreateRoomRequest) (res *livekit.RoomInfo, err error) {
if err = EnsureCreatePermission(ctx); err != nil {
return nil, twirpAuthError(err)
}
room, err := s.manager.CreateRoom(req)
if err != nil {
return
}
res = room.ToRoomInfo(&s.localNode.Node)
return
}
func (s *SimpleRoomService) GetRoom(ctx context.Context, req *livekit.GetRoomRequest) (res *livekit.RoomInfo, err error) {
onlyName, err := EnsureJoinPermission(ctx)
if err != nil {
return nil, twirpAuthError(err)
}
room, err := s.manager.GetRoomWithConstraint(req.Room, onlyName)
if err != nil {
// TODO: translate error codes to twirp
return
}
res = room.ToRoomInfo(&s.localNode.Node)
return
}
func (s *SimpleRoomService) DeleteRoom(ctx context.Context, req *livekit.DeleteRoomRequest) (res *livekit.DeleteRoomResponse, err error) {
if err = EnsureCreatePermission(ctx); err != nil {
return nil, twirpAuthError(err)
}
err = s.manager.DeleteRoom(req.Room)
if err != nil {
err = twirp.WrapError(twirp.InternalError("could not delete room"), err)
return
}
res = &livekit.DeleteRoomResponse{}
return
}

23
pkg/service/utils.go Normal file
View File

@@ -0,0 +1,23 @@
package service
import (
"github.com/google/wire"
"github.com/livekit/livekit-server/pkg/routing"
"github.com/livekit/livekit-server/pkg/rtc"
"github.com/livekit/livekit-server/proto/livekit"
)
var ServiceSet = wire.NewSet(
NewRoomService,
NewRTCService,
NewLivekitServer,
NewRTCRunner,
wire.Bind(new(livekit.RoomService), new(*RoomService)),
externalIpFromNode,
)
// helper to construct RTCConfig
func externalIpFromNode(currentNode routing.LocalNode) rtc.ExternalIP {
return rtc.ExternalIP(currentNode.Ip)
}

View File

@@ -7,13 +7,15 @@ import (
"github.com/livekit/livekit-server/pkg/auth"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/node"
"github.com/livekit/livekit-server/pkg/routing"
"github.com/livekit/livekit-server/pkg/rtc"
)
func InitializeServer(conf *config.Config, keyProvider auth.KeyProvider) (*LivekitServer, error) {
func InitializeServer(conf *config.Config, keyProvider auth.KeyProvider,
roomStore RoomStore, router routing.Router, currentNode routing.LocalNode) (*LivekitServer, error) {
wire.Build(
node.NodeSet,
ServiceSet,
rtc.RTCSet,
)
return &LivekitServer{}, nil
}

View File

@@ -8,26 +8,26 @@ package service
import (
"github.com/livekit/livekit-server/pkg/auth"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/node"
"github.com/livekit/livekit-server/pkg/routing"
"github.com/livekit/livekit-server/pkg/rtc"
)
// Injectors from wire.go:
func InitializeServer(conf *config.Config, keyProvider auth.KeyProvider) (*LivekitServer, error) {
nodeNode, err := node.NewLocalNode(conf)
func InitializeServer(conf *config.Config, keyProvider auth.KeyProvider, roomStore RoomStore, router routing.Router, currentNode routing.LocalNode) (*LivekitServer, error) {
roomService, err := NewRoomService(roomStore)
if err != nil {
return nil, err
}
roomManager, err := newRoomManagerWithNode(conf, nodeNode)
rtcService := NewRTCService(conf, roomStore, router, currentNode)
rtcConfig := rtc.RTCConfigFromConfig(conf)
externalIP := externalIpFromNode(currentNode)
webRTCConfig, err := rtc.NewWebRTCConfig(rtcConfig, externalIP)
if err != nil {
return nil, err
}
roomService, err := NewRoomService(conf, roomManager, nodeNode)
if err != nil {
return nil, err
}
rtcService := NewRTCService(conf, roomManager)
livekitServer, err := NewLivekitServer(conf, roomService, rtcService, keyProvider)
rtcRunner := NewRTCRunner(roomStore, router, currentNode, webRTCConfig)
livekitServer, err := NewLivekitServer(conf, roomService, rtcService, keyProvider, router, rtcRunner)
if err != nil {
return nil, err
}

View File

@@ -1,4 +1,4 @@
package rtc
package service
import (
"sync"
@@ -54,7 +54,7 @@ func (c *WSSignalConnection) ReadRequest() (*livekit.SignalRequest, error) {
err := protojson.Unmarshal(payload, msg)
return msg, err
default:
logger.GetLogger().Debugw("unsupported message", "message", messageType)
logger.Debugw("unsupported message", "message", messageType)
return nil, nil
}
}

View File

@@ -2,4 +2,4 @@ This package is largely files from the wonderful ion-sfu project.
https://github.com/pion/ion-sfu
It's duplicated here since we needed to access a private method in various helper classes
It's duplicated here with modifications to reference only classes that we need

View File

@@ -6,7 +6,7 @@ var (
errPeerConnectionInitFailed = errors.New("pc init failed")
errPtNotSupported = errors.New("payload type not supported")
errCreatingDataChannel = errors.New("failed to create data channel")
// router errors
// routing errors
errNoReceiverFound = errors.New("no receiver found")
// Helpers errors
errShortPacket = errors.New("packet is not large enough")

View File

@@ -127,7 +127,7 @@ func (x ParticipantInfo_State) Number() protoreflect.EnumNumber {
// Deprecated: Use ParticipantInfo_State.Descriptor instead.
func (ParticipantInfo_State) EnumDescriptor() ([]byte, []int) {
return file_model_proto_rawDescGZIP(), []int{4, 0}
return file_model_proto_rawDescGZIP(), []int{3, 0}
}
type Node struct {
@@ -137,7 +137,7 @@ type Node struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Ip string `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"`
RtcPort uint32 `protobuf:"varint,3,opt,name=rtc_port,json=rtcPort,proto3" json:"rtc_port,omitempty"`
NumCpus uint32 `protobuf:"varint,3,opt,name=num_cpus,json=numCpus,proto3" json:"num_cpus,omitempty"`
Stats *NodeStats `protobuf:"bytes,4,opt,name=stats,proto3" json:"stats,omitempty"`
}
@@ -187,9 +187,9 @@ func (x *Node) GetIp() string {
return ""
}
func (x *Node) GetRtcPort() uint32 {
func (x *Node) GetNumCpus() uint32 {
if x != nil {
return x.RtcPort
return x.NumCpus
}
return 0
}
@@ -336,77 +336,6 @@ func (x *Room) GetCreationTime() int64 {
return 0
}
type RoomInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Sid string `protobuf:"bytes,1,opt,name=sid,proto3" json:"sid,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
NodeIp string `protobuf:"bytes,3,opt,name=node_ip,json=nodeIp,proto3" json:"node_ip,omitempty"`
CreationTime int64 `protobuf:"varint,4,opt,name=creation_time,json=creationTime,proto3" json:"creation_time,omitempty"`
}
func (x *RoomInfo) Reset() {
*x = RoomInfo{}
if protoimpl.UnsafeEnabled {
mi := &file_model_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RoomInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RoomInfo) ProtoMessage() {}
func (x *RoomInfo) ProtoReflect() protoreflect.Message {
mi := &file_model_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RoomInfo.ProtoReflect.Descriptor instead.
func (*RoomInfo) Descriptor() ([]byte, []int) {
return file_model_proto_rawDescGZIP(), []int{3}
}
func (x *RoomInfo) GetSid() string {
if x != nil {
return x.Sid
}
return ""
}
func (x *RoomInfo) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *RoomInfo) GetNodeIp() string {
if x != nil {
return x.NodeIp
}
return ""
}
func (x *RoomInfo) GetCreationTime() int64 {
if x != nil {
return x.CreationTime
}
return 0
}
type ParticipantInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -421,7 +350,7 @@ type ParticipantInfo struct {
func (x *ParticipantInfo) Reset() {
*x = ParticipantInfo{}
if protoimpl.UnsafeEnabled {
mi := &file_model_proto_msgTypes[4]
mi := &file_model_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -434,7 +363,7 @@ func (x *ParticipantInfo) String() string {
func (*ParticipantInfo) ProtoMessage() {}
func (x *ParticipantInfo) ProtoReflect() protoreflect.Message {
mi := &file_model_proto_msgTypes[4]
mi := &file_model_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -447,7 +376,7 @@ func (x *ParticipantInfo) ProtoReflect() protoreflect.Message {
// Deprecated: Use ParticipantInfo.ProtoReflect.Descriptor instead.
func (*ParticipantInfo) Descriptor() ([]byte, []int) {
return file_model_proto_rawDescGZIP(), []int{4}
return file_model_proto_rawDescGZIP(), []int{3}
}
func (x *ParticipantInfo) GetSid() string {
@@ -493,7 +422,7 @@ type TrackInfo struct {
func (x *TrackInfo) Reset() {
*x = TrackInfo{}
if protoimpl.UnsafeEnabled {
mi := &file_model_proto_msgTypes[5]
mi := &file_model_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -506,7 +435,7 @@ func (x *TrackInfo) String() string {
func (*TrackInfo) ProtoMessage() {}
func (x *TrackInfo) ProtoReflect() protoreflect.Message {
mi := &file_model_proto_msgTypes[5]
mi := &file_model_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -519,7 +448,7 @@ func (x *TrackInfo) ProtoReflect() protoreflect.Message {
// Deprecated: Use TrackInfo.ProtoReflect.Descriptor instead.
func (*TrackInfo) Descriptor() ([]byte, []int) {
return file_model_proto_rawDescGZIP(), []int{5}
return file_model_proto_rawDescGZIP(), []int{4}
}
func (x *TrackInfo) GetSid() string {
@@ -564,7 +493,7 @@ type DataMessage struct {
func (x *DataMessage) Reset() {
*x = DataMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_model_proto_msgTypes[6]
mi := &file_model_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -577,7 +506,7 @@ func (x *DataMessage) String() string {
func (*DataMessage) ProtoMessage() {}
func (x *DataMessage) ProtoReflect() protoreflect.Message {
mi := &file_model_proto_msgTypes[6]
mi := &file_model_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -590,7 +519,7 @@ func (x *DataMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use DataMessage.ProtoReflect.Descriptor instead.
func (*DataMessage) Descriptor() ([]byte, []int) {
return file_model_proto_rawDescGZIP(), []int{6}
return file_model_proto_rawDescGZIP(), []int{5}
}
func (m *DataMessage) GetValue() isDataMessage_Value {
@@ -637,8 +566,8 @@ var file_model_proto_rawDesc = []byte{
0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x22, 0x6b, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x0e,
0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x0e,
0x0a, 0x02, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x19,
0x0a, 0x08, 0x72, 0x74, 0x63, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d,
0x52, 0x07, 0x72, 0x74, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x05, 0x73, 0x74, 0x61,
0x0a, 0x08, 0x6e, 0x75, 0x6d, 0x5f, 0x63, 0x70, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d,
0x52, 0x07, 0x6e, 0x75, 0x6d, 0x43, 0x70, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x05, 0x73, 0x74, 0x61,
0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b,
0x69, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74,
0x61, 0x74, 0x73, 0x22, 0x49, 0x0a, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73,
@@ -656,13 +585,6 @@ var file_model_proto_rawDesc = []byte{
0x78, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x23, 0x0a,
0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05,
0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69,
0x6d, 0x65, 0x22, 0x6e, 0x0a, 0x08, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10,
0x0a, 0x03, 0x73, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x69, 0x64,
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x70, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x70, 0x12, 0x23, 0x0a,
0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04,
0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69,
0x6d, 0x65, 0x22, 0xd9, 0x01, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61,
0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
@@ -710,22 +632,21 @@ func file_model_proto_rawDescGZIP() []byte {
}
var file_model_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_model_proto_goTypes = []interface{}{
(TrackType)(0), // 0: livekit.TrackType
(ParticipantInfo_State)(0), // 1: livekit.ParticipantInfo.State
(*Node)(nil), // 2: livekit.Node
(*NodeStats)(nil), // 3: livekit.NodeStats
(*Room)(nil), // 4: livekit.Room
(*RoomInfo)(nil), // 5: livekit.RoomInfo
(*ParticipantInfo)(nil), // 6: livekit.ParticipantInfo
(*TrackInfo)(nil), // 7: livekit.TrackInfo
(*DataMessage)(nil), // 8: livekit.DataMessage
(*ParticipantInfo)(nil), // 5: livekit.ParticipantInfo
(*TrackInfo)(nil), // 6: livekit.TrackInfo
(*DataMessage)(nil), // 7: livekit.DataMessage
}
var file_model_proto_depIdxs = []int32{
3, // 0: livekit.Node.stats:type_name -> livekit.NodeStats
1, // 1: livekit.ParticipantInfo.state:type_name -> livekit.ParticipantInfo.State
7, // 2: livekit.ParticipantInfo.tracks:type_name -> livekit.TrackInfo
6, // 2: livekit.ParticipantInfo.tracks:type_name -> livekit.TrackInfo
0, // 3: livekit.TrackInfo.type:type_name -> livekit.TrackType
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
@@ -777,18 +698,6 @@ func file_model_proto_init() {
}
}
file_model_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RoomInfo); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_model_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ParticipantInfo); i {
case 0:
return &v.state
@@ -800,7 +709,7 @@ func file_model_proto_init() {
return nil
}
}
file_model_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
file_model_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TrackInfo); i {
case 0:
return &v.state
@@ -812,7 +721,7 @@ func file_model_proto_init() {
return nil
}
}
file_model_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
file_model_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DataMessage); i {
case 0:
return &v.state
@@ -825,7 +734,7 @@ func file_model_proto_init() {
}
}
}
file_model_proto_msgTypes[6].OneofWrappers = []interface{}{
file_model_proto_msgTypes[5].OneofWrappers = []interface{}{
(*DataMessage_Text)(nil),
(*DataMessage_Binary)(nil),
}
@@ -835,7 +744,7 @@ func file_model_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_model_proto_rawDesc,
NumEnums: 2,
NumMessages: 7,
NumMessages: 6,
NumExtensions: 0,
NumServices: 0,
},

View File

@@ -89,16 +89,14 @@ func (x *CreateRoomRequest) GetMaxParticipants() uint32 {
return 0
}
type GetRoomRequest struct {
type ListRoomsRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Room string `protobuf:"bytes,1,opt,name=room,proto3" json:"room,omitempty"`
}
func (x *GetRoomRequest) Reset() {
*x = GetRoomRequest{}
func (x *ListRoomsRequest) Reset() {
*x = ListRoomsRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_room_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -106,13 +104,13 @@ func (x *GetRoomRequest) Reset() {
}
}
func (x *GetRoomRequest) String() string {
func (x *ListRoomsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetRoomRequest) ProtoMessage() {}
func (*ListRoomsRequest) ProtoMessage() {}
func (x *GetRoomRequest) ProtoReflect() protoreflect.Message {
func (x *ListRoomsRequest) ProtoReflect() protoreflect.Message {
mi := &file_room_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -124,16 +122,56 @@ func (x *GetRoomRequest) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use GetRoomRequest.ProtoReflect.Descriptor instead.
func (*GetRoomRequest) Descriptor() ([]byte, []int) {
// Deprecated: Use ListRoomsRequest.ProtoReflect.Descriptor instead.
func (*ListRoomsRequest) Descriptor() ([]byte, []int) {
return file_room_proto_rawDescGZIP(), []int{1}
}
func (x *GetRoomRequest) GetRoom() string {
if x != nil {
return x.Room
type ListRoomsResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Rooms []*Room `protobuf:"bytes,1,rep,name=rooms,proto3" json:"rooms,omitempty"`
}
func (x *ListRoomsResponse) Reset() {
*x = ListRoomsResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_room_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
return ""
}
func (x *ListRoomsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListRoomsResponse) ProtoMessage() {}
func (x *ListRoomsResponse) ProtoReflect() protoreflect.Message {
mi := &file_room_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListRoomsResponse.ProtoReflect.Descriptor instead.
func (*ListRoomsResponse) Descriptor() ([]byte, []int) {
return file_room_proto_rawDescGZIP(), []int{2}
}
func (x *ListRoomsResponse) GetRooms() []*Room {
if x != nil {
return x.Rooms
}
return nil
}
type DeleteRoomRequest struct {
@@ -147,7 +185,7 @@ type DeleteRoomRequest struct {
func (x *DeleteRoomRequest) Reset() {
*x = DeleteRoomRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_room_proto_msgTypes[2]
mi := &file_room_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -160,7 +198,7 @@ func (x *DeleteRoomRequest) String() string {
func (*DeleteRoomRequest) ProtoMessage() {}
func (x *DeleteRoomRequest) ProtoReflect() protoreflect.Message {
mi := &file_room_proto_msgTypes[2]
mi := &file_room_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -173,7 +211,7 @@ func (x *DeleteRoomRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeleteRoomRequest.ProtoReflect.Descriptor instead.
func (*DeleteRoomRequest) Descriptor() ([]byte, []int) {
return file_room_proto_rawDescGZIP(), []int{2}
return file_room_proto_rawDescGZIP(), []int{3}
}
func (x *DeleteRoomRequest) GetRoom() string {
@@ -192,7 +230,7 @@ type DeleteRoomResponse struct {
func (x *DeleteRoomResponse) Reset() {
*x = DeleteRoomResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_room_proto_msgTypes[3]
mi := &file_room_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -205,7 +243,7 @@ func (x *DeleteRoomResponse) String() string {
func (*DeleteRoomResponse) ProtoMessage() {}
func (x *DeleteRoomResponse) ProtoReflect() protoreflect.Message {
mi := &file_room_proto_msgTypes[3]
mi := &file_room_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -218,7 +256,7 @@ func (x *DeleteRoomResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeleteRoomResponse.ProtoReflect.Descriptor instead.
func (*DeleteRoomResponse) Descriptor() ([]byte, []int) {
return file_room_proto_rawDescGZIP(), []int{3}
return file_room_proto_rawDescGZIP(), []int{4}
}
var File_room_proto protoreflect.FileDescriptor
@@ -233,30 +271,33 @@ var file_room_proto_rawDesc = []byte{
0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
0x12, 0x29, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70,
0x61, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x6d, 0x61, 0x78, 0x50,
0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x24, 0x0a, 0x0e, 0x47,
0x65, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a,
0x04, 0x72, 0x6f, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6f,
0x6d, 0x22, 0x27, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x6d, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x6d, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x32, 0xc8, 0x01, 0x0a, 0x0b, 0x52, 0x6f, 0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x12, 0x3b, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x12, 0x1a,
0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52,
0x6f, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x6c, 0x69, 0x76,
0x65, 0x6b, 0x69, 0x74, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x35, 0x0a,
0x07, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x12, 0x17, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b,
0x69, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x11, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x52, 0x6f, 0x6f, 0x6d,
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x45, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f,
0x6f, 0x6d, 0x12, 0x1a, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b,
0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52,
0x6f, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x31, 0x5a, 0x2f, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69,
0x74, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x12, 0x0a, 0x10, 0x4c,
0x69, 0x73, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22,
0x38, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x52, 0x6f,
0x6f, 0x6d, 0x52, 0x05, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x22, 0x27, 0x0a, 0x11, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12,
0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f,
0x6f, 0x6d, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x6d,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xd1, 0x01, 0x0a, 0x0b, 0x52, 0x6f, 0x6f,
0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x12, 0x1a, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x52, 0x6f, 0x6f,
0x6d, 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x73, 0x12, 0x19,
0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6f,
0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x69, 0x76, 0x65,
0x6b, 0x69, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52,
0x6f, 0x6f, 0x6d, 0x12, 0x1a, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1b, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x31, 0x5a, 0x2f,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b,
0x69, 0x74, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -271,26 +312,28 @@ func file_room_proto_rawDescGZIP() []byte {
return file_room_proto_rawDescData
}
var file_room_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_room_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_room_proto_goTypes = []interface{}{
(*CreateRoomRequest)(nil), // 0: livekit.CreateRoomRequest
(*GetRoomRequest)(nil), // 1: livekit.GetRoomRequest
(*DeleteRoomRequest)(nil), // 2: livekit.DeleteRoomRequest
(*DeleteRoomResponse)(nil), // 3: livekit.DeleteRoomResponse
(*RoomInfo)(nil), // 4: livekit.RoomInfo
(*ListRoomsRequest)(nil), // 1: livekit.ListRoomsRequest
(*ListRoomsResponse)(nil), // 2: livekit.ListRoomsResponse
(*DeleteRoomRequest)(nil), // 3: livekit.DeleteRoomRequest
(*DeleteRoomResponse)(nil), // 4: livekit.DeleteRoomResponse
(*Room)(nil), // 5: livekit.Room
}
var file_room_proto_depIdxs = []int32{
0, // 0: livekit.RoomService.CreateRoom:input_type -> livekit.CreateRoomRequest
1, // 1: livekit.RoomService.GetRoom:input_type -> livekit.GetRoomRequest
2, // 2: livekit.RoomService.DeleteRoom:input_type -> livekit.DeleteRoomRequest
4, // 3: livekit.RoomService.CreateRoom:output_type -> livekit.RoomInfo
4, // 4: livekit.RoomService.GetRoom:output_type -> livekit.RoomInfo
3, // 5: livekit.RoomService.DeleteRoom:output_type -> livekit.DeleteRoomResponse
3, // [3:6] is the sub-list for method output_type
0, // [0:3] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
5, // 0: livekit.ListRoomsResponse.rooms:type_name -> livekit.Room
0, // 1: livekit.RoomService.CreateRoom:input_type -> livekit.CreateRoomRequest
1, // 2: livekit.RoomService.ListRooms:input_type -> livekit.ListRoomsRequest
3, // 3: livekit.RoomService.DeleteRoom:input_type -> livekit.DeleteRoomRequest
5, // 4: livekit.RoomService.CreateRoom:output_type -> livekit.Room
2, // 5: livekit.RoomService.ListRooms:output_type -> livekit.ListRoomsResponse
4, // 6: livekit.RoomService.DeleteRoom:output_type -> livekit.DeleteRoomResponse
4, // [4:7] is the sub-list for method output_type
1, // [1:4] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_room_proto_init() }
@@ -313,7 +356,7 @@ func file_room_proto_init() {
}
}
file_room_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetRoomRequest); i {
switch v := v.(*ListRoomsRequest); i {
case 0:
return &v.state
case 1:
@@ -325,7 +368,7 @@ func file_room_proto_init() {
}
}
file_room_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteRoomRequest); i {
switch v := v.(*ListRoomsResponse); i {
case 0:
return &v.state
case 1:
@@ -337,6 +380,18 @@ func file_room_proto_init() {
}
}
file_room_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteRoomRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_room_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteRoomResponse); i {
case 0:
return &v.state
@@ -355,7 +410,7 @@ func file_room_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_room_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumMessages: 5,
NumExtensions: 0,
NumServices: 1,
},

View File

@@ -45,9 +45,9 @@ const _ = twirp.TwirpPackageIsVersion7
type RoomService interface {
// TODO: how do we secure room service?
// should be accessible to only internal servers, not external
CreateRoom(context.Context, *CreateRoomRequest) (*RoomInfo, error)
CreateRoom(context.Context, *CreateRoomRequest) (*Room, error)
GetRoom(context.Context, *GetRoomRequest) (*RoomInfo, error)
ListRooms(context.Context, *ListRoomsRequest) (*ListRoomsResponse, error)
DeleteRoom(context.Context, *DeleteRoomRequest) (*DeleteRoomResponse, error)
}
@@ -80,7 +80,7 @@ func NewRoomServiceProtobufClient(baseURL string, client HTTPClient, opts ...twi
serviceURL += baseServicePath(clientOpts.PathPrefix(), "livekit", "RoomService")
urls := [3]string{
serviceURL + "CreateRoom",
serviceURL + "GetRoom",
serviceURL + "ListRooms",
serviceURL + "DeleteRoom",
}
@@ -92,13 +92,13 @@ func NewRoomServiceProtobufClient(baseURL string, client HTTPClient, opts ...twi
}
}
func (c *roomServiceProtobufClient) CreateRoom(ctx context.Context, in *CreateRoomRequest) (*RoomInfo, error) {
func (c *roomServiceProtobufClient) CreateRoom(ctx context.Context, in *CreateRoomRequest) (*Room, error) {
ctx = ctxsetters.WithPackageName(ctx, "livekit")
ctx = ctxsetters.WithServiceName(ctx, "RoomService")
ctx = ctxsetters.WithMethodName(ctx, "CreateRoom")
caller := c.callCreateRoom
if c.interceptor != nil {
caller = func(ctx context.Context, req *CreateRoomRequest) (*RoomInfo, error) {
caller = func(ctx context.Context, req *CreateRoomRequest) (*Room, error) {
resp, err := c.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*CreateRoomRequest)
@@ -109,9 +109,9 @@ func (c *roomServiceProtobufClient) CreateRoom(ctx context.Context, in *CreateRo
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*RoomInfo)
typedResp, ok := resp.(*Room)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*RoomInfo) when calling interceptor")
return nil, twirp.InternalError("failed type assertion resp.(*Room) when calling interceptor")
}
return typedResp, err
}
@@ -121,8 +121,8 @@ func (c *roomServiceProtobufClient) CreateRoom(ctx context.Context, in *CreateRo
return caller(ctx, in)
}
func (c *roomServiceProtobufClient) callCreateRoom(ctx context.Context, in *CreateRoomRequest) (*RoomInfo, error) {
out := new(RoomInfo)
func (c *roomServiceProtobufClient) callCreateRoom(ctx context.Context, in *CreateRoomRequest) (*Room, error) {
out := new(Room)
ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
if err != nil {
twerr, ok := err.(twirp.Error)
@@ -138,26 +138,26 @@ func (c *roomServiceProtobufClient) callCreateRoom(ctx context.Context, in *Crea
return out, nil
}
func (c *roomServiceProtobufClient) GetRoom(ctx context.Context, in *GetRoomRequest) (*RoomInfo, error) {
func (c *roomServiceProtobufClient) ListRooms(ctx context.Context, in *ListRoomsRequest) (*ListRoomsResponse, error) {
ctx = ctxsetters.WithPackageName(ctx, "livekit")
ctx = ctxsetters.WithServiceName(ctx, "RoomService")
ctx = ctxsetters.WithMethodName(ctx, "GetRoom")
caller := c.callGetRoom
ctx = ctxsetters.WithMethodName(ctx, "ListRooms")
caller := c.callListRooms
if c.interceptor != nil {
caller = func(ctx context.Context, req *GetRoomRequest) (*RoomInfo, error) {
caller = func(ctx context.Context, req *ListRoomsRequest) (*ListRoomsResponse, error) {
resp, err := c.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*GetRoomRequest)
typedReq, ok := req.(*ListRoomsRequest)
if !ok {
return nil, twirp.InternalError("failed type assertion req.(*GetRoomRequest) when calling interceptor")
return nil, twirp.InternalError("failed type assertion req.(*ListRoomsRequest) when calling interceptor")
}
return c.callGetRoom(ctx, typedReq)
return c.callListRooms(ctx, typedReq)
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*RoomInfo)
typedResp, ok := resp.(*ListRoomsResponse)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*RoomInfo) when calling interceptor")
return nil, twirp.InternalError("failed type assertion resp.(*ListRoomsResponse) when calling interceptor")
}
return typedResp, err
}
@@ -167,8 +167,8 @@ func (c *roomServiceProtobufClient) GetRoom(ctx context.Context, in *GetRoomRequ
return caller(ctx, in)
}
func (c *roomServiceProtobufClient) callGetRoom(ctx context.Context, in *GetRoomRequest) (*RoomInfo, error) {
out := new(RoomInfo)
func (c *roomServiceProtobufClient) callListRooms(ctx context.Context, in *ListRoomsRequest) (*ListRoomsResponse, error) {
out := new(ListRoomsResponse)
ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out)
if err != nil {
twerr, ok := err.(twirp.Error)
@@ -258,7 +258,7 @@ func NewRoomServiceJSONClient(baseURL string, client HTTPClient, opts ...twirp.C
serviceURL += baseServicePath(clientOpts.PathPrefix(), "livekit", "RoomService")
urls := [3]string{
serviceURL + "CreateRoom",
serviceURL + "GetRoom",
serviceURL + "ListRooms",
serviceURL + "DeleteRoom",
}
@@ -270,13 +270,13 @@ func NewRoomServiceJSONClient(baseURL string, client HTTPClient, opts ...twirp.C
}
}
func (c *roomServiceJSONClient) CreateRoom(ctx context.Context, in *CreateRoomRequest) (*RoomInfo, error) {
func (c *roomServiceJSONClient) CreateRoom(ctx context.Context, in *CreateRoomRequest) (*Room, error) {
ctx = ctxsetters.WithPackageName(ctx, "livekit")
ctx = ctxsetters.WithServiceName(ctx, "RoomService")
ctx = ctxsetters.WithMethodName(ctx, "CreateRoom")
caller := c.callCreateRoom
if c.interceptor != nil {
caller = func(ctx context.Context, req *CreateRoomRequest) (*RoomInfo, error) {
caller = func(ctx context.Context, req *CreateRoomRequest) (*Room, error) {
resp, err := c.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*CreateRoomRequest)
@@ -287,9 +287,9 @@ func (c *roomServiceJSONClient) CreateRoom(ctx context.Context, in *CreateRoomRe
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*RoomInfo)
typedResp, ok := resp.(*Room)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*RoomInfo) when calling interceptor")
return nil, twirp.InternalError("failed type assertion resp.(*Room) when calling interceptor")
}
return typedResp, err
}
@@ -299,8 +299,8 @@ func (c *roomServiceJSONClient) CreateRoom(ctx context.Context, in *CreateRoomRe
return caller(ctx, in)
}
func (c *roomServiceJSONClient) callCreateRoom(ctx context.Context, in *CreateRoomRequest) (*RoomInfo, error) {
out := new(RoomInfo)
func (c *roomServiceJSONClient) callCreateRoom(ctx context.Context, in *CreateRoomRequest) (*Room, error) {
out := new(Room)
ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
if err != nil {
twerr, ok := err.(twirp.Error)
@@ -316,26 +316,26 @@ func (c *roomServiceJSONClient) callCreateRoom(ctx context.Context, in *CreateRo
return out, nil
}
func (c *roomServiceJSONClient) GetRoom(ctx context.Context, in *GetRoomRequest) (*RoomInfo, error) {
func (c *roomServiceJSONClient) ListRooms(ctx context.Context, in *ListRoomsRequest) (*ListRoomsResponse, error) {
ctx = ctxsetters.WithPackageName(ctx, "livekit")
ctx = ctxsetters.WithServiceName(ctx, "RoomService")
ctx = ctxsetters.WithMethodName(ctx, "GetRoom")
caller := c.callGetRoom
ctx = ctxsetters.WithMethodName(ctx, "ListRooms")
caller := c.callListRooms
if c.interceptor != nil {
caller = func(ctx context.Context, req *GetRoomRequest) (*RoomInfo, error) {
caller = func(ctx context.Context, req *ListRoomsRequest) (*ListRoomsResponse, error) {
resp, err := c.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*GetRoomRequest)
typedReq, ok := req.(*ListRoomsRequest)
if !ok {
return nil, twirp.InternalError("failed type assertion req.(*GetRoomRequest) when calling interceptor")
return nil, twirp.InternalError("failed type assertion req.(*ListRoomsRequest) when calling interceptor")
}
return c.callGetRoom(ctx, typedReq)
return c.callListRooms(ctx, typedReq)
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*RoomInfo)
typedResp, ok := resp.(*ListRoomsResponse)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*RoomInfo) when calling interceptor")
return nil, twirp.InternalError("failed type assertion resp.(*ListRoomsResponse) when calling interceptor")
}
return typedResp, err
}
@@ -345,8 +345,8 @@ func (c *roomServiceJSONClient) GetRoom(ctx context.Context, in *GetRoomRequest)
return caller(ctx, in)
}
func (c *roomServiceJSONClient) callGetRoom(ctx context.Context, in *GetRoomRequest) (*RoomInfo, error) {
out := new(RoomInfo)
func (c *roomServiceJSONClient) callListRooms(ctx context.Context, in *ListRoomsRequest) (*ListRoomsResponse, error) {
out := new(ListRoomsResponse)
ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out)
if err != nil {
twerr, ok := err.(twirp.Error)
@@ -495,8 +495,8 @@ func (s *roomServiceServer) ServeHTTP(resp http.ResponseWriter, req *http.Reques
case "CreateRoom":
s.serveCreateRoom(ctx, resp, req)
return
case "GetRoom":
s.serveGetRoom(ctx, resp, req)
case "ListRooms":
s.serveListRooms(ctx, resp, req)
return
case "DeleteRoom":
s.serveDeleteRoom(ctx, resp, req)
@@ -544,7 +544,7 @@ func (s *roomServiceServer) serveCreateRoomJSON(ctx context.Context, resp http.R
handler := s.RoomService.CreateRoom
if s.interceptor != nil {
handler = func(ctx context.Context, req *CreateRoomRequest) (*RoomInfo, error) {
handler = func(ctx context.Context, req *CreateRoomRequest) (*Room, error) {
resp, err := s.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*CreateRoomRequest)
@@ -555,9 +555,9 @@ func (s *roomServiceServer) serveCreateRoomJSON(ctx context.Context, resp http.R
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*RoomInfo)
typedResp, ok := resp.(*Room)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*RoomInfo) when calling interceptor")
return nil, twirp.InternalError("failed type assertion resp.(*Room) when calling interceptor")
}
return typedResp, err
}
@@ -566,7 +566,7 @@ func (s *roomServiceServer) serveCreateRoomJSON(ctx context.Context, resp http.R
}
// Call service method
var respContent *RoomInfo
var respContent *Room
func() {
defer ensurePanicResponses(ctx, resp, s.hooks)
respContent, err = handler(ctx, reqContent)
@@ -577,7 +577,7 @@ func (s *roomServiceServer) serveCreateRoomJSON(ctx context.Context, resp http.R
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *RoomInfo and nil error while calling CreateRoom. nil responses are not supported"))
s.writeError(ctx, resp, twirp.InternalError("received a nil *Room and nil error while calling CreateRoom. nil responses are not supported"))
return
}
@@ -626,7 +626,7 @@ func (s *roomServiceServer) serveCreateRoomProtobuf(ctx context.Context, resp ht
handler := s.RoomService.CreateRoom
if s.interceptor != nil {
handler = func(ctx context.Context, req *CreateRoomRequest) (*RoomInfo, error) {
handler = func(ctx context.Context, req *CreateRoomRequest) (*Room, error) {
resp, err := s.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*CreateRoomRequest)
@@ -637,9 +637,9 @@ func (s *roomServiceServer) serveCreateRoomProtobuf(ctx context.Context, resp ht
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*RoomInfo)
typedResp, ok := resp.(*Room)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*RoomInfo) when calling interceptor")
return nil, twirp.InternalError("failed type assertion resp.(*Room) when calling interceptor")
}
return typedResp, err
}
@@ -648,7 +648,7 @@ func (s *roomServiceServer) serveCreateRoomProtobuf(ctx context.Context, resp ht
}
// Call service method
var respContent *RoomInfo
var respContent *Room
func() {
defer ensurePanicResponses(ctx, resp, s.hooks)
respContent, err = handler(ctx, reqContent)
@@ -659,7 +659,7 @@ func (s *roomServiceServer) serveCreateRoomProtobuf(ctx context.Context, resp ht
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *RoomInfo and nil error while calling CreateRoom. nil responses are not supported"))
s.writeError(ctx, resp, twirp.InternalError("received a nil *Room and nil error while calling CreateRoom. nil responses are not supported"))
return
}
@@ -683,7 +683,7 @@ func (s *roomServiceServer) serveCreateRoomProtobuf(ctx context.Context, resp ht
callResponseSent(ctx, s.hooks)
}
func (s *roomServiceServer) serveGetRoom(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
func (s *roomServiceServer) serveListRooms(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
header := req.Header.Get("Content-Type")
i := strings.Index(header, ";")
if i == -1 {
@@ -691,9 +691,9 @@ func (s *roomServiceServer) serveGetRoom(ctx context.Context, resp http.Response
}
switch strings.TrimSpace(strings.ToLower(header[:i])) {
case "application/json":
s.serveGetRoomJSON(ctx, resp, req)
s.serveListRoomsJSON(ctx, resp, req)
case "application/protobuf":
s.serveGetRoomProtobuf(ctx, resp, req)
s.serveListRoomsProtobuf(ctx, resp, req)
default:
msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
twerr := badRouteError(msg, req.Method, req.URL.Path)
@@ -701,38 +701,38 @@ func (s *roomServiceServer) serveGetRoom(ctx context.Context, resp http.Response
}
}
func (s *roomServiceServer) serveGetRoomJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
func (s *roomServiceServer) serveListRoomsJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "GetRoom")
ctx = ctxsetters.WithMethodName(ctx, "ListRooms")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
reqContent := new(GetRoomRequest)
reqContent := new(ListRoomsRequest)
unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
return
}
handler := s.RoomService.GetRoom
handler := s.RoomService.ListRooms
if s.interceptor != nil {
handler = func(ctx context.Context, req *GetRoomRequest) (*RoomInfo, error) {
handler = func(ctx context.Context, req *ListRoomsRequest) (*ListRoomsResponse, error) {
resp, err := s.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*GetRoomRequest)
typedReq, ok := req.(*ListRoomsRequest)
if !ok {
return nil, twirp.InternalError("failed type assertion req.(*GetRoomRequest) when calling interceptor")
return nil, twirp.InternalError("failed type assertion req.(*ListRoomsRequest) when calling interceptor")
}
return s.RoomService.GetRoom(ctx, typedReq)
return s.RoomService.ListRooms(ctx, typedReq)
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*RoomInfo)
typedResp, ok := resp.(*ListRoomsResponse)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*RoomInfo) when calling interceptor")
return nil, twirp.InternalError("failed type assertion resp.(*ListRoomsResponse) when calling interceptor")
}
return typedResp, err
}
@@ -741,7 +741,7 @@ func (s *roomServiceServer) serveGetRoomJSON(ctx context.Context, resp http.Resp
}
// Call service method
var respContent *RoomInfo
var respContent *ListRoomsResponse
func() {
defer ensurePanicResponses(ctx, resp, s.hooks)
respContent, err = handler(ctx, reqContent)
@@ -752,7 +752,7 @@ func (s *roomServiceServer) serveGetRoomJSON(ctx context.Context, resp http.Resp
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *RoomInfo and nil error while calling GetRoom. nil responses are not supported"))
s.writeError(ctx, resp, twirp.InternalError("received a nil *ListRoomsResponse and nil error while calling ListRooms. nil responses are not supported"))
return
}
@@ -779,9 +779,9 @@ func (s *roomServiceServer) serveGetRoomJSON(ctx context.Context, resp http.Resp
callResponseSent(ctx, s.hooks)
}
func (s *roomServiceServer) serveGetRoomProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
func (s *roomServiceServer) serveListRoomsProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "GetRoom")
ctx = ctxsetters.WithMethodName(ctx, "ListRooms")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
@@ -793,28 +793,28 @@ func (s *roomServiceServer) serveGetRoomProtobuf(ctx context.Context, resp http.
s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
return
}
reqContent := new(GetRoomRequest)
reqContent := new(ListRoomsRequest)
if err = proto.Unmarshal(buf, reqContent); err != nil {
s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
return
}
handler := s.RoomService.GetRoom
handler := s.RoomService.ListRooms
if s.interceptor != nil {
handler = func(ctx context.Context, req *GetRoomRequest) (*RoomInfo, error) {
handler = func(ctx context.Context, req *ListRoomsRequest) (*ListRoomsResponse, error) {
resp, err := s.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*GetRoomRequest)
typedReq, ok := req.(*ListRoomsRequest)
if !ok {
return nil, twirp.InternalError("failed type assertion req.(*GetRoomRequest) when calling interceptor")
return nil, twirp.InternalError("failed type assertion req.(*ListRoomsRequest) when calling interceptor")
}
return s.RoomService.GetRoom(ctx, typedReq)
return s.RoomService.ListRooms(ctx, typedReq)
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*RoomInfo)
typedResp, ok := resp.(*ListRoomsResponse)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*RoomInfo) when calling interceptor")
return nil, twirp.InternalError("failed type assertion resp.(*ListRoomsResponse) when calling interceptor")
}
return typedResp, err
}
@@ -823,7 +823,7 @@ func (s *roomServiceServer) serveGetRoomProtobuf(ctx context.Context, resp http.
}
// Call service method
var respContent *RoomInfo
var respContent *ListRoomsResponse
func() {
defer ensurePanicResponses(ctx, resp, s.hooks)
respContent, err = handler(ctx, reqContent)
@@ -834,7 +834,7 @@ func (s *roomServiceServer) serveGetRoomProtobuf(ctx context.Context, resp http.
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *RoomInfo and nil error while calling GetRoom. nil responses are not supported"))
s.writeError(ctx, resp, twirp.InternalError("received a nil *ListRoomsResponse and nil error while calling ListRooms. nil responses are not supported"))
return
}
@@ -1595,23 +1595,25 @@ func callClientError(ctx context.Context, h *twirp.ClientHooks, err twirp.Error)
}
var twirpFileDescriptor0 = []byte{
// 288 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x4f, 0x4b, 0xc3, 0x40,
0x10, 0xc5, 0x89, 0x8a, 0xc5, 0xa9, 0x55, 0xbb, 0x08, 0x86, 0x78, 0x29, 0x51, 0xb0, 0x1e, 0x4c,
0x50, 0xf1, 0xe4, 0xcd, 0x3f, 0x88, 0x37, 0x89, 0x9e, 0xbc, 0x94, 0x6d, 0x1c, 0x75, 0x31, 0x9b,
0x89, 0x9b, 0x49, 0xac, 0xdf, 0xd0, 0x8f, 0x25, 0xf9, 0xd7, 0x46, 0xd3, 0xd3, 0xce, 0xfe, 0xe6,
0x2d, 0xf3, 0xde, 0x2c, 0x80, 0x21, 0xd2, 0x5e, 0x62, 0x88, 0x49, 0xf4, 0x22, 0x95, 0xe3, 0x87,
0x62, 0xa7, 0xaf, 0xe9, 0x05, 0xa3, 0x8a, 0xba, 0x5f, 0x30, 0xbc, 0x36, 0x28, 0x19, 0x03, 0x22,
0x1d, 0xe0, 0x67, 0x86, 0x29, 0x0b, 0x01, 0x6b, 0xb1, 0xd4, 0x68, 0x5b, 0x23, 0x6b, 0xbc, 0x11,
0x94, 0xb5, 0x38, 0x80, 0x01, 0xea, 0x84, 0xbf, 0x27, 0xac, 0x34, 0x52, 0xc6, 0xf6, 0xca, 0xc8,
0x1a, 0x0f, 0x82, 0xcd, 0x12, 0x3e, 0x55, 0x4c, 0x1c, 0xc3, 0x8e, 0x96, 0xb3, 0x49, 0x22, 0x0d,
0xab, 0x50, 0x25, 0x32, 0xe6, 0xd4, 0x5e, 0x2d, 0x75, 0xdb, 0x5a, 0xce, 0x1e, 0x5a, 0xd8, 0x3d,
0x84, 0xad, 0x3b, 0xe4, 0x7f, 0x53, 0x0b, 0xbb, 0xcd, 0xd4, 0xa2, 0x76, 0x8f, 0x60, 0x78, 0x83,
0x11, 0x76, 0xec, 0x75, 0x84, 0xbb, 0x20, 0xda, 0xc2, 0x34, 0xa1, 0x38, 0xc5, 0xb3, 0x1f, 0x0b,
0xfa, 0x05, 0x78, 0x44, 0x93, 0xab, 0x10, 0xc5, 0x25, 0xc0, 0x22, 0xad, 0x70, 0xbc, 0x7a, 0x25,
0x5e, 0x67, 0x05, 0xce, 0x70, 0xde, 0x2b, 0xe8, 0x7d, 0xfc, 0x4a, 0xe2, 0x02, 0x7a, 0xb5, 0x63,
0xb1, 0x37, 0xef, 0xfe, 0xcd, 0xb0, 0xec, 0xd9, 0x2d, 0xc0, 0xc2, 0x59, 0x6b, 0x66, 0x27, 0x97,
0xb3, 0xbf, 0xb4, 0x57, 0x45, 0xb9, 0x3a, 0x7d, 0xf6, 0xdf, 0x14, 0xbf, 0x67, 0x53, 0x2f, 0x24,
0xed, 0xd7, 0xc2, 0xe6, 0x3c, 0x49, 0xd1, 0xe4, 0x68, 0xfc, 0xf2, 0x4f, 0x1b, 0x38, 0x5d, 0x2f,
0xaf, 0xe7, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9f, 0xf2, 0xc7, 0x37, 0x06, 0x02, 0x00, 0x00,
// 311 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0x3f, 0x4f, 0xf3, 0x30,
0x10, 0xc6, 0x95, 0xb7, 0x2f, 0xa0, 0x5e, 0xa9, 0x68, 0x2d, 0x86, 0x60, 0x96, 0x2a, 0x0c, 0x94,
0x81, 0x54, 0x94, 0x01, 0xe6, 0x02, 0x1b, 0x03, 0x0a, 0x4c, 0x2c, 0x95, 0x1b, 0x4e, 0x60, 0x11,
0xc7, 0xc1, 0x76, 0x42, 0xf9, 0x98, 0x7c, 0x23, 0x64, 0xe7, 0x4f, 0x03, 0xe9, 0xe4, 0xf3, 0xf3,
0x9c, 0xfc, 0xdc, 0xef, 0x64, 0x00, 0x25, 0xa5, 0x08, 0x33, 0x25, 0x8d, 0x24, 0x7b, 0x09, 0x2f,
0xf0, 0x9d, 0x1b, 0x3a, 0x10, 0xf2, 0x05, 0x93, 0x52, 0x0d, 0x3e, 0x61, 0x7c, 0xa3, 0x90, 0x19,
0x8c, 0xa4, 0x14, 0x11, 0x7e, 0xe4, 0xa8, 0x0d, 0x21, 0xf0, 0x3f, 0x65, 0x02, 0x7d, 0x6f, 0xe2,
0x4d, 0xfb, 0x91, 0xab, 0xc9, 0x09, 0x0c, 0x51, 0x64, 0xe6, 0x6b, 0x69, 0xb8, 0x40, 0x99, 0x1b,
0xff, 0xdf, 0xc4, 0x9b, 0x0e, 0xa3, 0x7d, 0x27, 0x3e, 0x95, 0x1a, 0x39, 0x83, 0x91, 0x60, 0xeb,
0x65, 0xc6, 0x94, 0xe1, 0x31, 0xcf, 0x58, 0x6a, 0xb4, 0xdf, 0x73, 0x7d, 0x07, 0x82, 0xad, 0x1f,
0x5a, 0x72, 0x40, 0x60, 0x74, 0xcf, 0xb5, 0xb1, 0xb1, 0xba, 0xca, 0x0d, 0xae, 0x61, 0xdc, 0xd2,
0x74, 0x26, 0x53, 0x6d, 0x83, 0x77, 0x2c, 0x85, 0xf6, 0xbd, 0x49, 0x6f, 0x3a, 0x98, 0x0f, 0xc3,
0x8a, 0x23, 0x74, 0x13, 0x97, 0x5e, 0x70, 0x0a, 0xe3, 0x5b, 0x4c, 0xb0, 0x83, 0x61, 0xdd, 0x1a,
0xc3, 0xd6, 0xc1, 0x21, 0x90, 0x76, 0x63, 0x99, 0x31, 0xff, 0xf6, 0x60, 0x60, 0x85, 0x47, 0x54,
0x05, 0x8f, 0x91, 0x5c, 0x01, 0x6c, 0xb6, 0x42, 0x68, 0x13, 0xd9, 0x59, 0x15, 0xfd, 0x3d, 0x0e,
0x59, 0x40, 0xbf, 0x21, 0x20, 0x47, 0x8d, 0xf7, 0x97, 0x94, 0xd2, 0x6d, 0x56, 0x05, 0x7c, 0x07,
0xb0, 0x19, 0xb1, 0x15, 0xde, 0x01, 0xa4, 0xc7, 0x5b, 0xbd, 0xf2, 0x99, 0xc5, 0xc5, 0xf3, 0xec,
0x95, 0x9b, 0xb7, 0x7c, 0x15, 0xc6, 0x52, 0xcc, 0xaa, 0xc6, 0xfa, 0x3c, 0xd7, 0xa8, 0x0a, 0x54,
0x33, 0xf7, 0x09, 0x6a, 0x71, 0xb5, 0xeb, 0xae, 0x97, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe4,
0x3c, 0x6a, 0xb4, 0x37, 0x02, 0x00, 0x00,
}

View File

@@ -530,7 +530,7 @@ type JoinResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Room *RoomInfo `protobuf:"bytes,1,opt,name=room,proto3" json:"room,omitempty"`
Room *Room `protobuf:"bytes,1,opt,name=room,proto3" json:"room,omitempty"`
Participant *ParticipantInfo `protobuf:"bytes,2,opt,name=participant,proto3" json:"participant,omitempty"`
OtherParticipants []*ParticipantInfo `protobuf:"bytes,3,rep,name=other_participants,json=otherParticipants,proto3" json:"other_participants,omitempty"`
}
@@ -567,7 +567,7 @@ func (*JoinResponse) Descriptor() ([]byte, []int) {
return file_rtc_proto_rawDescGZIP(), []int{6}
}
func (x *JoinResponse) GetRoom() *RoomInfo {
func (x *JoinResponse) GetRoom() *Room {
if x != nil {
return x.Room
}
@@ -851,39 +851,38 @@ var file_rtc_proto_rawDesc = []byte{
0x10, 0x0a, 0x03, 0x73, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x69,
0x64, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08,
0x52, 0x05, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x22, 0x14, 0x0a, 0x12, 0x4e, 0x65, 0x67, 0x6f, 0x74,
0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xba, 0x01,
0x0a, 0x0c, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25,
0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6c,
0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52,
0x04, 0x72, 0x6f, 0x6f, 0x6d, 0x12, 0x3a, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69,
0x70, 0x61, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x76,
0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb6, 0x01,
0x0a, 0x0c, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21,
0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6c,
0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x04, 0x72, 0x6f, 0x6f,
0x6d, 0x12, 0x3a, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74,
0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f,
0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x12, 0x47, 0x0a,
0x12, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61,
0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x76, 0x65,
0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49,
0x6e, 0x66, 0x6f, 0x52, 0x11, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63,
0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x54, 0x0a, 0x16, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x50,
0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63,
0x69, 0x64, 0x12, 0x28, 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x63,
0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x22, 0x15, 0x0a, 0x13,
0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x12, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a,
0x03, 0x73, 0x64, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x64, 0x70, 0x22,
0x51, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x55, 0x70,
0x64, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70,
0x61, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x76,
0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74,
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e,
0x74, 0x12, 0x47, 0x0a, 0x12, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69,
0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e,
0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70,
0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x11, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x61,
0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x54, 0x0a, 0x16, 0x54, 0x72,
0x61, 0x63, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e,
0x54, 0x72, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b,
0x22, 0x15, 0x0a, 0x13, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x12, 0x53, 0x65, 0x73, 0x73, 0x69,
0x6f, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a,
0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70,
0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x64, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x73, 0x64, 0x70, 0x22, 0x51, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61,
0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74,
0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18,
0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69,
0x70, 0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63,
0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x6c, 0x69, 0x76,
0x65, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e,
0x74, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74,
0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x69,
0x76, 0x65, 0x6b, 0x69, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -912,7 +911,7 @@ var file_rtc_proto_goTypes = []interface{}{
(*SessionDescription)(nil), // 9: livekit.SessionDescription
(*ParticipantUpdate)(nil), // 10: livekit.ParticipantUpdate
(TrackType)(0), // 11: livekit.TrackType
(*RoomInfo)(nil), // 12: livekit.RoomInfo
(*Room)(nil), // 12: livekit.Room
(*ParticipantInfo)(nil), // 13: livekit.ParticipantInfo
(*TrackInfo)(nil), // 14: livekit.TrackInfo
}
@@ -931,7 +930,7 @@ var file_rtc_proto_depIdxs = []int32{
7, // 11: livekit.SignalResponse.track_published:type_name -> livekit.TrackPublishedResponse
8, // 12: livekit.SignalResponse.negotiate:type_name -> livekit.NegotiationResponse
11, // 13: livekit.AddTrackRequest.type:type_name -> livekit.TrackType
12, // 14: livekit.JoinResponse.room:type_name -> livekit.RoomInfo
12, // 14: livekit.JoinResponse.room:type_name -> livekit.Room
13, // 15: livekit.JoinResponse.participant:type_name -> livekit.ParticipantInfo
13, // 16: livekit.JoinResponse.other_participants:type_name -> livekit.ParticipantInfo
14, // 17: livekit.TrackPublishedResponse.track:type_name -> livekit.TrackInfo

View File

@@ -6,7 +6,7 @@ option go_package = "github.com/livekit/livekit-server/proto/livekit";
message Node {
string id = 1;
string ip = 2;
uint32 rtc_port = 3;
uint32 num_cpus = 3;
NodeStats stats = 4;
}
@@ -24,13 +24,6 @@ message Room {
int64 creation_time = 5;
}
message RoomInfo {
string sid = 1;
string name = 2;
string node_ip = 3;
int64 creation_time = 4;
}
message ParticipantInfo {
enum State {
// websocket' connected, but not offered yet

View File

@@ -10,8 +10,8 @@ import "model.proto";
service RoomService {
// TODO: how do we secure room service?
// should be accessible to only internal servers, not external
rpc CreateRoom(CreateRoomRequest) returns (RoomInfo);
rpc GetRoom(GetRoomRequest) returns (RoomInfo);
rpc CreateRoom(CreateRoomRequest) returns (Room);
rpc ListRooms(ListRoomsRequest) returns (ListRoomsResponse);
rpc DeleteRoom(DeleteRoomRequest) returns (DeleteRoomResponse);
}
@@ -22,8 +22,11 @@ message CreateRoomRequest {
uint32 max_participants = 3;
}
message GetRoomRequest {
string room = 1;
message ListRoomsRequest {
}
message ListRoomsResponse {
repeated Room rooms = 1;
}
message DeleteRoomRequest {

View File

@@ -59,7 +59,7 @@ message NegotiationRequest {
}
message JoinResponse {
RoomInfo room = 1;
Room room = 1;
ParticipantInfo participant = 2;
repeated ParticipantInfo other_participants = 3;
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/livekit/livekit-server/cmd/cli/client"
"github.com/livekit/livekit-server/pkg/auth"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/routing"
"github.com/livekit/livekit-server/pkg/service"
"github.com/livekit/livekit-server/proto/livekit"
)
@@ -43,12 +44,12 @@ func waitForServerToStart(s *service.LivekitServer) {
}
}
func withTimeout(t *testing.T, f func() bool) {
func withTimeout(t *testing.T, description string, f func() bool) {
ctx, _ := context.WithTimeout(context.Background(), time.Second)
for {
select {
case <-ctx.Done():
t.Fatal("timed out")
t.Fatal("timed out: " + description)
case <-time.After(10 * time.Millisecond):
if f() {
return
@@ -76,19 +77,28 @@ func createServer() *service.LivekitServer {
if err != nil {
panic(fmt.Sprintf("could not create config: %v", err))
}
s, err := service.InitializeServer(serverConfig, &StaticKeyProvider{})
currentNode, err := routing.NewLocalNode(serverConfig)
if err != nil {
panic(err)
}
// local routing and store
router := routing.NewLocalRouter(currentNode)
roomStore := service.NewLocalRoomStore()
s, err := service.InitializeServer(serverConfig, &StaticKeyProvider{}, roomStore, router, currentNode)
if err != nil {
panic(fmt.Sprintf("could not create server: %v", err))
}
roomClient = livekit.NewRoomServiceJSONClient(fmt.Sprintf("http://localhost:%d", serverConfig.APIPort), &http.Client{})
roomClient = livekit.NewRoomServiceJSONClient(fmt.Sprintf("http://localhost:%d", serverConfig.Port), &http.Client{})
return s
}
// creates a client and runs against server
func createClient(name string) *client.RTCClient {
token := joinToken(testRoom, name)
ws, err := client.NewWebSocketConn(fmt.Sprintf("ws://localhost:%d", serverConfig.RTCPort), token)
ws, err := client.NewWebSocketConn(fmt.Sprintf("ws://localhost:%d", serverConfig.Port), token)
if err != nil {
panic(err)
}

View File

@@ -10,7 +10,6 @@ import (
"github.com/twitchtv/twirp"
"github.com/livekit/livekit-server/pkg/logger"
"github.com/livekit/livekit-server/pkg/service"
"github.com/livekit/livekit-server/proto/livekit"
)
@@ -20,7 +19,7 @@ func TestClientCouldConnect(t *testing.T) {
waitUntilConnected(t, c1, c2)
// ensure they both see each other
withTimeout(t, func() bool {
withTimeout(t, "c1 and c2 could connect", func() bool {
if len(c1.RemoteParticipants()) == 0 || len(c2.RemoteParticipants()) == 0 {
return false
}
@@ -45,7 +44,7 @@ func TestSinglePublisher(t *testing.T) {
// a new client joins and should get the initial stream
c3 := createClient("c3")
withTimeout(t, func() bool {
withTimeout(t, "c2 should receive two tracks", func() bool {
if len(c2.SubscribedTracks()) == 0 {
return false
}
@@ -61,7 +60,7 @@ func TestSinglePublisher(t *testing.T) {
// ensure that new client that has joined also received tracks
waitUntilConnected(t, c3)
withTimeout(t, func() bool {
withTimeout(t, "c2 should receive two tracks", func() bool {
if len(c3.SubscribedTracks()) == 0 {
return false
}
@@ -76,7 +75,6 @@ func TestSinglePublisher(t *testing.T) {
func TestMain(m *testing.M) {
logger.InitDevelopment()
s := createServer()
service.AuthRequired = true
go func() {
s.Start()
}()
@@ -86,7 +84,7 @@ func TestMain(m *testing.M) {
// create test room
token := createRoomToken()
header := make(http.Header)
logger.GetLogger().Debugw("auth token", "token", token)
logger.Debugw("auth token", "token", token)
header.Set("Authorization", "Bearer "+token)
tctx, err := twirp.WithHTTPRequestHeaders(context.Background(), header)
if err != nil {