3

I have a fully working peerTopeer (P1, P2) webRTC. To handle peerTopeer failures, I am trying for a simple exchange of bytes via a server in c# between P1 and P2 on a windows machine, as I don't want to develop a turn server by specs. I have also tried to find an open source c# server turn server with turn message but its not working (able to parse request but response seems to be not accepted by latest chrome/MS Edge chromium based)

Simple C# relay bridge server:

With simple udp/tcp listener and exchange of bytes with peers, (P1 to P2 and P2 to P1) and forcing bridge machine IP as candidate I am able to achieve connections and streaming data (bytes) are exchanged. However unable to see video/hear audio on peers and also after some exchange, the connections are dropped with connectionState failed on the client side.

Q1. It should have worked, what is going wrong?

Q2. Any opensource c# implementation of stun and turn (simple one)?

I appreciate any help in this regard.


Server and Client code samples:

Listen to tcp / udp(not in sample)

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));
        }
    }

ProcessData (exchange stream 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);
        }
    }

On the client side (Javascript / typescript), forcing the candidate as bridge server

SignalType.Candidate...
candidate = new RTCIceCandidate(Switch the SDP(messageJson.candidate,
                    BridgeServerAddress, "2525", "tcp"));
m_PeerConnection.addIceCandidate(candidate)
Guru_07
  • 362
  • 3
  • 15
  • Are you trying to multiplex your signaling server with TURN? – Patrick Roberts Dec 20 '19 at 16:25
  • I am trying to multiplex stream data with a server like TURN Similar to SFU box or the kind but a very simple one – Guru_07 Dec 20 '19 at 16:27
  • TURN _is_ to tunnel streaming data between peers that can't directly connect due to NAT failure. When you say "stream data", are you talking about the signaling process? – Patrick Roberts Dec 20 '19 at 16:31
  • No, signaling is not a problem. Its a "Peer<->Bridge<->Peer" without TURN. If this is not achievable, I am also looking for simple way to have own TURN server in C# – Guru_07 Dec 20 '19 at 16:34
  • TURN is the only supported bridge for P2P. If you want to implement a non-standard alternative, you won't find browser support for UDP-based streaming unless you make it indistinguishable from the TURN protocol from the peers' perspective. – Patrick Roberts Dec 20 '19 at 16:35
  • Thanks, I understand your suggestion @PatrickRoberts But I also believe I am trying to route the Peers data via a server (as u termed non-standard alternative :-)). It should be possible? similar to a hardware router or something which just routes the bytes/packets? Is there any specifics missing? – Guru_07 Dec 20 '19 at 16:40
  • Yes, browsers will most likely reject your custom solution because they will only allow TURN for P2P streaming. So, unless the API for your custom solution is indistinguishable from TURN to the browsers, it won't work. – Patrick Roberts Dec 20 '19 at 16:42
  • Did you manage to create a simple TURN bridge, or get turnserver/turnmessage to work? – Benni May 24 '21 at 13:10

1 Answers1

1

Simply modifying the ice candidate you got from P2P is unlikely to work since TCP candidates work a bit differently. And a TURN server is very different from a simple bridge.

The following SDP contains a TCP candidate with tcptype passive which will make the other side establish a connection to it. Feed it into setRemoteDescription, then create an answer and call setLocalDescription with the answer.

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

The browser should establish a connection to port 31337 on localhost (note that Firefox doesn't allow localhost ICE by default so try this in Chrome first). From there, you'll have to process ICE, decrypt SRTP etc.

Philipp Hancke
  • 15,855
  • 2
  • 23
  • 31
  • Hello, I am currently developing a group call, I am developing on the ios app and I'm having a hard time when both peers have each other's SDP but when the screen is black, when I called with an android app and my video stream was there. Do you know how to solve this problem, I have spent a lot of time to answer this problem. Sorry about my English level. – Hiền Đỗ Dec 21 '19 at 15:02
  • @HiềnĐỗ I faced similar issue as well, adding stream/tracks to PC "only once" resolved the issues. Also try to check if stream.id. Its very delicate but when done correctly it surely works! – Guru_07 Dec 22 '19 at 01:52
  • @Guru_07 Thanks for your answer, I have set a streamID = "stream" for localview and I don't really understand this id setting, what should I do next with this streamId? – Hiền Đỗ Dec 22 '19 at 13:14
  • @HiềnĐỗ Here's sample code that worked for me (blank video issue): In PeerConnection.ontrack event if (targetPeerConnection[stream.id]) return; // stream already added targetPeerConnection[stream.id] = true; hope this will work for you.Note: I am using webrtc adapter.js and stream.id is already set (I am just using it) – Guru_07 Dec 23 '19 at 02:05
  • @Philipp Hancke: Thanks for the suggestions. Since its passive, incoming connections gets blocked due to firewall and NAT etc. Only the server is reachable by every client! – Guru_07 Dec 23 '19 at 02:13