NAN:Node.js 與 io.js 的 Native Addon 開發利器

2015年3月21日 星期六
自從 Node.js v0.11 版之後,內建的 V8 引擎被更新了,於是 JavaScript 引擎的原生 API 大幅度改變,導致很多以 C/C++ 所撰寫的原生模組紛紛出現相容性問題。影響範圍包括了前陣子發佈的 Node.js v0.12 以及 io.js 1.0+,因為都使用了新版的 V8 JavaScript Engine,而有同樣的問題。

其實這樣的問題已經不是新鮮事,自從 Node.js v0.8 到 v0.10 就開始有些許不相容的問題,只是到了 v0.12 和 io.js 之後,出現了更多狀況。因此 Node.js 圈子內的知名開發者 Rod Vagg 建立了 NAN 專案,用來解決這樣 Native API 不相容的問題。

NAN 全名為 Native Abstractions for Node.js,目標是設計一系列通用 API 供 Native Add-on 開發者所使用,讓開發者可以使用這通用的 API,一次性開發出支援 v0.8、v0.10、v0.12 和 io.js 1.0+ 的原生模組,不必再為 V8 原生 API 相容性所苦。

若想要使用 NAN,可以直接以 NPM 下載:
$ npm install nan

然後在 binding.gyp 中加入 include_dirs 的屬性設定,讓 Node.js 或 io.js 引入 NAN 模組:
'include_dirs': [
    "<!(node -e \"require('nan')\")"
]

經過這樣的設定配置後,我們就可以在 C/C++ 程式裡面引入 NAN 的標頭檔,開始使用 NAN 的 API:
#include <nan.h>

NAN_METHOD(Hello) {
    NanScope();
    NanReturnUndefined();
    // 或是這樣寫 NanReturnValue(Undefined());
}

上面的程式碼,代換成舊的版本(v0.8、v0.10),就等同於:
Handle<Value> Hello(const Arguments& args)
{
    HandleScope scope;
    return scope.close(Undefined());
}

若在新版的 Node.js v0.12 或是 io.js 之上,就等同於:
void Hello(const v8::FunctionCallbackInfo<Value>& args)
{
    Isolate *isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);

    args.GetReturnValue().Set(Undefined());
}

我們可以看到,NAN 已經包裝成一個簡單的 API,方便開發者去移植或開發 Native Add-on。

建立物件

此外,NAN 也將許多物件類型的建立方法,利用 Template 統一成 NanNew() 這樣一個 API,例如:
Local<String> string = NanNew<String>("hello world");
Local<Boolean> boolean = NanNew<Boolean>(NanTrue());
Local<Number> number = NanNew<Number>(123);
Local<Array> number = NanNew<Array>();

更多功能

NAN 有更多的功能,有興趣的人可以參考專案上的說明:
https://github.com/rvagg/nan

後記

因應 io.js 的推出,最近開始搬移手上的 Native Module,包括了 node-dbus、 brig 以及其他種種模組,碰到 V8 API 大改,讓人手足無措,好在 NAN 已經解決了大多數的問題。其實不只是 V8 的更新,libuv 的更新也是問題之一,只不過問題還算小,日後有空再來筆記下來。

Hackathon Taiwan 新倒數計時器系統

2015年3月18日 星期三

話說

如果你之前就有參加過我們的 Hackathon 活動,就會對從第一屆黑客松就有的倒數計時器有所記憶。這是我們特別為 Hackathon 活動所開發的倒數計時器,其著漂亮粒子特效,讓許多人印象深刻,尤其是投影在夜晚的牆壁和玻璃上,伴隨著台北 101 和夜空為背景,可說是非常炫麗又有氣氛。



但經歷過了四次活動,這個計時器也該功成身退了,隨著活動人數成長,活動內容及場地規劃,舊的計時器已經慢慢不敷使用,除了一身漂亮的動畫外,沒有太多的功能。而且,縱使有著一個看起來炫酷的特效,對工作人員和很多參加者來說,也慢慢膩了。

於是,我們又提起筆開始設計一個全新的倒數計時器系統,想設計一個更具科技、科幻感及現代感的介面,除此之外,更希望可以在未來可以引入更多的功能和互動機制,如導引、會場資訊查詢、甚至是直播等。就這樣,一個新的計時器誕生,並在 3/7 - 3/8 第五次的黑客松活動被使用。

因為我們期望這個計時器,不只是用來倒數計時,未來能變成一個多用途的活動系統,所以在設計上有更多的規劃及保留。也採用更多色塊來進行設計,讓畫面上有更多可利用的空間。

互動功能

在這次活動中,我們觀察到了一個現象,那就是對正在專心進行創作及 Hack 的人,手上的工作雖樂趣無窮,但對於旁觀者來說,卻是無聊透頂,這讓黑客松(Hackathon)活動的現場,時不時會呈現一種沈悶的氛圍。此外,參加者的工作效率往往呈現著週期性,或是專心時間總有一個極限,適當的放鬆和中斷也是常見的情況。但是如果放鬆或中斷手上工作時,沒別的事可以舒展身心,這會感到相當無聊了,於是會看到有些人會選擇用吃東西來打發中間的時間。

其實,來黑客松除了動手做之外,人際關係經營及交流也是很重要的一環,但別人正在專心工作時,你不便打攪,尤其是當同隊的人都正在專注做事實,你剛好想要換個氣的時候,更不可能去煩自己的隊友。不過,雖然你的周圍可能沒人可以跟你互動,但你可以去找同樣想換氣的人產生互動,畢竟全場人這麼多,跟你處於同一個狀態的人總是有不少。

那麼,如何找到人可以跟自己互動或交流呢?

這次活動,我們建立了 IRC Channel ,讓參加者可以上來 IRC 聊天室來說說話。所以,如果你有興趣,除了活動時間之外,平時也可以加入我們的 IRC 聊天室掛著:
Server: irc.freenode.net
Channel: #HackathonTaiwan
若是你不懂 IRC 客戶端程式如何使用,也有 Web 介面可以使用:
http://webchat.freenode.net
雖然我們已經嘗試引入聊天互動的機制,但我們發現仍不足夠,因為大部分的人仍然不知道有這樣的管道可以與其他人聊天及討論,或在活動中根本忘了可以使用這些服務。於是,為了讓更多人可以輕鬆地看到聊天室內的精彩訊息,我們在這次活動空閒時開發了一個新功能,將 IRC Channel 的訊息接到了新倒數計時器系統上,並畫了一個區域讓它顯示聊天內容。如此,參加者在休息或放鬆時,可以側頭看看周遭的計時器投影,順便看看聊天內容,相當有趣。

此外,一旦有了這樣的功能,可以預見的是,參加者能在上面找隊友或跨團隊找人協助,或是打發不專心的時間,當然,更能拓展人際關係與交流,實踐黑客松的價值。

展示影片



程式原始碼

身在這個開放的時代,提供程式原始碼是很正常的一件事。

如果你對這支應用程式有興趣,可以從這取得程式原始碼,如果有什麼想法,也歡迎在 Github 上發 issue 或跟我們說:
https://github.com/HanGee/Hankathon

後記

下次黑客松台灣(Hackathon Taiwan)活動預計是 4/11(六)、4/12(日),記得找朋友一起來參加!也歡迎加入我們的粉絲專頁,取得各種第一手訊息:
https://www.facebook.com/HackathonTaiwan

第四屆 Hackathon Taiwan 回顧!人才們的集散地!

2015年2月10日 星期二

每個月舉辦的台灣黑客松(Hackathon Taiwan),第四屆活動順利落幕!感謝大家的支持!無論你碰上什麼樣的隊友,有沒有完成作品,下次都歡迎再來!

曾幾何時,許多人對黑客松活動已經感到麻痺,似乎就是一群躲在暗處的宅宅工程師聚集起來自我感覺良好的場合,不然就是許多新創團隊前來展示產品的地方。往往沒有機緣巧合參與的人,總是深怕自己能力不足而無法參與,也有人覺得來這裡看別人發表產品,相當無趣。人們逐漸忘了黑客松的原本出發點,也忘了捲起袖子動手的熱情,更忘了與人交流並相互扶持學習的愉悅。

事實上,一個在大家心目中理想的黑客松,不外乎就是有得玩、有得學、有得做、有得交流,最後,能上台展示自我並取得成就感。這樣的氛圍,不同於補習班,也不同於一般制式學校,因為沒有成績壓力、沒有世俗壓力、更沒有人干預你,這更像是一個大學校園,參與者就在這樣的環境中自由發展,盡情做自己覺得有趣的事。


也許是教育體制的問題,也許是歷史文化所致,我們從小就沒有太多自由發展的機會,這讓不少人很晚才找到了自己的興趣。而進入社會後,缺少發自內心驅動的職場生活,讓更多人被生活所困,只能被世界及國內潮流被動的推著往前。我們有多久,沒有因學習新事物而開心?我們有多久,沒有因為與同伴們完成共同目標而感到興奮?那些再簡單不過的樂事,變成是種奢望。

這也是為什麼,我們發起了這樣的黑客松活動,試圖喚起人們的童趣以及熱情,讓人們在這找回自我學習的熱誠,以及團隊合作的心情,更重要的是,能夠學習如何貢獻並展現自己。在我們的活動中,無論結果的作品如何,這些種種對一個好的人才來說,都是不可或缺的要素。因為我們認為,台灣的人才素質普遍不錯,只是尚未有好的方法展示出來,並引出其真正價值而已。

共同持續參與,並逐漸改變這個社會氛圍,在這我們看見了人才們發光,也看見這片土地的希望。如果你問我說台灣黑客松每屆的活動能留下什麼?我會說,別的黑客松我不知道,但我知道我們的活動,讓人們帶回去的是提升後的自己與改變產業、社會的動力。

也許你沒發現,但經歷過這一切後,你已經不一樣了。

後記

不同於普通的活動,籌劃黑客松更為累人,除了要照顧的是兩天一夜的會眾,還要規劃各類課程與營造氛圍,更不能為了財務壓力下與中心思想背道而馳,複雜程度完全不可同日而語。

可愛的是,我們的參與者都是發自內心的願意主動參與,讓人非常欣慰。看到越來越多人熱衷於參加活動,讓我們更有信心一屆屆辦下去。

感謝你們,不是單純的被正妹團、龍蝦與砸大錢的大魚大肉所吸引過來,而這就是廣告公司永遠無法理解的文化。

io.js 的 ES6 Collection 支援 - Set

2015年1月29日 星期四
io.js 不做任何設定下,預設支援了一些 ECMAScript 6 的語法,其中包括一系列的 Collection 支援,這讓 JavaScript 在資料操作上多了一些方便之處。本文將討論到的 Set 物件,就是其中一個 Collection 類別。

簡單來說,Set 是一個類似 Array 的物件型態,可以用於處理有序的資料,而且內建迭代器(Iterator:在某些應用上同樣功能也會稱之游標 Cursor),讓開發者可以很容易對資料進行一筆筆的處理。

基本操作

基本的 Set 物件使用很簡單,如下所示:
// 建立一個新的 Set
var items = new Set();

// 依序加入資料
items.add('Fred');
items.add('Stacy');
items.add('Wesley');
items.add('Rance');
items.add('Kevin');
items.add('Alex');

// 依序印出 Set 物件內的所有資料
for (var item of items) {
    console.log(item);
}
比較特別的是,如果要依序印出 Set 物件內的所有資料,需要使用『of』這個關鍵字。原因是 Set 物件本身是一個 Generator 實作所致,如果我們想要一次把 Generator 內的工作跑完,需要運用 for-loop 加上 of 關鍵字來達成。

註:關於 Generator 與 of 關鍵字,日後有空再撰文說明其細節。總之,只要記得必須使用 of 關鍵字才能一一讀取 Set 物件內的資料,就像 Array 的 for-loop 加上 in 關鍵字。

刪除資料

刪除特定資料可以使用 remove() 方法來達成,如下所示:
items.remove('Wesley');
若是要清空資料,可以使用 clear() 方法:
items.clear();

檢查資料是否存在

我們可以直接利用 has() 方法檢查特定資料是否存在:
items.has('Rance');

迭代器(Iterator)的使用

Set 的迭代器是圍繞著 Generator 來實作,所以當我們想要利用 Set 的迭代器,可以使用 values() 方法來取得一個新的迭代器,然後開始對資料進行一筆筆的操作:
var iter = items.values();
// 印出 Fred
console.log(iter.next().value) ;
// 印出 Stacy
console.log(iter.next().value) ;

io.js 的文字範本(Template literals)支援

2015年1月28日 星期三
io.js 最大的特色,就是採用了最新的 V8 ,而且直接支援了 ECMAScript 6 的語法和特性,其中一項就是文字範本(Template Literals)的支援。這代表我們可以很容易在字串中代入其他的變數內容,就像一般的 Shell Script 一般,不必再像從前的方式,使用串接字串的方式達成。

如果想要使用這樣的文字範本(Template Literals),可以直接使用 ${} 來代入其他變數,然後以『`』字元將字串包起來,然後就可以將指定的變數內容代入到字串中:
var name = 'Fred';
var stringTemplate = `Hi, I am ${name}!`;

console.log(stringTemplate);
接著,如果你使用 io.js 來執行,就可以得到下列結果:
Hi, I am Fred!
Copyright @ 2013 Fred's blog. Designed by Templateism | MyBloggerLab
載入中…

誰在追蹤 Fred

您可以贊助 Fred 持續寫作

廣告與公益


Blog Archive