發表文章

JSDC 2013 簡報釋出!NPK 與 JavaScript OS (Stem) 登場!

最近比較忙,一直拖到現在,才有點時間上傳我在今年 JSDC 的簡報。這次,給的講題是『我編譯故我在:誰說 Node.js 程式不能編成 Binary』,主要探討怎麼使用 NPK 打包你寫的 Node.js 程式,以及把 JavaScript 程式碼編譯成二進位(Binary)檔,甚至是進一步的加密設計。NPK 雖然還只是初版,目前支援了三種博君一笑的封裝等級:卸妝(Remove mock-up)、媽媽不認識(Mom doesn't recognize)、爸爸不認識(Dad doesn't recognize),有興趣了解這三種等級不同的人,可以參考我的簡報: 當然,參加這種活動需要的是熱血,不在 Lightening Talk 閃電秀登場一下怎麼可以呢?於是當天毫不考慮的搶了一個名額,用短短的五分鐘介紹 Mandice 團隊最近在做的 JavaScript OS - 『 Stem 』。在 Stem 的平台之下,無論你是否為嵌入式系統或作業系統的高手,只需要懂 JavaScript 和純粹的 Web 相關技術,你就可以開發自己的嵌入式應用,或讓你的舊電腦或開發板有全新的用途。 後記 大家都知道,做外包工作,一向很難累積東西,唯一能累積的,就是設計工具以加速自己做案子的速度。因此,Stem OS 就是我們經歷過許多的案子後,自己設計的平台,讓我們可以盡可能完全用 JavaScript 快速開發嵌入式系統,然後結合硬體開發設計各式應用。在 Stem 裡,只需要懂 JavaScript 和 Web 相關技術,就能勝任開發工作,實現你心中的 Idea。如果說 3D Printer 是可以讓你快速打造模型實體,那 Stem OS,就是能將你心中的 Idea,化為空硬體的靈魂,Idea 的 3D Printer。 這對創業者、創新者和非資訊產業的公司來說,都是一個可以快速切入設計產品和自家工具的機會,不妨嘗試看看。:-) 如果有任何需求,無論是顧問、教育訓練還是合作開發,都歡迎與我們 Mandice 聯絡,或來信到 fred@mandice.com。

NPK 釋出!打包你的 Node.js 程式!

『 NPK 』是什麼?一個打包 Node.js 程式的工具,之所以會有這個工具,完全是拜下周(5/18 - 5/19)將在中研院舉行的 JSDC 所賜。因為這次筆者也有個 Talk,將探討如何去編譯我們寫出來的 Node.js 程式,所以過程中便寫出了這樣一個工具。 https://github.com/cfsghost/npk 事實上,目前的 NPK 不是個新東西。JavaScript 經過多年的發展,早已經有非常多合併 JavaScript 程式碼的工具可以使用,對於前端工程師來說,是再尋常不過。不過,針對 Node.js 的程式碼,這樣的工具卻相對來說非常少。 如果你想嘗試使用看看,可以立即用 NPM 來安裝 NPK: npm install npk -g 以 NPK 裡的範例專案為例,你可以直接下命令打包該專案: npk tests/purejs/ 接著你可以在輸出的資料夾中找到打包好的檔案: tests/purejs/out/app.js/ 甚至是直接執行他: node tests/purejs/out/app.js/app.js NPK 工具定義了一個新的屬性『npk_target』在 package.json,用來讓程式人員自行決定要合併和連結哪些 JavaScript 程式(像過去為 C/C++ 等語言寫 Makefile),可以參考 NPK 內附範例專案的 package.json。 最終目標『編譯』成二進位格式(Binary) 在與一些企業以及同業分享 Node.js 技術和其未來發展時,時不時會有人提出一個問題:『我們能不能編譯自己寫的 Node.js 程式?』這個問題,往往會開始引發一長串的討論,有一些人為終止這個問題,甚至會開始引用 JavaScript 語言的設計宗旨:『明碼保存,不需要預先編譯』,來強調我們不應該把 JavaScript 的優勢給閹掉。當然,這樣一廂情願的說法,是不可能消除許多人的疑慮,尤其是和 Open Source 路線不熟的企業,或是被『壞客戶欺負』的工程師。 有些眼睛比較亮的人,或許已經發現到,這其實是個複合性的命題,會提出這個問題的人,多半想要知道或得到的是: 能否透過預先編譯 JavaScript 程式,讓執行效能提升。 想要打包自己寫的程式,讓他合併成一個,以方便...

OSDC.TW 2013 簡報釋出!使用 JavaScript 大搞桌面應用和嵌入式系統!

OSDC.TW 2013 順利在中央研究院國際會議廳閉幕,但一如往年,失落感接踵而來。為了這次的 Talk,可說是花了不少工夫,除了研究 Webkit 的內部實作,以及 V8 JavaScript Engine 之外,最後也發表了一個新的 JavaScript 作業系統『 Stem 』,一個可以完全用 JavaScript 和 Web 技術去開發應用程式的嵌入式作業系統。Stem 落實了用 JavaScript 語言開發嵌入式系統的理想,並簡化嵌入式應用開發,讓人人都能輕鬆躍過以往嵌入式系統開發的艱澀門檻。 這邊釋出當天的簡報檔,有興趣者可自行參閱: 此外,對 Stem 有興趣的人,可以拜訪專案網站: http://stem.mandice.org/ 也可以在 IRC 上交流: 英文頻道:irc.freenode.net #stemos 中文頻道:irc.freenode.net #stemos-zh 註:目前 Stem 已釋出 x86 版本的安裝鏡像檔,近期內將會釋出 ARM 的版本,敬請期待。有興趣參與開發者,歡迎來信一同交流。

這年頭,你只需要懂 node-webkit !

極為幸運,今年初的投稿被 [ OSDC 2013 ] 錄取,本次主題是『node-webkit』,將於 4/20(六)早場起,全面進攻。 你可能在問什麼是『 node-webkit 』?完全搞不清楚頭緒?身為 JavaScript 和 Node.js 的重度使用者,問問自己內心吧!不用懷疑,你最想要的東西,就在眼前。試著想像,一個沒有邊框又可獨立執行的瀏覽器,裡面跑著你用 JavaScript + HTML5 寫的應用程式,有如原生的桌面應用程式,當你想發行並釋出程式時,還能打包成一個獨立運作的執行檔,令人垂涎三尺呀! 『node-webkit』顧名思義就是將 Node.js 整合進 webkit(Chrome/Chromium/Sarfari 所用的網頁排版引擎)之中,讓你可以在網頁程式中使用功能強大的 Node.js。這意味著,你完全可以用 Node.js + HTML5 等 Web technology 開發跨平台『桌面應用程式』。由於『node-webkit』狹著 Node.js 以及其強大的第三方模組支援,而使用者介面採用了 Chromium(Google Chrome 的開放源始碼版本)核心當做繪圖引擎,能完全支援當前最新的各種網頁技術(如:HTML5、CSS3、WebGL 等)。因此,只要身為一個前端網頁開發者,都能輕易利用它設計出優雅、炫麗的圖形化介面,然後完成一支獨立運行的桌面應用程式。 如官方網站的範例,在前端網頁程式中使用 Node.js: <html> <head> <title>Hello World!</title> </head> <body> <h1>Hello World!</h1> We are using node.js <script>document.write(process.version)</script> </body> </html> 這年頭,你真的只需要懂 node-webkit!我們 OSDC 2013 中研院國際會議廳見!

歡迎洽詢!Node.js on Embedded System 專業技術服務!

經過一年多的孕釀,我們的團隊【Mandice】已有萬全的準備,在此正式對外宣布提供 Node.js on Embedded System 的專業技術服務,歡迎立即來信洽詢。 嵌入式系統開發生態已經改變,今天的 Node.js 已為嵌入式系統帶來全新的面貌,其高效開發的優勢,以及不俗的效能和數不清的現成模組,讓嵌入式系統的產品開發周期以及技術門嵌大大降低。導入使用 Node. js 能讓產品設計者,更能專注於創新和使用者體驗,因應這時代的快速發展。 我們的團隊在這一年間,已經深耕各類 Node.js 相關技術,更結合團隊過去的系統技術和產品經驗,提供了整套的系統軟體平台以及顧問服務給許多合作夥伴和大廠,讓其開始以 Node.js 開發自家產品。至今,已有一些面世或即將面世的產品,使用了 Node.js 的技術開發嵌入式系統,甚至已經著手準備第二代產品,成效相當不錯。 若您也想趕上這班列車,歡迎與我們聯繫,我們將提供您最好的服務。 有意請來信至電子郵件信箱,我們會立即與您聯繫: fred@mandice.com

Node.js EventEmitter 事件管理神器

如果你已經相當熟悉 JavaScript 的開發,那就肯定對其事件機制不陌生。我們等待一個物件產生事件,去觸發我們設定的 callback 函式,是最常見不過的東西了。不過,如果你想要設計一個自己的物件,並容許別人可以監聽它的事件,要怎麼做呢? 如果你什麼都沒有,你肯定是在自己的物件中宣告一個 event handler 的表,當別人想要針對特定的事件掛上 callback function 時,就記錄在該表內。然後在事件被產生時,去呼較對應事件的所有 callback function。然後,你會設計像 .on() 、off() 和 emit() 之類的方法,讓別人可以使用。 是的,很累。既然事件機制是我們在 JavaScript 中常用的功能,每個物件都寫一次這樣簡單的事件管理,真的很浪費時間。其實,Node.js 本來就有實作這樣的機制『EventEmitter』讓開發者直接使用。 EventEmitter 的使用方法很簡單: var util = require('util'); var events = require('events'); var MyClass = function() { }; util.inherits(MyClass, events.EventEmitter); MyClass.prototype.ping = function() { this.emit('response', 'pong'); }; 實際使用這個 Class 建立物件,然後監聽事件,最後觸發事件: var myClass = new MyClass(); myClass.on('response', function(msg) { console.log(msg); }); myClass.ping(); 後記 把 EventEmitter 的繼承寫在 Class 宣告和 prototype 宣告之間很彆扭,但在 Class 宣告後立即使其繼承 EventEmitter 是正確的邏輯行為,所以,勉強接受他吧。

Release GContext Node.js Module!

How to write a native desktop application in Node.js? Perhaps you know many modules can do that easily, something's like node-gui and jsdx-toolkit. In order to develop system program, DBus module is the most important thing you must have as well. With Dbus module, you can handle all communications between programs. Furthermore, you can control low-level functions system provided via DBus, which includes hardware, networking and operation system features. Unfortunately, all things do not work at all since new version of Node.js. Many system libraries are based on GLib, and work with GLib event loop. For writing a node.js binding with such libraries, libev is the only way to integrate event loop between node.js event loop and GLib main context. The problem is that libev is deprecated since 0.8 node.js cause modules which depends on libev will be broken on latest and higher version. Nothing works if there is no libev. In fact, upstream announced that libuv is being only one way to...

AppHouse 簡報釋出!

昨日應邀參加『 企業雲端環境建置與應用技術研討會 』,給予一場『AppHouse - 國產 PaaS』的簡報分享,聽眾相當熱情,在會後也一起相互討論了許多技術與非技術等議題。這次的分享,主要在說明 AppHouse Project 的細節,並闡述了 PaaS 在雲端產業中的定位。為了讓聽眾更能理解,也特意以小弟的淺見和觀點,用簡單明瞭的方式描述『什麼是雲端』。 後記 會後與不少人交流,發現過去很多人被『雲端』一詞搞糊塗了,不能理解。如果你也有此困擾,不妨可以看看此簡報。 若您有任何疑問,或需要協助的地方,歡迎與我聯絡。:-)

jsdx-power 讓你使用 JavaScript 實現電源管理

既然會成立新創公司,總有些自己的想法,也期望做一些和其他人不一樣的事,對我們而言,改變世界事小,留下長久價值更重要。也許你有點印象,筆者今年度到處給予的 Talk,多半都是與 Node.js 相關,也透漏許多正在執行的計劃。因此,有些人可能聽過筆者提及『JSDX Framework』,這是『 Mandice 』的長期計劃,也是將 JavaScript 落實在系統、桌面和嵌入式裝置的解決方案。 由於 JSDX 是一個開放原始碼專案,市場上也已經有一些產品和公司專案導入使用,但因為合約的關係,我不能透漏太多細節,所以本文將只討論些許技術細節。說到這,也許你還是沒什麼概念,但若是真要舉出最直接與其相關的專案,就是今年 8 月,於 COSCUP 一場議程中所公開的『JUICE Desktop Environment』(簡報檔詳見舊文: 【COSCUP 2012】閉幕!簡報釋出! ),完全以 JavaScript 實作的 3D 桌面環境。 JSDX 包括許多元件,從 GUI Toolkit(使用者界面)、Multimedia Player(多媒體播放)、Network Manager(網路管理)到 Sound Manager(聲音管理)等,提供了各類系統控制或硬體相關的 APIs。程式開發者只需要會 JavaScript 語言,就可以使用這些 JSDX 所提供的 APIs ,開發各類應用程式或系統程式。 回應本文標題,JSDX 如果可以拿來開發桌面環境,當然也有電源管理相關的 APIs 可使用。所以在這邊我們要討論的元件是『 jsdx-power 』,你可以在 github 上取的他的 Source Code,亦或是直接透過 npm 安裝。 npm install jsdx-power 這邊簡單示範如何使用 JavaScript 透過『jsdx-power』命令作業系統休眠: var Power = require('jsdx-power'); var power = new Power; power.init(function() { power.suspend(); }); 後記 JUICE DE 的 juice-panel 電量顯示,就是使用了 jsdx-power,有興趣的人可以參考其 Source Code。

Node.js 裡的 JavaScript Array 非同步操作

如果你原本是一個專業的前端工程師,或許在 Node.js 出來之後,便開始嘗試了 Server 程式的開發。然後發現,使用 JavaScript 開發 Server 程式的過程中,有很多的細節應該注意,尤其是碰上處理大量資料和 I/O 操作時,更要對 JavaScript 引擎的運作原理有一定程度的理解。因為,絕大多數的問題,都是出在非同步(Asynchronize)與同步(Synchronize)的機制上。 許多開發人員,都會認同在開發 Node.js 程式時,盡可能、甚至絕對不要使用『同步』的方法和 API,因為,那會打亂 JavaScript 事件引擎的運作,產生各種詭異的後疑症,而且非常難以除錯。如果你發現你的程式會莫明自己結束,或是程式運作的流程不如預期,可能就是掉入了『同步』與『非同步』的陷阱了。 如果你稍微翻過文件,就會發現,其實 Node.js 本身對很多的 API,已經同時提供了『同步』與『非同步』兩種版本供開發者使用。不過,雖然 Node.js API 都有提供『非同步』版本,但是有些根本東西,卻欠缺『非同步』的方法,像是本文標題所提到的『Array』,就是其中之一。 針對 Array 的諸多操作,最常見的莫過於 forEach 方法,用來處理每一個 Array item: var arr = [ 1, 2, 3, 4 ]; arr.forEach(function(element, index, arr) { // Processing }); console.log('Completed'); 然而,這個方法是『同步(Synchronize)』,也就是會讓整個程式阻塞,等所有 Array item 讀出和處理完之後,才顯示最後的『Completed』字串。 類似的東西,不少人也會使用純 for-loop 來實作,但也都是一樣的狀況: var arr = [ 1, 2, 3, 4 ]; for (var i in arr) { // Processing } console.log('Completed'); 想想看,如果 Array item 的數量相當多,又或者是每個 item 的處理時間相當長,整支程式會像死當一樣沒反應。要知道,讓一段程式跑太久,是 Event...

探究如何整合 GLib Main Event Loop 和 Node.js 的 libuv

圖片
在普通情況下,整合 GLib Main Event Loop 和 libuv 不是件平常人會做的事,因為,一般人使用著 GTK+、Clutter、DBus 等等函式庫(Library)時,永遠只會使用 GLib 而不會使用到第二套事件引擎。但是,在 Node.js 中,其事件引擎並不是 GLib,而是使用自己的『libuv』,想同時運行兩套事件引擎是不可能的,所以這將注定我們無法以 Node.js 去引入 GTK+、Clutter、DBus 等函式庫來使用。不過,天下文章一大抄,世界上所有事件引擎的設計差異不大,在理解 GLib Context 的運作後,我們還是可以嘗試將兩者整合在一起,協同運行。 簡單理解一下事件引擎,其說白了就是一個跑到天荒地老的無窮迴圈,不停的去檢查是否有事件被喚醒。所以,由此可知,兩套事件引擎不能被同時跑起來,因為任何一個事件處理的無窮迴圈,都將導致另一個事件處理的迴圈無法正常運作。所以,首要解決的課題,就是讓兩個無窮迴圈可以同時運作。 為了解決這樣的問題,你可能會想到去使用 Thread (執行緒/線程),只要在建立兩個 Thread,然後各自跑不同的事件引擎就可以了。但是這樣做,問題馬上就會出現。由於程式正在運作的過程中,事件數量相當多,事件被安插和喚醒的次數非常頻繁,這將導致兩個 Thread 之間很難維持穩定的資料交換,你得實作 Mutex Lock 等機制來達成 Thread-safe,更還要想辦法解決兩邊各類大小資料交換的需求。種種原因,都會造成兩個事件引擎大量的彼此等待,而效能不彰。此外,也不易同時控制兩邊的事件觸發順序,以及事件被喚醒時間的精確度,如計時器(Timer)。 既然使用 Thread 是不好的做法,是否有其他方式可以解決我們一開始的課題?解決方法是有的,從事件引擎的運作細節,我們可以發現一些端倪。 一般來說,大部份的事件引擎都包括了幾個部份: 從 Initial 出發, Event Loop 的迴圈每運行一次,都經歷了『prepared』、『Polling』和『Dispatching』三種狀態,若用白話來說,他們所代表的意義就是『已準備好事件清單』、『監控事件』、『喚醒、分配並處理事件』。 如果你去參考事件引擎程式碼,會發現在三個狀態之間,分別有『prepare()』、『query(...

MongoDB Replication 簡記

就在幾天前,MongoDB 邁入了 2.2.0 的穩定版本。我們若回頭來看,MongoDB 一直到了 2.0 前後,比起早期版本,已經有長足的進步,並且支援了相當多的功能,也對規模化和資料庫系統管理下了很多功夫。對於大多數的資料庫應用,已經非常適合。 若你對資料庫相關技術有些了解,就會知道,當資料庫的資料發展一定規模程度,或是要確保系統不當機時,我們就需要用到 Master/Slave 的方式去備份和備援,當主要(Master)伺服器出了問題,次要(Slave)伺服器便即時補上,保持系統運作。但是,既然已經有 Master/Slave 機制,是否可以有更多台備援呢?更或者進一步,將讀寫分開在不同伺服器,以分攤流量和系統負載,並加速讀寫速度。而 Replication 就是這樣的機制,可以用來動態同步多台資料庫伺服器的資料,也可以當主要伺服器因故下線時,讓其他伺服器即時替補主要機器的位置。 在 Debian 上設定 MongoDB 的 Replication 相當容易,首先在想要變成主要(Primary)的機器上,打開設定檔(/etc/mongodb.conf),並為我們的 Replication 群組命名(在 MongoDB 中稱為 ReplSet,一些書籍內翻譯成『複製組』): replSet = mydb 重新啟動 MongoDB: $ sudo service mongodb restart 使用指令 mongo,進入 MongoDB 命令模式: $ mongo 於 MongoDB 命令模式中執行: # 初使化 replSet rs.initiate(null) # 加入自己的 IP 位置 rs.add("192.168.11.1:27017") 若是回應成功,請先稍待數秒鐘,等伺服器偵測和初使化。然後會發現 MongoDB 的命令提示字元從『SECONDARY』變成『PRIMARY』,此時,代表這台機器已經變成 ReplSet(複製組) 中的主要機器。 同樣的,你可以開始為 ReplSet 加入其他次要的資料庫伺服器: rs.add("192.168.11.2:27017") rs.add("192.168.11.3:27017") rs.add("192....