webrtc入门:7.apprtc下的信令服务器collider

webrtc入门:7.apprtc下的信令服务器collider,第1张

webrtc入门教学的第5章中, 5.websockets下传递sdp和ice,就是一个信令服务器,信令服务器的作用就是用来传输对方的sdp和ice

apprtc下的信令服务器collider,做的也是这些事情,只不过apprtc有房间号的需求,第一个用户需要先创建一个房间,把这个房间号发给对方,对方就能通过这个房间号来找到自己。

collider虽然实现了很多形式的服务,https和wss,通常在信令服务器中用的是wss因为需要互换信息。

func (c *Collider) wsHandler(ws *websocket.Conn) {
	var rid, cid string

	registered := false

	var msg wsClientMsg
loop:
	for {
		err := ws.SetReadDeadline(time.Now().Add(time.Duration(wsReadTimeoutSec) * time.Second))
		if err != nil {
			c.wsError("ws.SetReadDeadline error: "+err.Error(), ws)
			break
		}

		err = websocket.JSON.Receive(ws, &msg)
		if err != nil {
			if err.Error() != "EOF" {
				c.wsError("websocket.JSON.Receive error: "+err.Error(), ws)
			}
			break
		}

		switch msg.Cmd {
		//进入房间(不存在先创建)
		case "register":
			if registered {
				c.wsError("Duplicated register request", ws)
				break loop
			}
			if msg.RoomID == "" || msg.ClientID == "" {
				c.wsError("Invalid register request: missing 'clientid' or 'roomid'", ws)
				break loop
			}
			if err = c.roomTable.register(msg.RoomID, msg.ClientID, ws); err != nil {
				c.wsError(err.Error(), ws)
				break loop
			}
			registered, rid, cid = true, msg.RoomID, msg.ClientID
			c.dash.incrWs()

			defer c.roomTable.deregister(rid, cid)
			break
		case "send":
			if !registered {
				c.wsError("Client not registered", ws)
				break loop
			}
			if msg.Msg == "" {
				c.wsError("Invalid send request: missing 'msg'", ws)
				break loop
			}
			c.roomTable.send(rid, cid, msg.Msg)
			break
		default:
			c.wsError("Invalid message: unexpected 'cmd'", ws)
			break
		}
	}
	// This should be unnecessary but just be safe.
	ws.Close()
}

在一个房间中,有一个用户列表,房间号。clients用来厨房用户列表,当一个用户连接到信令服务器,如果他没有带房间号,那么就给他创建一个房间号,并成为里面的一员,如果用户进入信令服务器的时候带了一个房间号,会进入这个房间,并和这个房间的成员进行通讯。比较需要注意的是,collider默认的房间最多人数是两个,const maxRoomCapacity = 2

type room struct {
	parent *roomTable
	id     string
	// A mapping from the client ID to the client object.
	clients         map[string]*client
	registerTimeout time.Duration
	roomSrvUrl      string
}

第一个用户进来创建房间:

// roomLocked gets or creates the room without acquiring the lock. Used when the caller already acquired the lock.
func (rt *roomTable) roomLocked(id string) *room {
	if r, ok := rt.rooms[id]; ok {
		return r
	}
	rt.rooms[id] = newRoom(rt, id, rt.registerTimeout, rt.roomSrvUrl)
	log.Printf("Created room %s", id)

	return rt.rooms[id]
}

接着创建client

func (rm *room) client(clientID string) (*client, error) {
	if c, ok := rm.clients[clientID]; ok {
		return c, nil
	}
	if len(rm.clients) >= maxRoomCapacity {
		log.Printf("Room %s is full, not adding client %s", rm.id, clientID)
		return nil, errors.New("Max room capacity reached")
	}

	var timer *time.Timer
	if rm.parent != nil {
		timer = time.AfterFunc(rm.registerTimeout, func() {
			if c := rm.clients[clientID]; c != nil {
				rm.parent.removeIfUnregistered(rm.id, c)
			}
		})
	}
	rm.clients[clientID] = newClient(clientID, timer)

	log.Printf("Added client %s to room %s", clientID, rm.id)

	return rm.clients[clientID], nil
}

值得注意的是,一开始第一个用法发送的消息会先放在缓存中,等第二个用户来的时候,把信息发给第二个用户。

func (rm *room) register(clientID string, rwc io.ReadWriteCloser) error {
	c, err := rm.client(clientID)
	if err != nil {
		return err
	}
	if err = c.register(rwc); err != nil {
		return err
	}

	log.Printf("Client %s registered in room %s", clientID, rm.id)

	// Sends the queued messages from the other client of the room.
	if len(rm.clients) > 1 {
		for _, otherClient := range rm.clients {
			otherClient.sendQueued(c)
		}
	}
	return nil
}

整个过程如log所示:

2022/05/13 01:49:40 Created room 902551569
2022/05/13 01:49:40 Added client 28470778 to room 902551569
2022/05/13 01:49:40 Client 28470778 registered in room 902551569
2022/05/13 01:49:48 Added client 19348598 to room 902551569
2022/05/13 01:49:48 Client 19348598 registered in room 902551569
2022/05/13 01:49:48 Sent queued messages from 28470778 to 19348598

这以后,房间里就存在两个用户,以后发的消息都是通过case "send":的分支。

这样就完成了整个sdpice的交换过程了。一般就能够进行视频通话。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/928183.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-17
下一篇 2022-05-17

发表评论

登录后才能评论

评论列表(0条)

保存