echo1241 / echo

0 stars 0 forks source link

[TroubleShooting] WebRTC N:M 연결 시도 시 메시지를 제대로 수신하지 못하는 이슈 #51

Closed HyeonjinChoi closed 2 months ago

HyeonjinChoi commented 2 months ago

WebRTC의 Mesh 방식을 통해 화상통화를 구현하던 중 N:M 시도 시 연결이 제대로 되지 않는 이슈가 발생했습니다.

이슈

P2P 연결을 위해서 새로운 Peer가 WebSocket에 연결될 때마다 새로운 RTCPeerConnection을 생성하였습니다.

이를 바탕으로 각 Peer들이 서로 offer와 answer을 순서대로 교환을 해야 했는데,

1:1 화상통화까지는 문제가 발생하지 않았지만 여기서 하나의 Peer가 추가될 때마다 아래와 같은 오류가 발생했습니다.

image

원인

WebRTC의 동작과정을 보면 다음과 같습니다.

image

Peer A가 LocalDescription이 담긴 offer를 전송하면 Peer B가 이를 수신하여 RemoteDescription으로 설정하고,

이번에는 B가 LocalDescription이 담긴 answer를 전송하면 Peer A가 이를 수신하여 RemoteDescription으로 설정합니다.

이 순서는 보장이 되어야 하지만, offer와 answer가 교환되는 동안에도 ICE 후보는 교환될 수 있습니다.

이는 사실 1:1에서 크게 문제가 되지 않지만, N:M으로 확장되는 순간 신경을 써주어야 하는데요,

예를 들어 Peer가 A, B, C가 존재한다고 가정해봅시다.

3 Peer들은 다음과 같은 순서로 진행을 합니다.

  1. A 화상통화 참여
  2. B 화상통화 참여
  3. C 화상통화 참여

1에서 2로 넘어갈 때, A는 B에게 offer를 전송하고 B는 이를 수신하여 answer를 A에게 보낼 겁니다. 그리고 ICE 후보 교환을 하여 연결이 되겠죠.

문제는 2에서 3으로 넘어갈 때입니다.

C가 화상통화에 참여함으로써 A, B 두 Peer가 새로운 C의 session ID를 바탕으로 offer를 전송하고,

C는 이를 수신하여 answer를 A, B에게 보내야 합니다.

image

하지만 Signaling Server는 Client로부터 받은 메시지를 다른 모든 session에게 전파하도록 구현되어있었기 때문에,

만약 다음과 같은 순서로 진행된다면 문제가 발생할 수 있습니다.

  1. A가 C에게 offer 전송
  2. C가 A의 offer 수신
  3. C가 A, B에게 answer 전송
  4. A, B가 C의 answer 수신
  5. B가 C에게 offer 전송
  6. C가 B의 offer 수신
  7. C가 A, B에게 answer 전송
  8. A, B가 C의 answer 수신

A로부터 받은 offer에 대한 C의 answer가 B에게 전송되어 문제가 발생할 수 있습니다.

또 반대로 이후에 B로부터 받은 offer에 대한 C의 answer가 A에게도 전송되어 문제가 발생할 수 있습니다.

결국 Description이 중복으로 설정되는 점과

offer와 answer의 순서가 보장되지 않아 SDP에 대한 오류가 발생하는 것입니다.

연결 상태를 바탕으로 필터링 하여 중복으로 설정되는 문제는 해결하였지만,

여전히 간헐적으로 메시지 순서가 꼬이는 문제가 발생했습니다.

해결

처음에는 연결 상태을 파악하여 메시지 수신을 제어하려고 시도하였고,

다음으로 메시지 큐를 이용하여 순서를 보장해보려는 시도를 했지만 원활하게 진행이 되지 않았습니다.

결국 해결한 방법은 발신, 수신에 대한 session ID를 모두 파라미터에 담아 처리하는 것이었습니다.

image

image

메시지의 목적지를 정확하게 지정해주면 offer, answer의 순서도 보장할 수 있고,

이를 통해 중복되어 Description이 설정되는 상황도 방지할 수 있습니다.

다소 허무하게 해결되었지만 이를 통해 N:M 화상통화를 P2P로 구현할 수 있게 되었습니다.