C#编写的简单Webrtc中继桥接服务器

3
我有一个完全工作的点对点 (P1, P2) WebRTC。为了处理点对点故障,我正在尝试在 Windows 机器上通过 C# 服务器进行字节简单交换来实现 P1 和 P2 之间的通信,因为我不想按规格开发转换服务器。我还尝试找到一个开源的 C# 服务器(转换服务器)(转换消息),但它无法使用(能够解析请求,但响应似乎不能被最新的 Chrome / MS Edge 基于Chromium内核接受)。
简单的 C# 中继桥服务器:
通过简单的UDP/TCP监听器并与对等方(P1 到 P2 和 P2 到 P1)交换字节来强制桥接机器IP作为候选者,我能够建立连接并交换数据(字节)。然而,在对等方无法看到视频/听到音频,并且在一些交换之后,连接会因客户端的连接状态失败而断开。
Q1.它应该能够工作,出了什么问题?
Q2.是否有stun和turn的开源C#实现(简单的)?
我非常感谢在这方面提供任何帮助。
服务器和客户端代码示例:
监听TCP/UDP(不在示例中)
public void ListenTCP(int port) {
        TcpListener listener = new TcpListener(IPAddress.Any, port);
        listener.Start();
        while (true){
            TcpClient tcpClient = listener.AcceptTcpClient();
            ..........add endpoint to list
            var bytes = readfromtcpstream.......;
            Task.Run(() => ProcessData(tcpClient.Client.RemoteEndPoint, bytes));
        }
    }

处理数据(交换流字节)
private void Process_DATA(IPEndPoint fromEndPoint, byte[] bytes) {
        foreach (var endpoint in list) { //distribute to all other peers
            if (endpoint == fromEndPoint) continue;
            endpoint's TCPClient.Send(bytes);
        }
    }

在客户端(Javascript/TypeScript)中,强制将候选人作为桥接服务器。
SignalType.Candidate...
candidate = new RTCIceCandidate(Switch the SDP(messageJson.candidate,
                    BridgeServerAddress, "2525", "tcp"));
m_PeerConnection.addIceCandidate(candidate)

你是否正在尝试使用TURN多路复用你的信令服务器? - Patrick Roberts
我正尝试使用类似于TURN的服务器对流数据进行复用,类似于SFU那样的盒子,但是一个非常简单的版本。 - Guru_07
TURN是一种用于在因NAT故障而无法直接连接的对等方之间隧道传输数据的协议。当你说“传输数据”时,你是指信令过程吗? - Patrick Roberts
不,信令不是问题。 这是一个没有TURN的“Peer<->Bridge<->Peer”。 如果这不可行,我也在寻找在C#中拥有自己的简单TURN服务器的方法。 - Guru_07
谢谢,我理解了你的建议@PatrickRoberts。 但我也相信我正在尝试通过服务器路由对等方数据(就像您所说的非标准替代方案:-))。这应该是可能的吧?类似于硬件路由器或其他仅路由字节/数据包的东西?有什么具体细节缺失吗? - Guru_07
显示剩余3条评论
1个回答

1

仅仅修改从P2P获取的ICE候选者可能不起作用,因为TCP候选者的工作方式有所不同。而TURN服务器与简单桥接非常不同。

以下SDP包含一个带有tcptype被动的TCP候选者,这将使另一侧建立到它的连接。将其提供给setRemoteDescription,然后创建一个应答并使用该应答调用setLocalDescription。

v=0
o=- 2576067654554894849 3 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio
a=msid-semantic: WMS
m=audio 9 UDP/TLS/RTP/SAVPF 111
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:2698387310 1 tcp 25042943 127.0.0.1 31337 typ host tcptype passive generation 0
a=ice-ufrag:server
a=ice-pwd:Kv6yCw1HiZ1/6uNExYcE28pO
a=fingerprint:sha-256 22:46:36:8D:B1:CD:08:7B:A1:60:86:BF:95:90:06:4B:EA:47:D9:74:24:FF:6D:2F:1C:09:5B:C1:F5:8D:CC:B2
a=setup:actpass
a=mid:audio
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=recvonly
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1

浏览器应该在本地主机的端口31337上建立连接(请注意,Firefox默认不允许localhost ICE,因此请先在Chrome中尝试)。 从那里开始,您将需要处理ICE,解密SRTP等。

你好,我目前正在开发一个群组通话功能,我正在开发iOS应用程序,但当两个用户都有对方的SDP时,屏幕是黑屏状态,但当我使用安卓应用进行通话时,我的视频流是正常的。你知道如何解决这个问题吗?我已经花了很多时间来解决这个问题。对于我的英语水平表示抱歉。 - Hiền Đỗ
@HiềnĐỗ 我也遇到了类似的问题,将流/轨道添加到PC“仅一次”就解决了问题。还要尝试检查流ID。虽然非常微妙,但如果正确执行,它肯定会起作用! - Guru_07
谢谢您的回答,我已经为本地视图设置了一个streamID =“stream”,但我并不真正理解这个id设置,接下来我该如何处理这个streamId? - Hiền Đỗ
@HiềnĐỗ 这是我用过的样例代码(空白视频问题): 在 PeerConnection.ontrack 事件中if (targetPeerConnection[stream.id]) return; // 流已经添加 targetPeerConnection[stream.id] = true;希望这对你有用。注意:我正在使用 webrtc adapter.js,stream.id 已经设置好了(我只是在使用它)。 - Guru_07
@Philipp Hancke:感谢您的建议。由于被动性,传入连接由于防火墙和NAT等原因被阻止。只有服务器可以被每个客户端访问! - Guru_07

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接