前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Edge.js:让.NET和Node.js代码比翼齐飞

Edge.js:让.NET和Node.js代码比翼齐飞

作者头像
张善友
发布于 2018-01-30 03:43:05
发布于 2018-01-30 03:43:05
3.8K0
举报
文章被收录于专栏:张善友的专栏张善友的专栏

通过Edge.js项目,你可以在一个进程中同时运行Node.js和.NET代码。在本文中,我将会论述这个项目背后的动机,并描述Edge.js提供的基本机制。随后将探讨一些Edge.js应用场景,它在这些场景中可以为你开发Node.js程序提供帮助。

为何要使用Edge.js?

虽然许多应用程序只能用Node.js编写,不过有些情况下又需要综合Node.js和.NET两者的优点。基于以下几个理由,你想要在程序中使用.NET和Node.js:.NET框架和NuGet包提供了一个丰富的功能生态系统,它很好地补充了Node.js和NPM模块;可能你希望在Node.js程序中重用某些现成的.NET组件;也可能想使用多线程CLR运行CPU密集型的计算,而这绝非是单线程的Node.js所擅长的;又或者你可能优先选择使用.NET框架和C#而不是使用C/C++编写原生的Node.js扩展来访问那些尚未通过Node.js暴露的操作系统机制。

一旦你决定在程序中使用Node.js和.NET,那么你必须将Node.js和.NET的组件用进程壁垒将两者分离开来,并建立某种形式的进程间通信的机制,比如说HTTP:

Edge.js提供另一种类似的组建异构系统的方式。它允许你在单一进程中同时运行Node.js和.NET代码,并且提供了V8和CLR之间的互操作机制。

使用Edge.js可以在一个进程中运行Node.js和.NET,而不用将其分割为两个进程,这样有两个主要的好处:更好的性能和更低的复杂性。

某个场景的性能测试显示,从Node.js向C#发出的进程内Edge.js请求比两个进程间通过HTTP发送的相同请求快32倍。与两个进程和进程间的通信信道相比,只处理一个单独的进程,明显降低了你需要解决的部署和维护的复杂性。

.NET欢迎Node.js

接下来我将用一个基础实例讲解Edge.js的关键概念,这个例子是从Node.js向C#发送请求。

第1行引入事先从NPM安装的edge模块。Edge.js是一个原生的Node.js组件。Edge.js的特殊之处在于,它被加载的时候便在node.exe进程内部开始代管CLR。

edge模块暴露了一个名为func的单函数。在高层次上,该函数以CLR代码为参数,然后返回一个JavaScript函数作为CLR代码的代理。func函数接受多种格式的CLR代码,从源代码,文件名,到预编译的CLR都可以。在上面的3-8行中,程序指定了一个异步的Lambda表达式作为C#文本代码。Edge.js提取出那段代码并将其编译为内存中的CLR程序集。然后它围绕着第3行的CLR代码(分配给hello变量的)创建并返回了一个JavaScript代理函数。需要注意的是,这个编译过程在每次调用edge.func函数时都会执行一次并将结果缓存。此外,如果你用同样的字符串变量调用edge.func函数两次,那么就会从缓存中获得相同的Func<object,Task<object>>实例。

Edge.js创建的hello函数是C#代码的代理函数,它在第10行由标准的Node.js异步模式调用。这个函数接收一个单独参数(Node.js字符串),并且还有一个接收错误和返回结果的回调函数。输入的参数在第4行被传递到C#异步Lambda表达式中,这个表达式在第6行将传入值附加到“.NET welcomes”字符串之后。当调用第10行的JavaScript回调函数的时候,这个C#中新构造的字符串被Edge.js作为result参数传递进去。JavaScript回调函数则将其打印在控制台上:“.NET welcomes Node.js”。

Edge.js提供了一套进程内Node.js和.NET代码之间规范的互操作模型。它不允许JavaScript直接调用任何CLR函数。CLR函数必须是一个Func<object,Task<object>> 委托。这种机制为Node.js和.NET互相传递数据提供了足够的灵活性。同时,它需要.NET代码异步执行,以便于和单线程的Node.js代码自然地集成在一起。这是Func<object,Task<object>>委托如何映射于Node.js异步模型概念:

互操作模式并不禁止你访问.NET framework的任何部分,但是它往往会要求你额外编写一个适配器层以暴露所需的.NET功能如同Func<object,Task<object>> 委托。这个适配器层要求你明确地定位.NET中的阻塞APIs的问题所在,它可能将这些运算运行在CLR线程池中以避免阻塞Node.js事件循环。

数据和功能

虽然Edge.js仅仅允许你在Node.js和.NET之间传递一个参数,但是这个参数可能是个复杂类型的。当从Node.js请求.NET代码的时候,Edge.js可以封送(marshal)所有标准的JavaScript类型:从基类型到对象和数组。当从.NET向Node.js传递数据的时候,Edge.js不但可以封送所有的基本CLR类型,而且还可以处理CLR对象实例、列表、集合和字典类型。从概念上讲,你可以认为在V8和CLR之间的数据传递就像是在一个环境中将数据序列化为JSON,而在另一个环境中对JSON进行反序列化。但是,Edge.js并没有在进程中进行实际的JSON序列化过程。相反,它直接在内存中进行V8和CLR类型系统之间的数据封送,而省略了字符串型中间代码,这个过程远比JSON序列化和反序列化更加高效。

Edge.js通过值进行数据封送,所以当执行过程跨越V8/CLR边界时,它会在V8或者CLR的堆中另外创建一份数据拷贝。这个规则有一处显著的例外:与通过值进行数据封送不同,Edge.js通过引用来封送函数。让我们通过下面这个例子来说明这个强有力的概念:

在这个例子中,Node.js调用addAndMultiplyBy2的C#中运行的函数。这个函数获取两个数字,而后返回它们总和的2倍。鉴于这个例子的目的,我们假设C#知道如何做加法但是却并不清楚如何做乘法。C#代码在计算和之后需要回调至JavaScript以进行乘法运算。

为了实现这个场景,Node.js应用程序在第18-20行定义一个multiplyBy2函数,并在第23行调用addAndMultiplyBy2函数时将其随同两个运算对象传递至C#代码。注意multiplyBy2函数是如何满足Edge.js规范的互操作模式的。这使得Edge.js可以在给multiplyBy2这个JavaScript函数创建.NET代理,就像是.NET中的Func<object,Task<object>>委托。这个JavaScript函数代理接下来被C#代码在第10行调用,用于对第8-9行中得到的和执行乘法运算。

遵守规范的互操作模式的函数也可以从.NET被封送到Node.js。能够在V8和CLR中双向封送函数是很强有力的概念,尤其是当掺杂着闭包的时候更是如此。请看下面这个例子:

在第1-7行,Edge.js创造了一个JavaScript函数createCounter,这个是C# Lambda表达式的代理。第9行中传给createCounter函数的的参数在第3行被强制转化为一个C#的本地变量。第4-5行的代码比较有趣:C#异步Lambda表达式的结果是一个Func<object,Task<object>>型的委托实例,它(第5行)的实现包含了第3行在闭包中定义的本地变量。当Edge.js将这个Func<object,Task<object>>实例封送为JavaScript函数回传给Node.js,并将其分配给第9行的counter变量的时候,这个JavaScript的counter函数有效的涵盖了CLR状态下的闭包。这点在第10-11行得到了充分的证明。这两行两次调用counter函数,结果返回的是一个不断增加的值。这是由于每次调用第5行实现的Func<object,Task<object>>都会使得第3行的本地变量的数值增加。

在V8和CLR之间封送函数的能力加上闭包的概念是个很强有力的机制。这样.NET代码就能够暴露CLR对象的功能给Node.js。第三行的本地变量在最后的例子中是一个Person类的实例。

让我们一起动手

我们来看几个实际的例子以便了解如何在Node.js应用程序中使用Edge.js。

Node.js是单线程的架构。如果要保持响应性,那么应用程序中就不能执行阻塞的代码。大部分Node.js程序都是在进程外执行CPU密集型的运算。外部进程通常使用的技术并不是Node.js。Edge.js使得这种场景非常容易实现。它允许你的Node.js程序在Node.js进程内部的CLR线程池中执行CPU密集型的逻辑运算。当CPU密集型的计算在CLR线程池的线程中运行时,V8线程上的Node.js程序仍然是可响应的。一旦CPU密集型操作结束,Edge.js同步线程就在V8线程上执行JavaScript回调函数。请看这个使用.NET功能转换图片格式的例子:

convertImageToJpg函数使用了.NET中的System.Drawing的功能将PNG图片转换为JPG格式。这是计算密集型的操作,因此第6行创建的C#实现(implementation)调用了Task.Run在CLR线程池中运行这个转换。当计算执行的时候,进程中的单例(singleton)V8线程可以处理后续的事件。C#代码随第6行的await关键字而等待图片转换的完成。只有在图片转换完成之后,convertImageToJpg在V8线程上执行第14-15行JavaScript回调代码,整个函数才算完成。

另一个让Edge.js大显身手的例子是在MS SQL中读取数据。现在Node.js开发者还没有什么读取MS SQL数据的方法可以比.NET Framework中的ADO.NET更加完善和成熟。Edge.js提供给你一个简单的在Node.js程序中利用ADO.NET的方法。请看下这个Node.js程序:

在第1行中,Edge.js通过编译sql.csx文件中的ADO.NET代码创建了sql函数。这个sql函数接受一个T-SQL命令构成的字符串,并使用ADO.NET异步执行它,然后将结果返回给Node.js。sql.csx文件用C#编写了不到100行的ADO.NET代码,它支持对MS SQL数据库执行CRUD四种操作:

在sql.csx文件中的实现(implementation)使用异步ADO.NET的API来访问MS SQL数据并执行Node.js传给它的T-SQL命令。

上面的两个例子仅仅代表了Edge.js帮你编写Node.js程序的一小部分场景。更多的例子可以参见Edge.js的GitHub站点。

路线图

Edge.js是一个遵循Apache 2.0协议的开源项目。它目前的开发很活跃,欢迎前来贡献代码。你可以用你的时间和经验来检查工作项目列表。

尽管本文中所有的例子都是使用C#写的,Edge.js支持在Node.js程序中运行任何CLR语言的代码。目前的扩展提供了对脚本语言F#PythonPowerShell的支持。通过语言扩展模型你能很容易的添加其他CLR语言的编译器

Edge.js目前需要.NET Framework环境,因此只能运行在Windows上。但是对Mono的支持也在积极的开发中,不久就可以在MacOS和*nix上运行Edge.js程序了。

关于作者

Tomasz Janczuk是微软的一名软件工程师。他目前主要关注Node.js和Windows Azure。在此之前他从事.NET Framework和网络服务(web services)方面的工作。业余时间里,他在太平洋等地参加了很多户外活动。你可以在Twitter上关注他,@tjanczuk,也可以访问他的GitHub页面或者阅读他的博客以获得更多的资讯。

查看英文原文:Run .NET and Node.js code in-process with Edge.js

查看中文原文Edge.js:让.NET和Node.js代码比翼齐飞

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2013-09-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Node.js 是什么?我为什么选择它?
当我们学习一项新的事物的时候,我们首先要知道它来自哪里?它是什么?能做什么或者换句话说,能解决什么问题?没有一样东西是最好的,是可以替代所有的,但在某一领域它是最适合的,正如 Node.js 它可能是某些程序员苦苦追寻的东西,也可能是某些程序员不会去关心的东西。本文主要为您介绍 Node.js 的背景及它能做什么,擅长什么,不会涉及到复杂的代码层面的知识讲解,如果你觉得自己很熟悉了,也可以忽略它。
五月君
2019/08/06
1.5K0
为什么要用 Node.js
传统意义上的 JavaScript 运行在浏览器上,这是因为浏览器内核实际上分为两个部分:渲染引擎和 JavaScript 引擎。前者负责渲染 HTML + CSS,后者则负责运行 JavaScript。Chrome 使用的 JavaScript 引擎是 V8,它的速度非常快。
哲洛不闹
2018/09/18
1.9K0
为什么要用 Node.js
大厂node.js高阶面试题和答案,重点难点攻克!
不论是前端开发还是后端开发,Node.js 这些内容都早已经是我们的必备技能,消化理解了整个人就变得通透了,几乎我们所有的程序开发人员日常开发中都会遇到这些难题了 !不过也不担心,是问题就总能解决的哈
艾编程
2022/04/02
5.9K0
大厂node.js高阶面试题和答案,重点难点攻克!
【Node.js】你真的了解 Node.js 么
Node.js 是基于 Chrome V8 引擎的 JavaScript 运行时环境。
GopalFeng
2022/08/01
5.7K0
【Node.js】你真的了解 Node.js 么
.NET Core vs Node.js:你应该选择哪个?
本文最初发布于 inveritasoft.com 网站,经网站授权由 InfoQ 中文站翻译并分享。
深度学习与Python
2020/10/26
1.9K0
.NET Core vs Node.js:你应该选择哪个?
为什么要用 Node.js
这是一个移动端工程师涉足前端和后端开发的学习笔记,如有错误或理解不到位的地方,万望指正。 Node.js 是什么 传统意义上的 JavaScript 运行在浏览器上,这是因为浏览器内核实际上分为两个部分:渲染引擎和 JavaScript 引擎。前者负责渲染 HTML + CSS,后者则负责运行 JavaScript。Chrome 使用的 JavaScript 引擎是 V8,它的速度非常快。 Node.js 是一个运行在服务端的框架,它的底层就使用了 V8 引擎。我们知道 Apache + PHP 以及 J
前朝楚水
2018/04/03
2.4K0
[译] 深入理解 Node.js 中的 Worker 线程
原文:https://blog.insiderattack.net/deep-dive-into-worker-threads-in-node-js-e75e10546b11
江米小枣
2020/06/15
2.4K0
Node.js简介
Ryan Dahl(瑞安·达尔)尝试过用Ruby, c, Lua去解决, 但都因为语言自身的各种限制而一一失败 语言历史包袱太重, 船大难掉头 各种语言的思想都根深蒂固, 生态没法轻易改变 渐渐摸索到解决问题的钥匙:事件驱动 异步I/O
JokerDJ
2023/11/27
3960
Node.js简介
Node.js编写组件的几种方式
本文主要备忘为Node.js编写组件的三种实现:纯js实现、v8 API实现(同步&异步)、借助swig框架实现。
conanma
2022/01/06
1.5K0
Node.js原理
概述 Node.js是什么 Node 是一个服务器端 JavaScript 解释器,用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。 Node.js 是一个可以让 JavaScript 运行在浏览器之外的平台。它实现了诸如文件系统、模块、包、操作系统 API、网络通信等 Core JavaScript 没有或者不完善的功能。历史上将 JavaScript移植到浏览器外的计划不止一个,但Node.
xiangzhihong
2018/01/26
3.1K0
为什么要使用Node.js?
JavaScript的流行给它本身带来许多变化,Web开发的面貌也发生了巨大的改变。现在JavaScript不仅可以运行在浏览器上,甚至可以运行在服务器上,像Flash或者Java Applets那样被包装在沙盒环境中运行,这在几年前这是很难想象的。
疯狂的技术宅
2019/03/28
3.5K0
为什么要使用Node.js?
你不知道的Node.js性能优化
仅仅是简单的升级 Node.js 版本就可以轻松地获得性能提升,因为几乎任何新版本的 Node.js 都会比老版本性能更好,为什么?
Starkwang
2018/11/16
3.5K2
你不知道的Node.js性能优化
[译]理解 Node.js 的中 Worker Threads
原文:https://nodesource.com/blog/worker-threads-nodejs
腾讯IVWEB团队
2020/06/28
2.1K0
Node.js真的无所不能?那些不适用的应用领域分析
Node.js是一个服务器端JavaScript解释器,底层采用的还是libevent;它的目标是帮助程序员构建高度可伸缩的应用程序,目前对Node.js 的采用状况,Node.js 官方站点有一些罗列,但是相当不完整。如果你自己公司用到,也可以在 github 上提交自己的 pull-request 来更新这个文档。 http://nodejs.org/industry/ https://github.com/joyent/node/wiki/Projects,-Applications,-and-Com
李海彬
2018/03/19
1.5K0
Node.js真的无所不能?那些不适用的应用领域分析
Node.js学习笔记(一)——Node.js概要、NPM与package.json
Node.js 是一个基于Google Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。Node.js 的包管理器 npm,是全球最大的开源库生态系统。
张果
2022/09/28
2.7K0
Node.js学习笔记(一)——Node.js概要、NPM与package.json
Node.js简介
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。 Node.js不是一种独立的语言。Node.js用JavaScript进行编程, 运行平台是包装后的js引擎(V8)。和PHP, JSP等语言不同,他们都需要运行在服务器上,例如apache,tomat,nginx,IIS,Node.js不用架设在任何服务器软件之上。
VV木公子
2019/07/31
7.5K0
Node.js简介
Node.js的介绍
作者:sagittarius-rev 链接:https://www.zhihu.com/question/31305968/answer/116439739 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
用户8870853
2021/08/30
1.6K0
Node.js 入门你需要知道的 10 个问题
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。它是一个开源和跨平台的服务端应用程序。任何人都可以编写 JavaScript 代码来开发 Node.js 应用程序。它可以运行于 Microsoft Windows、Linux、 或 OS 系统。
五月君
2019/07/12
1.4K0
Node.js 入门你需要知道的 10 个问题
深入 Node.js 事件循环架构
关于 Node.js ,相信你已经了解过不少内容,诸如 Node.js 内核、事件循环、单线程、setTimeout 或 setImmediate 函数的执行机制等等。
凌虚
2020/07/20
1.8K0
深入 Node.js 事件循环架构
2024年,Bun、Node.js还是Deno,哪个更适合你?
大家好,今天我们来聊聊2024年构建现代JavaScript API的新趋势。随着像Express.js这样的库的出现,搭建一个API变得简单快捷。但挑战在于选择合适的JavaScript后端语言环境。
前端达人
2023/12/19
5.7K0
2024年,Bun、Node.js还是Deno,哪个更适合你?
相关推荐
Node.js 是什么?我为什么选择它?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档