从CefSharp中的iframe返回.net调用被阻止

时间:2018-09-13 01:05:20

标签: .net asynchronous cefsharp

我有一个场景,我在cefsharp浏览器中调用JavaScript方法,然后该javascript方法调用postMessage将消息发送到其他域上的iframe,然后iframe在我的代码库中调用.Net方法以通知它是完成其工作。

我的问题是调用线程阻止了回叫。

这是C#结束语的示例:

// This class can be called by Javascript from cefSharp browser
public class BrowserListener
{
    public BrowserListener()
    {
    }
    public void SendBool(bool result)
    {
        // This line doesn't get hit until after the timeout period
        Log.Logger.Debug("Bool received from iframe {result}", result);
        Shared.Result = result;
        Shared.Received = true;
    }
}

public static class Shared
{
    // Only done this way for demonstration purposes
    public static bool Received {get; set;} = false;
    public static bool Result {get; set;} = false;
}

public class winCefBrowser : Window, IRequestHandler, IDownloadHandler, ILifeSpanHandler, IJsDialogHandler, ILoadHandler, IDialogHandler, IRenderProcessMessageHandler
{
    // snipped a lot of interface implementation
    private ChromiumWebBrowser mActiveView;

    public winCefBrowser(IKiraSession activeSession)
    {
        CefSettings settings = new CefSettings();
        settings.RemoteDebuggingPort = 1212;
        settings.IgnoreCertificateErrors = false;
        if (!Cef.IsInitialized)
        {
            Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
        }
        var v = new ChromiumWebBrowser();
        var s = new BrowserSettings();
        s.ImageLoading = CefState.Disabled;
        v.BrowserSettings = s;
        v.RequestContext = new RequestContext();
        mActiveView = v;
        // We have a tab control with the browser tab on it
        var loNewTab = new TabItem { Header = "New" };
        tabBrowser.Items.Add(loNewTab);

        mActiveView.DownloadHandler = this;
        mActiveView.RequestHandler = this;
        mActiveView.LifeSpanHandler = this;
        mActiveView.JsDialogHandler = this;
        mActiveView.LoadHandler = this;
        mActiveView.DialogHandler = this;

        var opt = new BindingOptions {CamelCaseJavascriptNames = false};

        mActiveView.RegisterAsyncJsObject("ourNet", new BrowserListener(),opt);

        loNewTab.Content = mActiveView;

    }

    public async Task<bool> DoStuff(string myString)
    {
        Shared.Received = false;
        var jsResponse = await mActiveView.EvaluateScriptAsync("myMethod('" + myString "');");
        if (jsResponse.Result != "OK") return false;
        var t = new Stopwatch();
        t.Start();

        // THIS LOOP IS WHERE THE PROBLEM IS
        // The code will loop around here for 10 seconds, then return false
        // THEN the call is received from the javascript method.
        while (!Shared.Received)
        {
            Thread.Sleep(100);
            if (t.Elapsed.Seconds > 10)
            {
                // Shouldn't hit this line
                Log.Logger.Debug("Timed out waiting for response from inner javascript call.");
                return false;
            }
        }
        // Never hits this line
        return Shared.Result;
    }
}

此代码位于html主页上

function myMethod(message) {
    // Simplified, this posts to the first iframe on the page
    var x = document.getElementsByTagName("iframe")[0].contentWindow;
    if (x !== null && x !== undefined) {
        x.postMessage(message, "*");
    }
    return "OK";
}

此代码位于iframe中,该iframe托管在其他域中:

if (window.addEventListener) {
    window.addEventListener("message", myListen, true);
} else {
    window.attachEvent("onmessage", myListen);
}

function myListen(event) {
    if (event.data == null) return;
    // These log messages appear almost immediately in the debug console at http://localhost:1212
    console.log("myListen triggered with event data:");
    console.log(event.data);

    ourNet.SendBool(true);

    // This final log message is hit straight away. 
    // But .Net doesn't start processing the call to SendBool for 10 seconds.
    console.log("Call back to .net completed.");
}

我正在WPF中使用CefSharp进行测试。我们最终的目标是在离屏模式下运行,因此,如果这是WPF特定的事情,我就不会介意。

0 个答案:

没有答案