NodeJS 的 Web 服务也可以监听在 sock 文件

像 NodeJS 写的 TCP 服务可以监听在某个 sock 文件(Domain Socket) 上,它的 HTTP 服务也能这么干。虽然作为 HTTP 服务连接某个 sock 文件的意义不大,所以这里只算是一个纯粹的尝试。

TCP 服务是这样写

连接上面那个 '/tmp/node_tcp.sock'

✗ telnet /tmp/node_tcp.sock
Trying /tmp/node_tcp.sock...
Connected to (null).
Escape character is '^]'.
Hello World!
received: Hello World!

准确说来本文应该是 NodeJS 的 TCP 和 HTTP 监听 Domain Socket 文件。 阅读全文 >>

使用 NodeJS 框架 NW.js 编写桌面应用入门

前阵子还在琢磨于 Atom Shell 和 Node-Webkit 间如何作个选择。基于 Atom Shell 有点像是站在了 Node-Webkit 的肩膀上的原因,感觉 Atom Shell  会有些优势,所以首先体验了下 使用 NodeJS 框架 Atom Shell 编写桌面应用入门。至于它们实现上是否合并了 Context 对我目前来说还不清楚会有什么影响。

正当我要安下心来的时候,先前那个 Node-Webkit 最近几日来了个华丽变身,以更为简洁明快的名字 NW.js 横空出世,并且与 NodeJS 的另一分支 io.js 更热乎。新的名字似乎有意在含糊它与 Webkit 之间的关系。对于 NW.js 的这一激动人心之举, 难免心起涟漪,顿绝不能只是路过,而况它还是出自国人之手,自豪感总有的。

于是决心一试,略玩之后发现, 特别是开发阶段可显示 toolbar -- 浏览任意 html, 前进/后退/刷新,并能用 Developer Tools 调试 UI 和 JavaScript 的特性。这才令我有些爱不释手,尚不知 Atom Shell 是否有类似的功能。

开始随我体验 NW.js 的 Hello World 程序,这里包含了外部 js 和 css 文件,仍是以 Mac OS X 平台为例,其他平台类似。

1. 前提条件,安装 NW.js

$ npm install nw -g

nw 模块就安装在 /usr/local/lib/node_modules/nw 目录下了,以后可以直接用 nw 命令来测试程序。 阅读全文 >>

使用 NodeJS 框架 Atom Shell 编写桌面应用入门

NodeJS 使前后台语言上得到了统一,给 “不就是做网站的” 那些人带来了福音,其基于事件驱动的处理机制更是在并发/CPU 密集型计算上大展身手。

虽然我不怎么做 UI 程序,但对于每一种语言却爱关心它做 GUI 程序是否得心应手。像 Java, Groovy, Scala 等写桌面程序也不怎么样,JavaFX 似乎显现出苗头来,因为 JavaFX 也支持 CSS 了,但布局仍然老套。

HTML + CSS + JS 做页面布局等样式控制有种与身俱来的优越感,于是 NodeJS 的世界里便产生了  Node-Webkit(已更名为 NW.js) 和 Atom Shell,它们各自的代表作有 LightTable 和堪与 Sublime 相媲美的 Atom 编辑器。

Node-Webkit(NW.js) 有两个context,node context 和 web context, 应用入口是一个 html 文件。而在  Atom Shell 只维持一个context,入口是一个 JS 文件,浏览器的启动控制要亲自动手。

完了基本的介绍后,回到原点,来看个 Atom Shell 的 Hello World 程序例子。 阅读全文 >>

Java NIO2(AIO) 进行文件异步读取

在  NodeJS 中进行异步操作很简单,而 Java 到了  7 开始才支持异步的 IO 操作。虽然之前的版本有引入非阻塞 IO,但编码中还不易体现出它的优越性。亮一下 NodeJS 用异步 IO 的例子:

var fs = require('fs');
fs.readFile('Test.scala', 'utf-8', function(err, data){
  if( !err ) {
    console.log(data);
  }
});

console.log('continue doing other thins');

执行输出是

continue doing other things
CONTENT FROM FILE Test.scala

对的,理想中的异步操作就是,传递回调函数来读取文件,读取完成后招待回调,且不阻塞主线程。

在 Java 8 之前,因为没有 Lambda 支持只能应用内部类的方式。JDK 提供了以下异步 Channel 来实现异步操作

AsynchronousFileChannel 阅读全文 >>

三种方式告知泛型类或泛型方法具体类型

在上一篇中写道 Java 泛型 -- 依据声明的变量类型自动推断,主要是说明了通过声明类型告知泛型方法具体类型,其后有个小结三种方式告知泛型类或泛型方法具体类型,在此重列如下:

一. 具体类型写在两尖括号中

1. List<String> list
2. new HashMap<String, String>
3. instance.<String>foo()   //如方法 <T> T foo() { return (T) obj; }

二. 变量声明类型指示具体类型

1. List<String> list = new ArrayList<>()   // 这个例子应该可以列在这里,List<String> 指示了具体类型是 String, 所以后只需要空 <>,JDK7 or later
2. String s = obj.foo()   //比如方法是 <T> T foo() { return (T) obj; }, 由于前面的 String s 声明,所以不必写成 String s = instance.<String>foo()

三. 实参类型指示具体类型

1. instance.foo(String.class)  //方法为 <T> T foo(Class<T> type) { return (T) obj; }, instance.foo(String.class) 返回的就是字符串值
2. instance.foo("abc")  //方法为 <T> foo(T value) { return (T) obj; }, instance.foo("abc") 返回的就是字符串值 阅读全文 >>

Java 泛型 -- 依据声明的变量类型自动推断

Java 泛型在调用方法操作时应用具体参数还是很好理解的,比如

Map<String, Integer> map = new HashMap<>();  //钻石操作符是 JDK 1.7 引入的

后续的 put 操作调用的具体方法就是

Integer put(String key, Integer value)

因为  put 方法的原型是

V put(K key, V value)

上面的代码我们是看到了 <>,所以知道是泛型调用。有时候并不需要 <>,但实际上也是进行的泛型调用,那就是 Java  可以依据变量声明类型来作特化调用 -- 应用具体参数类型。

例如:

List<String> list = Collections.emptyList();  //虽不见 <>, 但同样是泛型调用,类型为 String 阅读全文 >>