예제 #1
0
        /// <summary>
        /// Receives data on <see cref="T:WebAssembly.Net.WebSockets.ClientWebSocket"/> as an asynchronous operation.
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="buffer">Buffer.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        public async Task <WebRtcReceiveResult> ReceiveAsync(ArraySegment <byte> buffer, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();

            var tcsReceive = new TaskCompletionSource <WebRtcReceiveResult>();

            // Wrap the cancellationToken in a using so that it can be disposed of whether
            // we successfully receive or not.
            // Otherwise any timeout/cancellation would apply to the full session.
            using (cancellationToken.Register(() => tcsReceive.TrySetCanceled()))
            {
                if (bufferedPayload == null)
                {
                    bufferedPayload = await receiveMessageQueue.DequeuePayloadAsync(cancellationToken);
                }

                var endOfMessage = bufferedPayload.BufferPayload(buffer, out WebRtcReceiveResult receiveResult);

                tcsReceive.SetResult(receiveResult);

                if (endOfMessage)
                {
                    bufferedPayload = null;
                }

                return(await tcsReceive.Task);
            }
        }
예제 #2
0
        public RTCDataChannel(JSObject ho)
        {
            cts             = new CancellationTokenSource();
            this.hostObject = ho;

            _ = Task.Run(Receive);

            onMessage = new Action <JSObject>((messageEvent) =>
            {
                ThrowIfNotConnected();

                using (messageEvent)
                {
                    // get the events "data"
                    var eventData = messageEvent.GetObjectProperty("data");

                    switch (eventData)
                    {
                    case ArrayBuffer buffer: using (buffer)
                        {
                            var mess = new ReceivePayload(buffer, WebSockets.WebSocketMessageType.Binary);
                            receiveMessageQueue.BufferPayload(mess);
                        }
                        break;

                    case JSObject blobData: using (blobData)
                        {
                            // TODO: Handle ArrayBuffer binary type but have only seen 'blob' so far without
                            // changing the default websocket binary type manually.
                            var dataType = hostObject.GetObjectProperty("binaryType").ToString();
                            if (dataType == "blob")
                            {
                                Action <JSObject> loadend = null;
                                // Create a new "FileReader" object
                                using (var reader = new HostObject("FileReader"))
                                {
                                    loadend = new Action <JSObject>((loadEvent) =>
                                    {
                                        using (var target = (JSObject)loadEvent.GetObjectProperty("target"))
                                        {
                                            if ((int)target.GetObjectProperty("readyState") == 2)
                                            {
                                                using (var binResult = (ArrayBuffer)target.GetObjectProperty("result"))
                                                {
                                                    var mess = new ReceivePayload(binResult, WebSockets.WebSocketMessageType.Binary);
                                                    receiveMessageQueue.BufferPayload(mess);
                                                    //Runtime.FreeObject(loadend);
                                                }
                                            }
                                        }
                                        loadEvent.Dispose();
                                    });

                                    reader.Invoke("addEventListener", "loadend", loadend);

                                    //using (var blobData = (JSObject)messageEvent.GetObjectProperty("data"))
                                    //    reader.Invoke("readAsArrayBuffer", blobData);
                                }
                            }
                            else
                            {
                                throw new NotImplementedException($"WebSocket binary type '{hostObject.GetObjectProperty("binaryType").ToString()}' not supported.");
                            }
                        }
                        break;

                    case String message:
                        {
                            var mess = new ReceivePayload(Encoding.UTF8.GetBytes(message), WebSockets.WebSocketMessageType.Text);
                            receiveMessageQueue.BufferPayload(mess);
                        }
                        break;
                    }
                }
            });

            // Attach the onMessage callaback
            hostObject.Invoke("addEventListener", "message", onMessage);

            onOpen = new Action <JSObject>((messageEvent) =>
            {
                this.OnOpen?.Invoke(this, EventArgs.Empty);
                messageEvent.Dispose();
            });

            // Attach the onMessage callaback
            hostObject.SetObjectProperty("onopen", onOpen);

            onClose = new Action <JSObject>((messageEvent) =>
            {
                this.OnClose?.Invoke(this, EventArgs.Empty);
                messageEvent.Dispose();
            });

            // Attach the onMessage callaback
            hostObject.SetObjectProperty("onclose", onClose);
        }