今天和大家介绍一下使用cefsharp,在浏览器中调用.Net 方法


什么是cef和cefsharp

Cef全称Chromium Embedded Framework 是谷歌的chromium浏览器的嵌入式框架,可以给予其他应用嵌入谷歌chromium浏览器的能力。

CefSharp是Cef的.NET 封装版本,可以在.NET环境下运行Cef。

有了CefSharp我们就能够在.NET应用中嵌入前端界面,大大扩展了前端页面在多端复用的能力。

CefSharpn的的使用例子可以参考github给出的官方用例:

今天我们着重讲一下如何利用CefSharp实现浏览器中调用.NET方法。

Cef调用.NET方法原理

image-20200509164227021

public class BoundObject
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

browser.JavascriptObjectRepository.Register("boundAsync", new BoundObject(), true, options);

第一步是在cef控件的JavascriptObjectRepository中注册一个.NET对象。

此时cef会将这个.NET 对象存储在一个字典中,并且分析对象的MethodInfo将对象中所有public的实例方法信息提取出来。

image-20200509165014304

接下来在运行时,执行对应的js方法时,Chromium会将对应的对象的方法,参数等,序列化后通过WCF(CefSharp是如此)传递至JavascriptObjectRepository。

JavascriptObjectRepository更据对象名称找到字典中的.NET对象,并Invoke对应的Method获得结果。

(async function()
{
	await CefSharp.BindObjectAsync("boundAsync");
	
	//The default is to camel case method names (the first letter of the method name is changed to lowercase)
	boundAsync.add(16, 2).then(function (actualResult)
	{
		const expectedResult = 18;
		assert.equal(expectedResult, actualResult, "Add 16 + 2 resulted in " + expectedResult);
	});
})();

Cef调用.NET方法实践

调用.NET的同步方法

image-20200509171012743

实践一下,这里我们定义了一个HelloWorld方法,返回一个字符串”HelloWorld”。

image-20200509171155473

接着我们将方法进行注册,并且指定isAsync为true

注意:请不要使用同步执行长时间任务,可能会导致浏览器的渲染线程卡死。

image-20200509141607543

然后我们在浏览器进行调用,成功返回了。

调用.NET的异步方法

我们当然不止是有同步的方法,更常见的情况会在.NET中使用异步方法。

这就容易导致异步方法传递,所以暴露给浏览器的js方法就可能是返回一个task。

image-20200509172336273

例如我们这里定义的Hello方法,返回的是一个Task<String>

然而我们直接调用的话会返回如下错误。

image-20200509105219014

这里提示是Task对象不是浏览器原生支持的对象,没有办法在js中调用,也不能跨WCF传递。

因此我们必须先使用Task.Result同步执行完成,再将结果传递给前端。

好在CefShape不会让我们在业务端做这些重复工作。

只要在第一个Cef控件初始化之前,设置CefSharpSettings.ConcurrentTaskExecution = true;

image-20200509173251935

现在我们再试试前端调用,正常等待1s之后获得返回值。

image-20200509141656892

风险点

我们刚刚看到目前的CefSharp利用WCF进行通信。

但是WCF在最新的.NET Core还没有得到支持,短期也看不到微软要支持它的样子。

因此目前只能在.NET Framework项目中使用。

总结

  • 使用CefSharp可以打通Chromium浏览器和.NET
  • 使用js调用.NET同步方法
  • 使用js调用.NET异步方法

参考文档:


本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/%E4%BD%BF%E7%94%A8cefsharp%E8%AE%A9%E5%89%8D%E7%AB%AF%E8%B0%83%E7%94%A8.NET%E6%96%B9%E6%B3%95.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名黄腾霄(包含链接: https://xinyuehtx.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系