Пример #1
0
        void IDevToolsMessageObserver.OnDevToolsMethodResult(IBrowser browser, int messageId, bool success, Stream result)
        {
            var uiThread = CefThread.CurrentlyOnUiThread;
            SyncContextTaskCompletionSource <DevToolsMethodResponse> taskCompletionSource = null;

            if (queuedCommandResults.TryRemove(messageId, out taskCompletionSource))
            {
                var methodResult = new DevToolsMethodResponse
                {
                    Success   = success,
                    MessageId = messageId
                };

                //TODO: Improve this
                var memoryStream = new MemoryStream((int)result.Length);

                result.CopyTo(memoryStream);

                methodResult.ResponseAsJsonString = Encoding.UTF8.GetString(memoryStream.ToArray());

                Action execute = null;

                if (success)
                {
                    execute = () =>
                    {
                        taskCompletionSource.TrySetResult(methodResult);
                    };
                }
                else
                {
                    execute = () =>
                    {
                        var errorObj = methodResult.DeserializeJson <DevToolsDomainErrorResponse>();
                        errorObj.MessageId = messageId;

                        //Make sure continuation runs on Thread Pool
                        taskCompletionSource.TrySetException(new DevToolsClientException("DevTools Client Error :" + errorObj.Message, errorObj));
                    };
                }

                var syncContext = taskCompletionSource.SyncContext;
                if (syncContext == null)
                {
                    execute();
                }
                else
                {
                    syncContext.Post(new SendOrPostCallback((o) =>
                    {
                        execute();
                    }), null);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Execute a method call over the DevTools protocol. This method can be called on any thread.
        /// See the DevTools protocol documentation at https://chromedevtools.github.io/devtools-protocol/ for details
        /// of supported methods and the expected <paramref name="parameters"/> dictionary contents.
        /// </summary>
        /// <param name="method">is the method name</param>
        /// <param name="parameters">are the method parameters represented as a dictionary,
        /// which may be empty.</param>
        /// <returns>return a Task that can be awaited to obtain the method result</returns>
        public async Task <DevToolsMethodResponse> ExecuteDevToolsMethodAsync(string method, IDictionary <string, object> parameters = null)
        {
            if (browser == null || browser.IsDisposed)
            {
                //TODO: Queue up commands where possible
                return(new DevToolsMethodResponse {
                    Success = false
                });
            }

            var messageId = Interlocked.Increment(ref lastMessageId);

            var taskCompletionSource = new SyncContextTaskCompletionSource <DevToolsMethodResponse>();

            taskCompletionSource.SyncContext = CaptureSyncContext ? SynchronizationContext.Current : syncContext;

            if (!queuedCommandResults.TryAdd(messageId, taskCompletionSource))
            {
                throw new DevToolsClientException(string.Format("Unable to add MessageId {0} to queuedCommandResults ConcurrentDictionary.", messageId));
            }

            var browserHost = browser.GetHost();

            //Currently on CEF UI Thread we can directly execute
            if (CefThread.CurrentlyOnUiThread)
            {
                var returnedMessageId = browserHost.ExecuteDevToolsMethod(messageId, method, parameters);
                if (returnedMessageId == 0)
                {
                    return(new DevToolsMethodResponse {
                        Success = false
                    });
                }
                else if (returnedMessageId != messageId)
                {
                    //For some reason our message Id's don't match
                    throw new DevToolsClientException(string.Format("Generated MessageId {0} doesn't match returned Message Id {1}", returnedMessageId, messageId));
                }
            }
            //ExecuteDevToolsMethod can only be called on the CEF UI Thread
            else if (CefThread.CanExecuteOnUiThread)
            {
                var returnedMessageId = await CefThread.ExecuteOnUiThread(() =>
                {
                    return(browserHost.ExecuteDevToolsMethod(messageId, method, parameters));
                }).ConfigureAwait(false);

                if (returnedMessageId == 0)
                {
                    return(new DevToolsMethodResponse {
                        Success = false
                    });
                }
                else if (returnedMessageId != messageId)
                {
                    //For some reason our message Id's don't match
                    throw new DevToolsClientException(string.Format("Generated MessageId {0} doesn't match returned Message Id {1}", returnedMessageId, messageId));
                }
            }
            else
            {
                throw new DevToolsClientException("Unable to invoke ExecuteDevToolsMethod on CEF UI Thread.");
            }

            return(await taskCompletionSource.Task);
        }
Пример #3
0
        /// <summary>
        /// Execute a method call over the DevTools protocol. This method can be called on any thread.
        /// See the DevTools protocol documentation at https://chromedevtools.github.io/devtools-protocol/ for details
        /// of supported methods and the expected <paramref name="parameters" /> dictionary contents.
        /// </summary>
        /// <param name="method">is the method name</param>
        /// <param name="parameters">are the method parameters represented as a dictionary,
        /// which may be empty.</param>
        /// <returns>return a Task that can be awaited to obtain the method result</returns>
        public new async Task <DevToolsMethodResponse> ExecuteDevToolsMethodAsync(string method, IDictionary <string, object> parameters = null)
        {
            DevToolsMethodResponse result;

            if (this.browser == null || this.browser.IsDisposed)
            {
                result = new DevToolsMethodResponse
                {
                    Success = false
                };
            }
            else
            {
                int messageId = Interlocked.Increment(ref this.lastMessageId);
                SyncContextTaskCompletionSource <DevToolsMethodResponse> syncContextTaskCompletionSource = new SyncContextTaskCompletionSource <DevToolsMethodResponse>();
                syncContextTaskCompletionSource.SyncContext = (this.CaptureSyncContext ? SynchronizationContext.Current : this.syncContext);
                if (!this.queuedCommandResults.TryAdd(messageId, syncContextTaskCompletionSource))
                {
                    throw new DevToolsClientException(string.Format("Unable to add MessageId {0} to queuedCommandResults ConcurrentDictionary.", messageId));
                }
                IBrowserHost browserHost = this.browser.GetHost();
                if (CefThread.CurrentlyOnUiThread)
                {
                    int num = browserHost.ExecuteDevToolsMethod(messageId, method, parameters);
                    if (num == 0)
                    {
                        result = new DevToolsMethodResponse
                        {
                            Success = false
                        };
                        return(result);
                    }
                    if (num != messageId)
                    {
                        throw new DevToolsClientException(string.Format("Generated MessageId {0} doesn't match returned Message Id {1}", num, messageId));
                    }
                }
                else
                {
                    if (!CefThread.CanExecuteOnUiThread)
                    {
                        throw new DevToolsClientException("Unable to invoke ExecuteDevToolsMethod on CEF UI Thread.");
                    }
                    int num2 = await CefThread.ExecuteOnUiThread <int>(() => browserHost.ExecuteDevToolsMethod(messageId, method, parameters)).ConfigureAwait(false);

                    if (num2 == 0)
                    {
                        result = new DevToolsMethodResponse
                        {
                            Success = false
                        };
                        return(result);
                    }
                    if (num2 != messageId)
                    {
                        // throw new DevToolsClientException(string.Format("1Generated MessageId {0} doesn't match returned Message Id {1}", num2, messageId));
                    }
                }
                result = await syncContextTaskCompletionSource.Task;
            }
            return(result);
        }