分类目录归档:nodejs

Nodejs 的 c++ module 如何正确链接到 OpenSSL

事情的起因是这样的, 因为某些原因, 最近在写 Nodejs 的 c++ module, 然后在js这边调用。  网络通信自然离不开ssl, 于是需要链接到Openssl的库。

我们本来的期望是,需要用户安装有Openssl的运行库, 然后我们的c++ module 动态链接到Openssl的so库上来运行。 

起初一切看起来还不错,直到我们发现这个openssl的函数不能工作:

 PKCS7_sign()

我们发现:

  1. 如果我们的 c++ 模块与Openssl库动态链接的话, 编译都没问题. 但是运行会出现: PKCS7_sign 符号无法找到的错误.
  2. 如果我们的 c++ 模块与Openssl库静态链接的话, 编译也没问题, 但是运行时,调用这个函数的地方没有效果, 这个函数返回值是 0. 按照文档表示出现错误, 但是用 Openssl的函数 ERR_get_error 获取错误码也是0. 表示没有错误码.

在linux上是这样, 那在Mac上呢? 用Mac试了一下, 发现Mac没有问题. 于是,想到这可能是Nodejs的一个bug. 然后就去 Nodejs 给它报了一个bug: [https://github.com/joyent/node/issues/8026][1]

同时, google上搜索了 nodejs linking to openssl 类似的关键字.

找到这样几篇文章:
https://github.com/TooTallNate/node-gyp/wiki/Linking-to-OpenSSL

https://github.com/joyent/node/issues/3915

http://serverfault.com/questions/338092/how-can-i-build-node-js-using-static-libssl-and-crypto-libraries

https://github.com/robhawkes/node-extension/issues/1

通过搜索, 我们发现, 原来Nodejs自己也使用了Openssl 库, 推测nodejs自己的crypto模块也是使用Openssl lib实现的. 这点从Nodejs的源码中就能发现, 它包含了最新的Openssl的全部源码.

其中写上面第一篇文章: https://github.com/TooTallNate/node-gyp/wiki/Linking-to-OpenSSL 的那个帅哥是Nodejs的开发人员.

基本结论:

  1. Nodejs 自己使用了Openssl
  2. 在Nodejs 0.6之前, Nodejs是动态链接到 Openssl 库的. 而之后的版本都是静态链接的.

这时发现 Node 那边已经回复我的bug了: https://github.com/joyent/node/issues/8026

Node 解释的原因:

Node 自己编译之后, 把自己没用到的符号清除, 所以我们在运行时就找不到符号了. 于是他们把这bug 修掉了. 保留了全部符号. 这导致 Node 的体积大了 400k.

感谢Node的快速回复, 不得不佩服Node的活跃程度. 赞.

byNeil
byNeil.com

原文来自 Blog by Neil, post Nodejs 的 c++ module 如何正确链接到 OpenSSL 转载请注明出处。本站保留一切权力

等等,你可能误解nodejs了–通俗的概括nodejs的真相

最近刚把产品从cpp平台迁移到nodejs平台了.  很多以前关于nodejs的观念被颠覆了. 这里分享出来, 欢迎大家批评指正.

"nodejs是做服务器端开发的, 它一定和web相关,几乎是用来做网站开发的."  这是我之前一直的观念.  相信这可能也是很多人对nodejs的初步认识吧.  但后来我才发现, 我可能错了.

第一个问题:  nodejs到底是什么?

http://nodejs.org/ 官方主页上有一段解释: "Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices."

我们注意其中的几个关键字:  nodejs是一个平台,  它构建在chrome的v8引擎之上,  能简易的构建快速,可扩展的网络应用程序.......

这里官方用的"网络应用程序",  整个描述没有提到"web", "server" 等等概念.  这段话的描述中, 有两个是重点, 第一,就是chrome的v8引擎.  第二, 是事件驱动的非阻塞io模型.   把握住这两点,  我觉得就算掌握了nodejs的真谛了.

这么说吧,  举个例子, 类比来说,  概念上, nodejs相当于.net,   jvm 或者 python.   它是一个运行平台, 只不过它运行的是javascript语言而已.   类似地,  .net一般运行C#, vb等编译过后的il.  而jvm一般运行java编译成的字节码,  python一般运行python语言.

你可能要问, 那么nodejs是不是也能实现 .net等等这些平台的功能呢.  比如写个窗口桌面程序, 做socket网络通信, 以及访问磁盘文件等等.

恩, 这些问题的答案都是肯定的.

nodejs核心主要是由两部分组成的:

第一, 是v8引擎, 它负责把javascript代码解释成本地的二进制代码运行.

第二, 是libuv,  类似windows上的窗口消息机制, 它主要负责订阅和处理系统的各种内核消息. 而且它也实现了消息循环(是不是很耳熟? 没错, 这个几乎就和windows 的窗口消息循环是一个概念.).  它的前身是linux上的libev, 专门封装linux上的内核消息机制.  后来nodejs重写了它, 并在windows上使用iocp技术重新实现了一遍.  所以nodejs现在能跨平台运行在windows上了.

 

nodejs其实就是libuv的一个应用而已.

你自己写程序也可以集成libuv进来, 这样你的c++程序就有了消息循环了. 不再是简单main函数了. 你可以订阅系统的事件, 然后当事件发生时, 系统会调用你的回调函数, 就跟windows上的button click事件一样方便. 而且是跨平台的哦. 是不是很酷.    你几乎可以订阅所有的系统事件,  比如socket事件, 文件读写事件等等.

nodejs简单的说只是把javascript解释成c++的回调, 并挂在libuv消息循环上, 等待处理.  这样就实现了非阻塞的异步处理机制.

那么为什么是javascript而不是其他的语言.  很简单, 因为javascript的闭包.  这非常适合做回调函数.  因为我们一般都希望当回调发生时, 它能记住它原来所在的上下文.  这就是闭包最好的应用场景.

这里有libuv的详细介绍 http://nikhilm.github.io/uvbook/.

好像扯远了,  说nodejs的, 怎么扯到libuv了.  很简单, 因为 nodejs只是libuv的一个应用.  先了解libuv才能了解nodejs的实质和前世今生.

我们再回来说nodejs.

从另一个角度看,   上面的工作都分别由v8和libuv做了.  那么nodejs到底做了什么呢?   我们先看一下nodejs的文档: http://nodejs.org/api/

对了,除了用javascript封装libuv框架之外,   nodejs就是实现了这些api 功能.  这些api大部分是用javascript写的, 也有一部分是c++写的.

这是nodejs官方的仓库, https://github.com/joyent  其中有很多nodejs的插件. 有了这些nodejs就可以实现非常丰富的功能了.

作为结尾, 写一个简单的nodejs 常规helloworld 程序.

//test.js

//=================

console.log("hello world!")

//=================

存成test.js.  然后运行: node test.js

就能看到效果了.

怎么样,  看起来是不是很像python的感觉.  但是用的是javascript哦.  用这个代替python, 是不是爽死了.

就到这吧.  关于libuv, 关于nodejs插件.  等等话题, 希望能跟大家沟通交流.

欢迎大家访问我的独立博客: http://byNeil.com

 
byNeil
byNeil.com

原文来自 Blog by Neil, post 等等,你可能误解nodejs了–通俗的概括nodejs的真相 转载请注明出处。本站保留一切权力