定制信令(signaling)解决方案
信令(signaling)是与远程端点进行通信以建立对等连接的过程。WebRTC标准不对WebRTC信令强制执行任何特定的协议或解决方案。相反,它只是声明必须通过开发人员选择的任何方式(其信令解决方案)在远程对等方之间传输一些不透明的消息。
通常,除了两个试图相互连接的对等方之外,信令解决方案还涉及第三方服务器。刚开始使用对等连接时,使用第三方服务器似乎违反直觉,但通常来说,第三方服务器是一个易于访问的服务器(公共IP),充当中继并启用即使在复杂的网络场景中(一个或两个对等点都位于NAT之后),WebRTC仍可以发现两个对等点之间的直接路由,否则两个对等点就不可能直接发现彼此。信令服务器提供的服务有时也称为某种发现服务或身份服务(因为它使每个对等方的身份对另一方都可用)。
NamedPipeSignaler
在本教程中,我们使用NamedPipeSignaler
中发现的examples/TestNetCoreConsole/NamedPipeSignaler
在GitHub的仓库。这是一个简单的信令解决方案,顾名思义,该解决方案基于命名管道,它允许在本地主机上进行本地对等设备发现和连接,而无需进行任何配置。这不是生产就绪的解决方案,但是对于本教程而言,它的好处是非常简单,可以避免任何网络配置和潜在问题。
安装
NamedPipeSignaler
在TestNetCoreConsole
示例应用程序中使用类的最简单方法是将examples/TestNetCoreConsole/NamedPipeSignaler.cs
文件与TestNetCoreConsole.csproj
项目一起复制。这避免了在项目中进行任何参考设置或任何其他类型的项目配置的需要。
管道创建
无需了解NamedPipeSignaler
该类在本教程中的工作方式。但是出于好奇,这是建立连接的方式(如果不感兴趣,读者可以跳到下面的“ 设置信号器”部分):
- 尝试创建管道服务器。
- 如果成功,则此对等方是第一个对等方,并将充当server。
- 如果失败,则另一个对等方已经创建了该管道服务器,因此该对等方将充当client。
- 如果充当服务器:
- 等待远程对等方将其客户端管道连接到此服务器。
- 创建反向管道客户端,并连接到远程对等方的反向管道服务器。
- 如果担任客户:
- 连接到另一个对等方创建的管道服务器。
- 创建一个反向管道服务器,然后等待服务器与其反向管道客户端重新连接。
- 此时,两个对等方都具有用于发送数据的客户端管道和用于接收数据的服务器管道,并且可以进行通信。
- 启动后台任务以读取来自远程对等方的传入消息,然后等待。
我们在这里注意到,尽管WebRTC依赖对等连接,但两个对等并不严格相等。这不仅是由于该特定信令解决方案是非对称的,而且还因为建立WebRTC连接的非对称性质。一般来说,我们指的是对发起连接作为主叫方和其他同行作为被叫方。
设置信号器
继续编辑Program.cs
文件并添加以下内容:
创建与现有对等连接关联的信号器。
var signaler = new NamedPipeSignaler.NamedPipeSignaler(pc, "testpipe");
将处理程序连接到信令程序的消息,并将其转发到对等连接。
signaler.SdpMessageReceived += async (SdpMessage message) => {
// Note: we use 'await' to ensure the remote description is applied
// before calling CreateAnswer(). Failing to do so will prevent the
// answer from being generated, and the connection from establishing.
await pc.SetRemoteDescriptionAsync(message);
if (message.Type == SdpMessageType.Offer)
{ pc.CreateAnswer(); } };
signaler.IceCandidateReceived += (IceCandidate candidate) => { pc.AddIceCandidate(candidate); };
除了将消息转发到对等连接外,一旦应用了从呼叫者那里收到的远程要约,我们也将自动PeerConnection.CreateAnswer()
在被呼叫者对等者上进行呼叫。这确保了最小的等待时间,但也意味着被叫方自动接受任何来电。或者,典型的应用程序将显示一些用户反馈,并等待确认以接受来电。
启动信号器并将其连接到远程对等方的信号器。
await signaler.StartAsync();
最后一个呼叫将阻塞,直到两个信号器相互连接为止。
此时,信号器已正常工作。但是,如上所述,它将等待TestNetCoreConsole
应用程序的第二个实例连接。当前,除非本地计算机至少具有2个网络摄像头和2个麦克风,否则这将无法工作,因为两个实例都将尝试捕获网络摄像头和麦克风,并且其中一个实例将无法捕获并终止,直到程序到达信号发源点为止开始。
可选的音频和视频捕获
为了使用2个实例TestNetCoreConsole
和一个麦克风和摄像头测试信号器,我们需要其中一个实例不要尝试打开音频和视频捕获设备。为此,我们有一些命令行参数来控制音频和视频捕获。
继续编辑Program.cs
文件:
在该Main
功能的顶部,检查用户提供的命令行参数上是否存在音频和视频捕获参数。我们将这些参数命名为-v
/,--video
以启用视频捕获,和-a
/ --audio
来启用音频捕获。
bool needVideo = Array.Exists(args, arg => (arg == "-v") || (arg == "--video"));
bool needAudio = Array.Exists(args, arg => (arg == "-a") || (arg == "--audio"));
使用刚刚定义的布尔值将对的调用包装AddLocal(Audio|Video)TrackAsync
到if
块中。我们还打印一些控制台消息,以便用户可以确认是否确实考虑了这些标志。这对于避免出错很有用,因为我们将运行该应用程序的2个实例,一个实例带有标志,另一个实例带有标志。我们还将在该块中移动收发器的代码。
// Record video from local webcam, and send to remote peer
if (needVideo) { Console.WriteLine("Opening local webcam...");
localVideoTrack = await LocalVideoTrack.CreateFromDeviceAsync(); videoTransceiver = pc.AddTransceiver(MediaKind.Video);
videoTransceiver.DesiredDirection = Transceiver.Direction.SendReceive;
videoTransceiver.LocalVideoTrack = localVideoTrack; }
// Record audio from local microphone, and send to remote peer
if (needAudio) { Console.WriteLine("Opening local microphone...");
localAudioTrack = await LocalAudioTrack.CreateFromDeviceAsync();
audioTransceiver = pc.AddTransceiver(MediaKind.Audio);
audioTransceiver.DesiredDirection = Transceiver.Direction.SendReceive;
audioTransceiver.LocalAudioTrack = localAudioTrack; }
建立信号器连接
此时,示例应用程序已准备好建立信号器连接。也就是说,TestNetCoreConsole
可以启动该应用程序的2个实例,并且它们的NamedPipeSignaler
实例将彼此连接。但是请注意,我们还没有完成对等体,因此WebRTC对等连接本身尚未建立。
启动示例应用程序的2个实例:
- 一个带有音频/视频标志的捕获器
- 一个没有任何标志的接收者
1号(捕获器)
dotnet run TestNetCoreConsole -- --audio --video
2号(接收机)
dotnet run TestNetCoreConsole
这两个终端应打印一些消息,并最终指示信号发送器连接成功:
Signaler connection established.
原创文章,作者:游戏开发极客,如若转载,请注明出处:https://hololens2.cn/hololens2-%e5%9f%ba%e4%ba%8eweb-rtc%e7%9a%84%e8%bf%9c%e7%a8%8b%e5%bc%80%e5%8f%916/