[MediaSoup---Source Code] (2) Router

Overview

Router: Routing object, similar to the function of a room, saves the subscription relationship between streams. It receives the data of the Producer and forwards it to the Consumer who subscribes to the Producer.

Router inherits the following classes:

RTC::Transport::Listener,RTC::RtpObserver::Listener,Channel::ChannelSocket::RequestHandler

RTC::Transport, which is used to transmit real-time audio and video data between mediasoup and the client

RTC::RtpObserver, an interface for observing and processing Real-Time Transport Protocol (RTP) data

Channel::ChannelSocket is used for transmission between response and upper layer

{   //router和房间是一对一的关系,一个router就表示一个房间。当router接收到房间内成员的RTP数据后,会转发给所有房间内的其它成员,或者其它worker。
	class Router : public RTC::Transport::Listener,
	               public RTC::RtpObserver::Listener,
	               public Channel::ChannelSocket::RequestHandler
The process of creating a Router room

 In the Worker layer, first the upper layer will pass in a signaling to create a Router, which will first reach the Worker.

inline void Worker::HandleRequest(Channel::ChannelRequest* request)

 Enter the room creation through type judgment, where the mapping relationship between roomid and Router instance is saved in Worker.

        //创建房间
		case Channel::ChannelRequest::MethodId::WORKER_CREATE_ROUTER:
		{
			std::string routerId;//保存上层传递的roomid

			try
			{   
				//根据上层信令传入的roomid来创建底层的房间概念
				SetNewRouterIdFromData(request->data, routerId);
			}
			catch (const MediaSoupError& error)
			{
				MS_THROW_ERROR("%s [method:%s]", error.what(), request->method.c_str());
			}
            //创建好了Router与Router内处理各种消息的事宜
			auto* router = new RTC::Router(this->shared, routerId, this);
            //把routerId和router实例进行绑定
			this->mapRouters[routerId] = router;

			MS_DEBUG_DEV("Router created [routerId:%s]", routerId.c_str());

			request->Accept();

			break;
		}
Router constructor
	/* Instance methods. */
    // 实例化`Router` 类并注册其消息处理程序的构造函数。
	Router::Router(RTC::Shared* shared, const std::string& id, Listener* listener)
	  : id(id), shared(shared), listener(listener)
	{
		MS_TRACE();
        /*
		这段代码是C++中的函数调用,用于将一个请求处理程序注册到一个通道消息注册器中。具体来说,这个函数调用的参数包括:
        -`this->id`:表示当前对象的id或标识符。
        -`channelRequestHandler`:指向请求处理函数的指针。
        -`payloadChannelRequestHandler`:指向负载请求处理函数的指针,此处为nullptr,表示没有负载请求处理函数。
        -`payloadChannelNotificationHandler`:指向负载通知处理函数的指针,此处为nullptr,表示没有负载通知处理函数。
        通过注册请求处理程序,可以在接收到相应的通道消息时,调用相应的处理函数对消息进行处理。这个函数调用是一种常见的使用C++进行事件驱动编程的方式。
		*/
		// NOTE: This may throw.
		this->shared->channelMessageRegistrator->RegisterHandler(
		  this->id,
		  /*channelRequestHandler*/ this,
		  /*payloadChannelRequestHandler*/ nullptr,
		  /*payloadChannelNotificationHandler*/ nullptr);
	}

An in-depth analysis of the above code shows that RTC::Shared and Listener are first held in the Router.

RTC::Shared is actually shared in Worker, and Listener is Worker.

There is an important point in the constructor. Let's analyze this->shared->channelMessageRegistrator->RegisterHandler. The meaning of this call is to register the current Router as a processing function that responds to channel messages. If the channel responds The message will be automatically transferred to the Router for corresponding processing. The saved method is mapping roomid to room instance.

/将当前路由器实例注册为消息处理程序。
//`RegisterHandler()` 方法为 mediasoup 应用程序提供通用消息通信区域,并可将不同的消息分发给不同的路由器实例进行处理。
void ChannelMessageRegistrator::RegisterHandler(
  const std::string& id,//当前路由器实例的 ID,用于标识路由器实例
  Channel::ChannelSocket::RequestHandler* channelRequestHandler,//指向处理特定类型的通用请求的函数的指针
  PayloadChannel::PayloadChannelSocket::RequestHandler* payloadChannelRequestHandler,//通用请求和通知处理程序,这些处理程序用于处理特定类型的请求和通知消息
  PayloadChannel::PayloadChannelSocket::NotificationHandler* payloadChannelNotificationHandler)
{
	MS_TRACE();
    //channelRequestHandler理论上为创建Router时候的实例
	if (channelRequestHandler != nullptr)
	{
		if (this->mapChannelRequestHandlers.find(id) != this->mapChannelRequestHandlers.end())
		{
			MS_THROW_ERROR("Channel request handler with ID %s already exists", id.c_str());
		}
        //把id作为key,处理特定类型的通用请求的函数的指针作为value保存
		this->mapChannelRequestHandlers[id] = channelRequestHandler;
	}
    //理论说用transport的时候会进行绑定
	if (payloadChannelRequestHandler != nullptr)
	{   //如果存在旧的,就先删除
		if (this->mapPayloadChannelRequestHandlers.find(id) != this->mapPayloadChannelRequestHandlers.end())
		{
			if (channelRequestHandler != nullptr)
			{
				this->mapChannelRequestHandlers.erase(id);
			}

			MS_THROW_ERROR("PayloadChannel request handler with ID %s already exists", id.c_str());
		}
        //重新为本次分配
		this->mapPayloadChannelRequestHandlers[id] = payloadChannelRequestHandler;
	}

	if (payloadChannelNotificationHandler != nullptr)
	{
		if (
		  this->mapPayloadChannelNotificationHandlers.find(id) !=
		  this->mapPayloadChannelNotificationHandlers.end())
		{
			if (channelRequestHandler != nullptr)
			{
				this->mapChannelRequestHandlers.erase(id);
			}

			if (payloadChannelRequestHandler != nullptr)
			{
				this->mapPayloadChannelRequestHandlers.erase(id);
			}

			MS_THROW_ERROR("PayloadChannel notification handler with ID %s already exists", id.c_str());
		}

		this->mapPayloadChannelNotificationHandlers[id] = payloadChannelNotificationHandler;
	}
}

When a channel message occurs, the corresponding Router instance will be first searched for through the ID.

//通过路由器ID查找相应的处理函数
Channel::ChannelSocket::RequestHandler* ChannelMessageRegistrator::GetChannelRequestHandler(
  const std::string& id)
{
	MS_TRACE();

	auto it = this->mapChannelRequestHandlers.find(id);

	if (it != this->mapChannelRequestHandlers.end())
	{
		return it->second;
	}
	else
	{
		return nullptr;
	}
}

Trigger the above in Worker

		default:
		{
			try
			{   //事件驱动机制通过id来查找相对应的处理模块
				auto* handler =
				  this->shared->channelMessageRegistrator->GetChannelRequestHandler(request->handlerId);

				if (handler == nullptr)
				{
					MS_THROW_ERROR("Channel request handler with ID %s not found", request->handlerId.c_str());
				}
                //一般是Router::HandleRequest
				handler->HandleRequest(request);
			}
			catch (const MediaSoupTypeError& error)
			{
				MS_THROW_TYPE_ERROR("%s [method:%s]", error.what(), request->method.c_str());
			}
			catch (const MediaSoupError& error)
			{
				MS_THROW_ERROR("%s [method:%s]", error.what(), request->method.c_str());
			}

			break;
		}

After the above turnover, the processing in the Router comes back

    //房间内部处理指令
	void Router::HandleRequest(Channel::ChannelRequest* request)

Guess you like

Origin blog.csdn.net/qq_40179458/article/details/133162522