private async Task ProcessSelectIceCandidateAsync(string iceUserLocal, WSPayload clientReq)
        {
            var sdpParser = new SdpParser();
            var clientSdp = sdpParser.Parse(clientReq.sdp);

            var iceCandidate = clientSdp.MediaDescriptions
                               .SelectMany(l => l.IceCandidates)
                               .FirstOrDefault(l => l.CandidateType == "host");

            var iceAttributes = clientSdp.MediaDescriptions
                                .Select(l => l.IceAttributes)
                                .FirstOrDefault();

            if (iceCandidate != null && iceAttributes != null)
            {
                try
                {
                    var iceClientIps = await Dns.GetHostEntryAsync(iceCandidate.ConnectionAddress);

                    var iceClientIp       = iceClientIps.AddressList.First();
                    var clientIceEndpoint = new IPEndPoint(iceClientIp, iceCandidate.Port);

                    await SendIceCandidateAsync(clientIceEndpoint, iceUserLocal, iceCandidate, iceAttributes);
                }
                catch (SocketException e) when(e.SocketErrorCode == SocketError.HostNotFound)
                {
                    _logger.LogInformation("Unable to resolve ice host {ConnectionAddress} to an IP Address", iceCandidate.ConnectionAddress);
                }
            }
        }
        private async Task ProcessCreateSdpOfferAsync(WebSocket webSocket, IPEndPoint clientIp, string host, string iceUserLocal, string iceLocalPassword)
        {
            var serverAddr = (await Dns.GetHostAddressesAsync(host)).First(l => l.AddressFamily == AddressFamily.InterNetwork);
            var sdp        = _rtspProxyService.BuildSdp(serverAddr, iceUserLocal, iceLocalPassword);

            var response = new WSPayload
            {
                action = WSAction.CreateSdpOffer,
                type   = "offer",
                sdp    = sdp
            };

            await SendResponseAsync(webSocket, clientIp, response);
        }
 private async Task ProcessPlayStreamAsync(WebSocket webSocket, IPEndPoint clientIp, WSPayload clientReq)
 {
     try
     {
         await _rtspProxyService.PlayStreamAsync(clientReq.rtspUrl);
     }
     catch (Exception e)
     {
         await SendResponseAsync(webSocket, clientIp,
                                 new WSPayload
         {
             action       = clientReq.action,
             errorMessage = e.Message,
             error        = true
         });
     }
 }
        private async Task SendResponseAsync(WebSocket webSocket, IPEndPoint clientIp, WSPayload response)
        {
            var responseData = JsonSerializer.Serialize(response);

            _logger.LogDebug("[{clientIp}] Sending response", clientIp);
            _logger.LogTrace("[{clientIp}] {responseData}", clientIp, responseData);

            await webSocket.SendAsync(Encoding.UTF8.GetBytes(responseData), WebSocketMessageType.Text, endOfMessage : true, CancellationToken.None);
        }