/// <summary> /// Trigger an event callback in a remote process. /// Can be called on any thread as the CEF API involved (<see cref="CefBrowser.SendProcessMessage"/>) can be called on any thread when in the browser process. /// </summary> /// <param name="listener"> /// The message that requested to listen to the triggered event. /// </param> /// <param name="result"> /// The data payload of the triggered event. /// </param> public void SendEvent(BrowserCallInfo listener, ResultData result) { if (listener == null) { throw new ArgumentNullException("listener"); } if (result == null) { throw new ArgumentNullException("result"); } var eventMessage = new PluginMessage { MessageId = listener.RequestMessage.MessageId, MessageType = PluginMessageType.EventFired, PluginId = string.Empty, MemberName = string.Empty, Data = ParagonJsonSerializer.Serialize(result), BrowserId = listener.RequestMessage.BrowserId, ContextId = listener.RequestMessage.ContextId }; SendMessage(listener.Browser, eventMessage); }
private void OnInvokeFunction(CefBrowser browser, PluginMessage pluginMessage, JavaScriptPlugin handler) { var methodDescriptor = handler.Descriptor.Methods.Find(descriptor => descriptor.MethodName == pluginMessage.MemberName); IJavaScriptPluginCallback returnCallback = null; BrowserCallInfo parameterCallback = null; if (pluginMessage.V8CallbackId != Guid.Empty) { if (methodDescriptor.HasCallbackParameter) { // Create a second stored callback info which represents the V8 callback function itself // rather than the method that is being invoked now. This allows the callback function // to be passed to and invoked by multiple native methods that accept a callback parameter. parameterCallback = _pendingCallbacks.Get(pluginMessage.V8CallbackId); if (parameterCallback == null) { var parameterCallbackMessage = new PluginMessage { MessageId = pluginMessage.V8CallbackId, MessageType = PluginMessageType.ParameterCallback, PluginId = string.Empty, MemberName = string.Empty, BrowserId = pluginMessage.BrowserId, ContextId = pluginMessage.ContextId, FrameId = pluginMessage.FrameId, V8CallbackId = Guid.Empty }; parameterCallback = CreateAndAddCall(browser.Clone(), parameterCallbackMessage, null, null); } } var returnCallInfo = CreateAndAddCall(browser, pluginMessage, handler, parameterCallback); if (!handler.IsValid) { RemoveAndCancelCall(returnCallInfo); return; } returnCallback = returnCallInfo; } JArray callArgs = null; if (!string.IsNullOrEmpty(pluginMessage.Data)) { callArgs = JArray.Parse(pluginMessage.Data); } handler.InvokeFunction( _pluginManager, pluginMessage.BrowserId, pluginMessage.FrameId, pluginMessage.ContextId, pluginMessage.MemberName, new JArrayJavaScriptParameters(callArgs), returnCallback); }
private BrowserCallInfo CreateAndAddCall(CefBrowser browser, PluginMessage pluginMessage, JavaScriptPlugin handler, IJavaScriptParameterCallback parameterCallback) { var pluginId = handler != null ? handler.Descriptor.PluginId : null; var info = new BrowserCallInfo(this, browser, pluginMessage, pluginId, parameterCallback); _pendingCallbacks.Add(info); return(info); }
private void RemoveAndCancelCall(BrowserCallInfo info) { _pendingCallbacks.Remove(info); if (info.RequestMessage.MessageType == PluginMessageType.FunctionCallback) { CancelUnhandledQuery(info.Browser, info.RequestMessage); } info.Dispose(); }
/// <summary> /// Send a response to a function call. /// Can be called on any thread as the CEF API involved (<see cref="CefBrowser.SendProcessMessage"/>) can be called on any thread when in the browser process. /// </summary> /// <param name="info"> /// The callback that was created when the function was invoked. /// </param> /// <param name="result"> /// The result of the function (result, errorCode, error). /// </param> public void SendFunctionResponse(BrowserCallInfo info, ResultData result) { if (info == null) { throw new ArgumentNullException("info"); } if (result == null) { throw new ArgumentNullException("result"); } if (!info.IsRetained) { _pendingCallbacks.Remove(info); } SendFunctionResponse(info.Browser, info.RequestMessage, result); if (!info.IsRetained) { info.Dispose(); } }