Exemple #1
0
        /// <summary>
        /// Internal helper to wrap a coroutine into a synchronous call
        /// for use inside a <see cref="Task"/> object.
        /// </summary>
        /// <param name="msg">the message to send</param>
        private IEnumerator PostToServerAndWait(SignalerMessage message, ManualResetEvent mre)
        {
            // Start the coroutine and wait for it to finish
            yield return(StartCoroutine(PostToServer(message)));

            mre.Set();
        }
Exemple #2
0
        /// <inheritdoc/>
        public override Task SendMessageAsync(SignalerMessage message)
        {
            // This method needs to return a Task object which gets completed once the signaler message
            // has been sent. Because the implementation uses a Unity coroutine, use a reset event to
            // signal the task to complete from the coroutine after the message is sent.
            // Note that the coroutine is a Unity object so needs to be started from the main Unity thread.
            var mre = new ManualResetEvent(false);

            _mainThreadWorkQueue.Enqueue(() => StartCoroutine(PostToServerAndWait(message, mre)));
            return(Task.Run(() => mre.WaitOne()));
        }
Exemple #3
0
        /// <summary>
        /// Internal helper for sending HTTP data to the node-dss server using POST
        /// </summary>
        /// <param name="msg">the message to send</param>
        private IEnumerator PostToServer(SignalerMessage msg)
        {
            var data = System.Text.Encoding.UTF8.GetBytes(JsonUtility.ToJson(msg));
            var www  = new UnityWebRequest($"{HttpServerAddress}data/{RemotePeerId}", UnityWebRequest.kHttpVerbPOST);

            www.uploadHandler = new UploadHandlerRaw(data);

            yield return(www.SendWebRequest());

            if (AutoLogErrors && (www.isNetworkError || www.isHttpError))
            {
                Debug.Log("Failure sending message: " + www.error);
            }
        }
Exemple #4
0
        /// <summary>
        /// Send a message to the signaling server to be dispatched to the remote
        /// endpoint specified by <see cref="SignalerMessage.TargetId"/>.
        /// </summary>
        /// <param name="message">Message to send</param>
        public Task SendMessageAsync(SignalerMessage message)
        {
            if (string.IsNullOrWhiteSpace(_httpServerAddress))
            {
                throw new ArgumentException("Invalid empty HTTP server address.");
            }

            // Send a POST request to the server with the JSON-serialized message.
            var         jsonMsg    = JsonConvert.SerializeObject(message);
            string      requestUri = $"{_httpServerAddress}data/{RemotePeerId}";
            HttpContent content    = new StringContent(jsonMsg);
            var         task       = _httpClient.PostAsync(requestUri, content).ContinueWith((postTask) =>
            {
                if (postTask.Exception != null)
                {
                    OnFailure?.Invoke(postTask.Exception);
                }
            });

            // Atomic read
            if (Interlocked.CompareExchange(ref _connectedEventFired, 1, 1) == 1)
            {
                return(task);
            }

            // On first successful message, fire the OnConnect event
            return(task.ContinueWith((prevTask) =>
            {
                if (prevTask.Exception != null)
                {
                    OnFailure?.Invoke(prevTask.Exception);
                }

                if (prevTask.IsCompletedSuccessfully)
                {
                    // Only invoke if this task was the first one to change the value, because
                    // another task may have completed faster in the meantime and already invoked.
                    if (0 == Interlocked.Exchange(ref _connectedEventFired, 1))
                    {
                        OnConnect?.Invoke();
                    }
                }
            }));
        }
 /// <summary>
 /// Asynchronously send a signaling message to the remote peer.
 /// </summary>
 /// <param name="message">The signaling message to send to the remote peer.</param>
 /// <returns>
 /// A <see cref="Task"/> object completed once the message has been sent,
 /// but not necessarily delivered.
 /// </returns>
 public abstract Task SendMessageAsync(SignalerMessage message);