Intel EdsionでNode.jsのサーバを動かす
続いて、Node.js + expressでWebサーバを立ち上げてみます
パッケージマネージャの更新
Yoctoではapt-getとかではなく、opkgというパッケージマネージャを使うようです。これを最新にしておきます。 こちらを参考に
# cd /etc/opkg # curl http://nonnoise.github.io/Edison/_sources/Edison/base-feeds.conf # curl http://nonnoise.github.io/Edison/_sources/Edison/intel-iotdk.conf # curl http://nonnoise.github.io/Edison/_sources/Edison/mraa-upm.conf
アップデートしておきます
# opkg update # opkg upgrade
Node.jsの確認
とりあえずコマンド叩いてみましょう
# node > (^C again to quit) >
間違いなくNode.jsが入ってます。バージョンは
# node -v v0.10.28
そして、Nodeのパッケージマネージャであるnpmも入ってます
# npm Usage: npm <command> where <command> is one of: add-user, adduser, apihelp, author, bin, bugs, c, cache, completion, config, ddp, dedupe, deprecate, docs, edit, explore, faq, find, find-dupes, get, help, help-search, home, i, info, init, install, isntall, issues, la, link, list, ll, ln, login, ls, outdated, owner, pack, prefix, prune, publish, r, rb, rebuild, remove, repo, restart, rm, root, run-script, s, se, search, set, show, shrinkwrap, star, stars, start, stop, submodule, t, tag, test, tst, un, uninstall, unlink, unpublish, unstar, up, update, v, version, view, whoami npm <cmd> -h quick help on <cmd> npm -l display full usage info npm faq commonly asked questions npm help <term> search for help on <term> npm help npm involved overview Specify configs in the ini-formatted file: /home/root/.npmrc or on the command line via: npm <command> --key value Config info can be viewed via: npm help config npm@1.4.9 /usr/lib/node_modules/npm
expressのインストール
npmが入っているので、npmでexpressをグローバルインストールします。
# npm install -g express
expressコマンドを使いたいのですが、そのままではパスが通っていません。どこにインストールされたのか調べます
# find / -name express /usr/lib/node_modules/iotkit-agent/node_modules/.bin/express /usr/lib/node_modules/iotkit-agent/node_modules/express /usr/lib/node_modules/iotkit-agent/node_modules/express/bin/express
どうやらグローバルインストールされたコマンドは.bin以下にシンボリックリンクが配置されるようなので、ここにパスを通します。ただしYoctoでは".bashrc"とか".bash_profile"ではなく、".profile"を読み込むようなので、ホームディレクトリに".profile"ファイルを作成して、そこにexportでパスを追加します。vimも無いようで、viエディタを使います。
# vi .profile
.profileにパスを追加します
export PATH=/usr/lib/node_modules/iotkit-agent/node_modules/.bin:$PATH
読み込み直します(rebootしてちゃんと読み込まれることを確認した方がいいでしょう)
# source .profile
パスを見てみます
# echo $PATH /usr/lib/node_modules/iotkit-agent/node_modules/.bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
expressでNode.jsサーバを作成
ここまで出来たら、あとはカンタンです。expressでフレームワークを生成して、Nodeを起動するだけです。テンプレートエンジンはejsを使います。
# express -e server create : server create : server/package.json create : server/app.js create : server/public create : server/public/javascripts create : server/public/images create : server/public/stylesheets create : server/public/stylesheets/style.css create : server/routes create : server/routes/index.js create : server/routes/user.js create : server/views create : server/views/index.ejs install dependencies: $ cd server && npm install run the app: $ node app # cd server && npm install # node app.js
ifconfigで調べたEdisonのIPアドレスにポート3000でアクセスしてみましょう。
というわけで、カンタンにWebサーバを起動させることができます。
たった1日で出来たWeb + Android + Arduinoのリアルタイム連携プロトタイピング
はじめに
今回のネタは、早稲田大学で行われているAndroidアプリ開発養成講座TechInstituteで、センサー回りの講座を受け持つことになり、Androidのセンサーを使った応用例として作成しました。
動作概要
Android
動作としては某L◯NEの「ふるふる」っぽい動作をAndroidでは行います。「加速度センサー」で、ある一定の加速度を超えたら、「GPSセンサー」で位置情報をサーバに送信します。Webサーバでは送信された位置情報をGoogleMapにマッピングします。
Arduino
Arduinoには何かセンサーを接続します。なんでもいいのですが、「照度センサー」とします。照度センサーにより、周囲が暗くなったらサーバに「暗くなった」ことを通知します。
Web
Webサーバは送られてきた位置情報のマッピングを行います。またブローカサーバがArduinoからのセンサー情報を、接続している全Android端末にPush配信を行います。
構成
ざっくりこんな感じです。
もうちょっと詳しく書くと
Androidアプリから、位置情報をMQTTプロトコルでブローカにpublishすることで、subscribeしているWebサーバがそれを受信して、GoogleMap上にマッピングします。Arduinoから「暗くなった」とブローカにpublishすると、Androidアプリでは事前にそのTopicをsubscribeしているようにしてあるので、Pushが飛んできます。※MQTTについてはこちらを参照
使っている技術は難しくありません。
- Androidアプリ:加速度センサー、GPSセンサー、MQTTクライアント
- Arduino:照度センサー、MQTTクライアント
- MQTTブローカサーバ:mosquitto
- Webサーバ:Node.js + WebSocket(Socket.IO) + MQTTライブラリ
それぞれの画面
Androidアプリ
スクリーンネームを入れて、スタートボタンを押して「振る」単純なアプリです。加速度センサーをチェックして、振れ幅が大きくなったら位置情報を送信します。
Arduino
UIは無いです。Cdsセルで周囲の照度を測定して、一定値以下になったら「暗くなった」と通知します。
AndroidにはPushで通知が飛んできます。
Web
Node.jsでWebSocketを使用して、送信された位置情報とスクリーンネームをマッピングします。
作成の流れ
- Androidのセンサー応用例のデモを作ろう
- ふるふるっぽいのなら、加速度センサーとGPSセンサーでできそうだな(ここまで前日案)
- 位置情報を表示するMapが欲しいな。んじゃMQTTを使ってNode.jsで受けるか
- MQTTブローカサーバ立てる
- PyhtonでMQTTのPubSubのサンプルを作成して動作を確認
- Node.js + Socket.IOでGoogleMap表示部作成
- MQTTライブラリをNode.jsに組み込んで、ブローカをSubscribeするようにする
- PythonでMQTTのサンプルのPublishを作成して、ダミーの位置情報をブローカに送信するとNode.js上のGoogleMap上にマッピングできることを確認
- Androidアプリで加速度センサーとGPSを組み合わせてアプリを作る
- MQTTライブラリを送信用に組み込んで、8で作成したtopicフォーマットに沿って送信するようにする
- Andoridアプリをふるふるすると、無事GoogleMapに表示できた\(^o^)/
- Arduinoも講義で扱うし、ArduinoにもMQTTクライアントがあるからこれも繋げてみよう
- 題材で使用する照度センサーとArduino Ethernetを組み合わせてMQTTでブローカに投げるようにする
- Androidアプリの方にArduinoの通知を受け取れるように、MQTTブローカへのSubscribeを追加
- ほぼ完成\(^o^)/
ここまででほぼ1日8時間くらいの作業という感じでした(途中買い物行ったりしてので、出来たのは夜中近く)
参考情報(Topicの扱い)
-
- subscribe "PUBLIC/location/port/all/#"
- publish "PUBLIC/location/state/hogefuga" ← hogefugaはスクリーンネームが入る
Node.js
- subscribe "PUBLIC/location/state/#"
-
- publish "PUBLIC/location/port/all/push"
※ArduinoのあたりのTopicの扱いが変だけど、最後取ってつけた関係上...
まとめ
ここに出てくる技術はひと通り経験したことがあるので、アイデアが出れば実装はさほど難しくありません。 だいたい1日の作業でこのくらいまでプロトタイピング実装できるんだなーと、あらためて今の技術の恩恵を感じました。逆に言えば、技術よりもアイデアの方が重要なのかも(こっちのが難しい)
さて、実装してみると色々展開できることが見えてきます。
MQTTなので上手くTopicのPublish/Subscribeのルールを決めてやることで
他にも
- ボタンでの通知を時間間隔での通知にして、ジオフェンスを使った遊びや監視?
- Arduino側をウェアラブルデバイスとしてアイデアを膨らますこともできそうです
- Arduino側を様々な家電に置き換えて考えると、コントローラ&通知システム作れますね
ソースコードは公開してもいいのですが、なんせ1日で作ったレベルなのでちょっと...
要望があれば整理して公開できるようにするかもしれません。
Node.js + Socket.IO + pm2でデーモン化とクラスタリング
Socket.IOをpm2でクラスタリングするには、ちょっと工夫が必要だったのでメモ
forever
Node.jsのデーモン化といえばforeverです。しかしクラスタリングしようとすると、Node.jsのコードをクラスタリング対応で書かないといけないのでやや面倒だったりします。今回、foreverよりも高機能なpm2を使ってクラスタリングを試してみました。
pm2
pm2はforeverと同じようにNode.jsをデーモン化するツールですが、モニタ機能やクラスタリング機能などかなり高機能になっています。
pm2のインストール
pm2はグローバルでインストールします。
$ npm install -g pm2
対応するNode.jsのバージョンは古いと動かないかもしれません。今回はv0.10.20(on Mac)で動作確認しました。動かすNode.jsアプリはこちらのSocket.IOのサンプルアプリです。このコードだとSocket.IOのバージョンが古いようなので、一旦npm uninstall socket.ioして、再度npm install socket.ioで再インストールしました。
pm2を使ってクラスタリング
$ pm2 start app.js -i max
として起動するとプロセスがCPUコア数分だけ起動し、クラスタリングされます。簡単ですね。起動リストを表示させるには
$ pm2 list
プロセスが4つ起動されているのがわかります。この時にブラウザでアクセスして確認します。
片方がxhr-pollingになってたりしますね。これリロードするとwebsocketになったり、xhr-pollingになったりなんとも不安定になります。
ログを表示するには
$ pm2 logs
ところどころに警告がでています。
warn - client not handshaken client should reconnect
調べてみるとSocket.IOの接続に起因するものでSocket.IO or WebSocket を AmazonELB でバランスする検証にありました。
つまり、 Socket.IO は接続確立までに 2 回リクエストを投げるということです。 そしてこの最初の要求と、 WS の接続要求は、「同じインスタンス」にアクセスする必要があります。 二つの接続がバランスされて別々のサーバに行くと、ハンドシェイクがエラーになり、リトライが発生します。 たまたま二回同じサーバにいけば、接続が確立できるので、バランスするサーバが増えるほど成功確率が減 り、確立までの時間が長くなります。
redisの導入
解決策としてredisをセッションキーストアとして利用する、ということのようです。今更だけどSocket.ioについてまとめてみる
redisのPub/Subを利用して、各プロセス間でセッション共有をするということです。
このサイトの記事のとおりなのですが、ひと通りメモ
redisのインストールと起動
$ brew install redis $ redis-server /usr/local/etc/redis.conf & [1] 3234 $ [3234] 31 Jan 11:29:03.112 * Max number of open files set to 10032 _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 2.8.1 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in stand alone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 3234 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' [3234] 31 Jan 11:29:03.113 # Server started, Redis version 2.8.1 [3234] 31 Jan 11:29:03.113 * The server is now ready to accept connections on port 6379
redisのpub/sub機能
redisにはpublisher/subscriberという機能があって、いずれかのプロセスが受けた通知をredisに設定することで、他のプロセスに通知を行い共有できるということです。この機能を使うことでクラスタリングされたプロセス間でセッションの共有を行えます。
サーバアプリの書き換え
app.jsを以下のように書き換えます
var app = express() , server = http.createServer(app) , redis = require('socket.io/lib/stores/redis') // socket.ioにredisがある , redisConf = { host: '127.0.0.1', port: 6379 } , io = require('socket.io').listen(server); // storeタイプをredisに変更 io.set('store', new redis({ redisPub: redisConf, redisSub: redisConf, redisClient: redisConf }));
pm2でクラスタリング
再びpm2でクラスタリングを試してみます。
$ pm2 start app.js -i max
この時のアクセスログを見ると警告が無くなり、かつ正常にクラスタリングされているようです\(^o^)/
BeagleBone BlackのUbuntuにbonescriptをインストールする
デフォルトのAngstromではなく、Ubuntuの方にbonescript入れてやればいいよね?的な発想でインストール
Node.js v0.10.21でインストール
前々回にインストールしたv0.10.12でbonescriptをインストールしてみます
ubuntu@ubuntu-armhf:~$ npm install -g bonescript npm http GET https://registry.npmjs.org/bonescript npm http 304 https://registry.npmjs.org/bonescript > bonescript@0.2.3 preinstall /home/ubuntu/.nodebrew/node/v0.10.21/lib/node_modules/bonescript > node-gyp clean || (exit 0); node-gyp configure build make: Entering directory `/home/ubuntu/.nodebrew/node/v0.10.21/lib/node_modules/bonescript/build' CXX(target) Release/obj.target/misc/misc.o ../misc.cpp:1:0: warning: "BUILDING_NODE_EXTENSION" redefined [enabled by default] <--中略--> make: *** [Release/obj.target/misc/misc.o] Error 1 make: Leaving directory `/home/ubuntu/.nodebrew/node/v0.10.21/lib/node_modules/bonescript/build' gyp ERR! build error gyp ERR! stack Error: `make` failed with exit code: 2 gyp ERR! stack at ChildProcess.onExit (/home/ubuntu/.nodebrew/node/v0.10.21/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:267:23) gyp ERR! stack at ChildProcess.EventEmitter.emit (events.js:98:17) gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:789:12) gyp ERR! System Linux 3.8.13-bone30 gyp ERR! command "node" "/home/ubuntu/.nodebrew/node/v0.10.21/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "build" gyp ERR! cwd /home/ubuntu/.nodebrew/node/v0.10.21/lib/node_modules/bonescript gyp ERR! node -v v0.10.21 gyp ERR! node-gyp -v v0.10.10 gyp ERR! not ok npm ERR! weird error 1 npm ERR! not ok code 0
おうふ・・・
bonescriptは対応Nodeバージョンがある
ググったところ、こんな情報を発見。Installing Ubuntu 13.10, Node.js, bonescript.js on BBB
I had to make some changes when installing node.js in order to get bonescript.js installed. Bonescript.js is only compatible with node.js v0.8 Github issue #53.
たしかにAngstromの場合v0.8.22でした。というわけで、v0.8.22をインストール。こういう時にnodebrewを使ってると便利ですね。
Node.js v0.8.22をインストール
ubuntu@ubuntu-armhf:~$ nodebrew install v0.8.22 -- ビルド約1時間-- ubuntu@ubuntu-armhf:~$ nodebrew ls v0.8.22 v0.10.21 current: v0.10.21 ubuntu@ubuntu-armhf:~$ nodebrew use v0.8.22 use v0.8.22
あらためてbonescriptをインストール
ubuntu@ubuntu-armhf:~$ npm install -g bonescript > serialport@1.0.6 install /home/ubuntu/.nodebrew/node/v0.8.22/lib/node_modules/bonescript/node_modules/serialport > node-gyp rebuild -- 中略 -- make: Entering directory `/home/ubuntu/.nodebrew/node/v0.8.22/lib/node_modules/bonescript/node_modules/serialport/build' CXX(target) Release/obj.target/serialport/src/serialport.o CXX(target) Release/obj.target/serialport/src/serialport_unix.o SOLINK_MODULE(target) Release/obj.target/serialport.node SOLINK_MODULE(target) Release/obj.target/serialport.node: Finished COPY Release/serialport.node make: Leaving directory `/home/ubuntu/.nodebrew/node/v0.8.22/lib/node_modules/bonescript/node_modules/serialport/build' bonescript@0.2.3 /home/ubuntu/.nodebrew/node/v0.8.22/lib/node_modules/bonescript ├── systemd@0.2.0 ├── i2c@0.1.4 (bindings@1.1.1, repl@0.1.3, underscore@1.2.4, coffee-script@1.3.3) ├── winston@0.6.2 (cycle@1.0.3, stack-trace@0.0.7, eyes@0.1.8, colors@0.6.2, pkginfo@0.2.3, async@0.1.22, request@2.9.203) ├── express@3.1.0 (methods@0.0.1, fresh@0.1.0, cookie-signature@0.0.1, range-parser@0.0.4, debug@0.7.4, buffer-crc32@0.1.1, cookie@0.0.5, commander@0.6.1, mkdirp@0.3.3, send@0.1.0, connect@2.7.2) ├── socket.io@0.8.7 (policyfile@0.0.4, redis@0.6.7, socket.io-client@0.8.7) └── serialport@1.0.6 (bindings@0.3.0, sf@0.1.3, async@0.1.18, optimist@0.3.7, node-gyp@0.6.2)
expressやらsocket.io, serialportなども同時にインストールされるようです。リストを取ってみます
ubuntu@ubuntu-armhf:~$ npm list -g /home/ubuntu/.nodebrew/node/v0.8.22/lib ├─┬ bonescript@0.2.3 │ ├─┬ express@3.1.0 │ │ ├── buffer-crc32@0.1.1 │ │ ├── commander@0.6.1 │ │ ├─┬ connect@2.7.2 │ │ │ ├── bytes@0.1.0 │ │ │ ├── formidable@1.0.11 │ │ │ ├── pause@0.0.1 │ │ │ └── qs@0.5.1 │ │ ├── cookie@0.0.5 │ │ ├── cookie-signature@0.0.1 │ │ ├── debug@0.7.4 │ │ ├── fresh@0.1.0 │ │ ├── methods@0.0.1 │ │ ├── mkdirp@0.3.3 │ │ ├── range-parser@0.0.4 │ │ └─┬ send@0.1.0 │ │ └── mime@1.2.6 │ ├─┬ i2c@0.1.4 │ │ ├── bindings@1.1.1 │ │ ├── coffee-script@1.3.3 │ │ ├── repl@0.1.3 │ │ └── underscore@1.2.4 │ ├─┬ serialport@1.0.6 │ │ ├── async@0.1.18 │ │ ├── bindings@0.3.0 │ │ ├─┬ node-gyp@0.6.2 │ │ │ ├─┬ fstream@0.1.25 │ │ │ │ ├── graceful-fs@2.0.1 │ │ │ │ └── inherits@2.0.1 │ │ │ ├─┬ glob@3.2.7 │ │ │ │ └── inherits@2.0.1 │ │ │ ├── graceful-fs@1.2.3 │ │ │ ├─┬ minimatch@0.2.14 │ │ │ │ ├── lru-cache@2.5.0 │ │ │ │ └── sigmund@1.0.0 │ │ │ ├── mkdirp@0.3.5 │ │ │ ├─┬ nopt@2.1.2 │ │ │ │ └── abbrev@1.0.4 │ │ │ ├─┬ npmlog@0.0.6 │ │ │ │ └── ansi@0.2.1 │ │ │ ├── osenv@0.0.3 │ │ │ ├── request@2.9.203 │ │ │ ├── rimraf@2.2.5 │ │ │ ├── semver@1.1.4 │ │ │ ├─┬ tar@0.1.19 │ │ │ │ ├── block-stream@0.0.7 │ │ │ │ └── inherits@2.0.1 │ │ │ └── which@1.0.5 │ │ ├─┬ optimist@0.3.7 │ │ │ └── wordwrap@0.0.2 │ │ └── sf@0.1.3 │ ├─┬ socket.io@0.8.7 │ │ ├── policyfile@0.0.4 │ │ ├── redis@0.6.7 │ │ └─┬ socket.io-client@0.8.7 │ │ ├── uglify-js@1.0.6 │ │ ├── websocket-client@1.0.0 │ │ └── xmlhttprequest@1.2.2 │ ├── systemd@0.2.0 │ └─┬ winston@0.6.2 │ ├── async@0.1.22 │ ├── colors@0.6.2 │ ├── cycle@1.0.3 │ ├── eyes@0.1.8 │ ├── pkginfo@0.2.3 │ ├── request@2.9.203 │ └── stack-trace@0.0.7 └─┬ npm@1.2.14 ├── abbrev@1.0.4 ├── ansi@0.1.2 ├── archy@0.0.2 ├── block-stream@0.0.6 ├── chmodr@0.1.0 ├── chownr@0.0.1 ├── fstream@0.1.22 ├─┬ fstream-npm@0.1.3 │ └── fstream-ignore@0.0.6 ├── glob@3.1.21 ├── graceful-fs@1.2.0 ├── inherits@1.0.0 ├── ini@1.1.0 ├─┬ init-package-json@0.0.6 │ └── promzard@0.2.0 ├── lockfile@0.3.0 ├── lru-cache@2.2.2 ├─┬ minimatch@0.2.11 │ └── sigmund@1.0.0 ├── mkdirp@0.3.5 ├── node-gyp@0.8.5 ├── nopt@2.1.1 ├─┬ npm-registry-client@0.2.18 │ └── couch-login@0.1.15 ├─┬ npmconf@0.0.23 │ └─┬ config-chain@1.1.5 │ └── proto-list@1.2.2 ├── npmlog@0.0.2 ├── once@1.1.1 ├── opener@1.3.0 ├── osenv@0.0.3 ├─┬ read@1.0.4 │ └── mute-stream@0.0.3 ├── read-installed@0.1.1 ├── read-package-json@0.2.2 ├── request@2.9.203 ├── retry@0.6.0 ├── rimraf@2.1.4 ├── semver@1.1.4 ├── slide@1.1.3 ├── tar@0.1.16 ├── uid-number@0.0.3 └── which@1.0.5
これでUbuntuでもbonescriptを使ったNodeアプリが書ける・・・はず>たぶん次回
BeagleBone BlackのAngstrom Linuxに入ってるNode.jsについて
ちょっとだけ調べてみました。
Nodeのバージョン
root@beaglebone:~# node -v v0.8.22
Node Package Managerも入っているようです
root@beaglebone:~# npm Usage: npm <command> where <command> is one of: add-user, adduser, apihelp, author, bin, bugs, c, cache, completion, config, ddp, dedupe, deprecate, docs, edit, explore, faq, find, find-dupes, get, help, help-search, home, i, info, init, install, isntall, issues, la, link, list, ll, ln, login, ls, outdated, owner, pack, prefix, prune, publish, r, rb, rebuild, remove, restart, rm, root, run-script, s, se, search, set, show, shrinkwrap, star, stars, start, stop, submodule, tag, test, tst, un, uninstall, unlink, unpublish, unstar, up, update, version, view, whoami npm <cmd> -h quick help on <cmd> npm -l display full usage info npm faq commonly asked questions npm help <term> search for help on <term> npm help npm involved overview Specify configs in the ini-formatted file: /home/root/.npmrc or on the command line via: npm <command> --key value Config info can be viewed via: npm help config npm@1.2.14 /usr/lib/node_modules/npm
Nodeのパッケージを調べてみる
root@beaglebone:~# npm list -g /usr/lib ├─┬ bonescript@0.2.2 │ ├─┬ express@3.1.0 │ │ ├── buffer-crc32@0.1.1 │ │ ├── commander@0.6.1 │ │ ├─┬ connect@2.7.2 │ │ │ ├── bytes@0.1.0 │ │ │ ├── formidable@1.0.11 │ │ │ ├── pause@0.0.1 │ │ │ └── qs@0.5.1 │ │ ├── cookie@0.0.5 │ │ ├── cookie-signature@0.0.1 │ │ ├── debug@0.7.2 │ │ ├── fresh@0.1.0 │ │ ├── methods@0.0.1 │ │ ├── mkdirp@0.3.3 │ │ ├── range-parser@0.0.4 │ │ └─┬ send@0.1.0 │ │ └── mime@1.2.6 │ ├── UNMET DEPENDENCY serialport 0.7.5 │ ├─┬ socket.io@0.8.7 │ │ ├── policyfile@0.0.4 │ │ ├── redis@0.6.7 │ │ └─┬ socket.io-client@0.8.7 │ │ ├── uglify-js@1.0.6 │ │ ├── websocket-client@1.0.0 │ │ └── xmlhttprequest@1.2.2 │ ├── systemd@0.2.0 │ └─┬ winston@0.6.2 │ ├── async@0.1.22 │ ├── colors@0.6.0-1 │ ├── cycle@1.0.2 │ ├── eyes@0.1.8 │ ├── pkginfo@0.2.3 │ ├── request@2.9.203 │ └── stack-trace@0.0.6 └─┬ npm@1.2.14 ├── abbrev@1.0.4 ├── ansi@0.1.2 ├── archy@0.0.2 ├── block-stream@0.0.6 ├── chmodr@0.1.0 ├── chownr@0.0.1 ├── fstream@0.1.22 ├─┬ fstream-npm@0.1.3 │ └── fstream-ignore@0.0.6 ├── glob@3.1.21 ├── graceful-fs@1.2.0 ├── inherits@1.0.0 ├── ini@1.1.0 ├─┬ init-package-json@0.0.6 │ └── promzard@0.2.0 ├── lockfile@0.3.0 ├── lru-cache@2.2.2 ├─┬ minimatch@0.2.11 │ └── sigmund@1.0.0 ├── mkdirp@0.3.5 ├── node-gyp@0.8.5 ├── nopt@2.1.1 ├─┬ npm-registry-client@0.2.18 │ └── couch-login@0.1.15 ├─┬ npmconf@0.0.23 │ └─┬ config-chain@1.1.5 │ └── proto-list@1.2.2 ├── npmlog@0.0.2 ├── once@1.1.1 ├── opener@1.3.0 ├── osenv@0.0.3 ├─┬ read@1.0.4 │ └── mute-stream@0.0.3 ├── read-installed@0.1.1 ├── read-package-json@0.2.2 ├── request@2.9.203 ├── retry@0.6.0 ├── rimraf@2.1.4 ├── semver@1.1.4 ├── slide@1.1.3 ├── tar@0.1.16 ├── uid-number@0.0.3 └── which@1.0.5 npm ERR! missing: serialport@0.7.5, required by bonescript@0.2.2 npm ERR! not ok code 0
ふむふむ、bonescriptはもちろん、express, socket.io, serialportなどがグローバルインストールされていました。ということは、AngstromのままでもNode.jsでプログラム書いて動かして遊ぶのもいいですね
BeagleBone BlackにNode.jsをインストールする2(セルフビルド)
見事にビルドに失敗・・・ググってみたら、傘のお肉はどこにあるの?知り合いの@iwata_nのブログに引っ掛かったw
つまりは
./configure --without-snapshot
が必要ということなので、nodebrewのソースを修正して対応します。
nodebrew本体のコード(~./nodebrew/nodebrew)の「sub _cmd_install」にあるConfigureに--without-snapshotを追加します
system qq[ cd "$src_dir/$target_name" && ./configure --without-snapshot --prefix="$self->{node_dir}/$version" && make && make install ];
これでもう一度インストールしてみます。一旦さっきのバージョンをuninstallしておいてから再度インストール。
ubuntu@ubuntu-armhf:~$ nodebrew uninstall v0.10.21 v0.10.21 uninstalled ubuntu@ubuntu-armhf:~$ nodebrew ls not installed current: none ubuntu@ubuntu-armhf:~$ nodebrew install v0.10.21 fetch: http://nodejs.org/dist/v0.10.21/node-v0.10.21.tar.gz ######################################################################## 100.0% { 'target_defaults': { 'cflags': [], 'default_configuration': 'Release', 'defines': [], 'include_dirs': [], 'libraries': []}, 'variables': { 'arm_fpu': 'vfpv3', 'arm_neon': 0, 'armv7': 1, 'clang': 0, 'gcc_version': 46, 'host_arch': 'arm', 'node_install_npm': 'true', 'node_prefix': '/home/ubuntu/.nodebrew/node/v0.10.21', 'node_shared_cares': 'false', 'node_shared_http_parser': 'false', 'node_shared_libuv': 'false', 'node_shared_openssl': 'false', 'node_shared_v8': 'false', 'node_shared_zlib': 'false', 'node_tag': '', 'node_unsafe_optimizations': 0, 'node_use_dtrace': 'false', 'node_use_etw': 'false', 'node_use_openssl': 'true', 'node_use_perfctr': 'false', 'node_use_systemtap': 'false', 'python': '/usr/bin/python', 'target_arch': 'arm', 'v8_enable_gdbjit': 0, 'v8_no_strict_aliasing': 1, 'v8_use_arm_eabi_hardfloat': 'true', 'v8_use_snapshot': 'false'}}
「'v8_use_snapshot': 'false'」になっています。失敗した時のログを見てみると
fetch: http://nodejs.org/dist/v0.10.21/node-v0.10.21.tar.gz ######################################################################## 100.0% { 'target_defaults': { 'cflags': [], 'default_configuration': 'Release', 'defines': [], 'include_dirs': [], 'libraries': []}, 'variables': { 'arm_fpu': 'vfpv3', 'arm_neon': 0, 'armv7': 1, 'clang': 0, 'gcc_version': 46, 'host_arch': 'arm', 'node_install_npm': 'true', 'node_prefix': '/home/ubuntu/.nodebrew/node/v0.10.21', 'node_shared_cares': 'false', 'node_shared_http_parser': 'false', 'node_shared_libuv': 'false', 'node_shared_openssl': 'false', 'node_shared_v8': 'false', 'node_shared_zlib': 'false', 'node_tag': '', 'node_unsafe_optimizations': 0, 'node_use_dtrace': 'false', 'node_use_etw': 'false', 'node_use_openssl': 'true', 'node_use_perfctr': 'false', 'node_use_systemtap': 'false', 'python': '/usr/bin/python', 'target_arch': 'arm', 'v8_enable_gdbjit': 0, 'v8_no_strict_aliasing': 1, 'v8_use_arm_eabi_hardfloat': 'true', 'v8_use_snapshot': 'true'}}
こちらはtrueになっていました。
さてまたしても1時間経過・・・ビルド完了
symlinking ../lib/node_modules/npm/bin/npm-cli.js -> /home/ubuntu/.nodebrew/node/v0.10.21/bin/npm updating shebang of /home/ubuntu/.nodebrew/node/v0.10.21/bin/npm to /home/ubuntu/.nodebrew/node/v0.10.21/bin/node ubuntu@ubuntu-armhf:~$ nodebrew ls v0.10.21 current: none ubuntu@ubuntu-armhf:~$ nodebrew use v0.10.21 use v0.10.21 ubuntu@ubuntu-armhf:~$ node >
というわけで、無事Node.jsが起動できるようになりました。
BeagleBone BlackにNode.jsをインストールする(セルフビルド)
いつものようにNode.jsをインストールします。今回はnvmではなくnodebrewを使い、セルフビルドにてインストールします。
BeagleBone Black用のNode.js
ビルドするのが面倒な方はこちらにインストールバイナリがありますので、こちらを使ったほうが楽チンです。その場合はnodebrewは必要ありません。このリンク先のNode.jsのバージョンはv0.10.21なので、同じバージョンをnodebrewでセルフビルドでインストールします
ビルド環境のインストール
ubuntu@ubuntu-armhf:~$ sudo apt-get install curl build-essential libssl-dev
nodebrewのインストール
nodebrewに関してはBlock Rockin’ Codesに記事があるのでご参考に。nodebrewのサイトはこちらです。サイトにあるように下記コマンドでインストールできます。なおnodebrewをインストールするとnpm(Node Package Manager)も同時にインストールされます。
ubuntu@ubuntu-armhf:~$ curl -L git.io/nodebrew | perl - setup % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 18651 100 18651 0 0 18947 0 --:--:-- --:--:-- --:--:-- 18947 fetching nodebrew... install nodebrew in $HOME/.nodebrew ======================================== Add path: export PATH=$HOME/.nodebrew/current/bin:$PATH ========================================
インストールしたら、上記パスをvimなどで.bashrcに追加して、sourceコマンドで読み込みなおしておきます
ubuntu@ubuntu-armhf:~$ vim .bashrc ubuntu@ubuntu-armhf:~$ source .bashrc
nodebrew ls-remoteで使えるNode.jsのバージョンが取得できます
ubuntu@ubuntu-armhf:~$ nodebrew ls-remote -- 省略-- v0.9.0 v0.9.1 v0.9.2 v0.9.3 v0.9.4 v0.9.5 v0.9.6 v0.9.7 v0.9.8 v0.9.9 v0.9.10 v0.9.11 v0.9.12 v0.10.0 v0.10.1 v0.10.2 v0.10.3 v0.10.4 v0.10.5 v0.10.6 v0.10.7 v0.10.8 v0.10.9 v0.10.10 v0.10.11 v0.10.12 v0.10.13 v0.10.14 v0.10.15 v0.10.16 v0.10.17 v0.10.18 v0.10.19 v0.10.20 v0.10.21 v0.10.22 v0.10.23 v0.11.0 v0.11.1 v0.11.2 v0.11.3 v0.11.4 v0.11.5 v0.11.6 v0.11.7 v0.11.8 v0.11.9
nodebrewにはバイナリのインストール機能がありますので、試しにv0.10.21をインストールしようとすると、サポートしてないよ!ってエラーが出てしまいます。
ubuntu@ubuntu-armhf:~$ nodebrew install-binary v0.10.21 Error: Linux armv7l is not supported. at /home/ubuntu/.nodebrew/current/bin/nodebrew line 585.
Node.jsのセルフビルドでのインストール
というわけで、セルフビルドでインストールします (ちなみに以下、失敗します...ちゃんと動くようにビルドするにはコチラへ)
ubuntu@ubuntu-armhf:~$ nodebrew install v0.10.21
セルフビルドは約1時間・・・(class2のSDカードだったのでclass10だともっと速いと思われ)
installing /home/ubuntu/.nodebrew/node/v0.10.21/lib/node_modules/npm/lib/utils/completion/installed-shallow.js installing /home/ubuntu/.nodebrew/node/v0.10.21/lib/node_modules/npm/lib/utils/completion/file-completion.js symlinking ../lib/node_modules/npm/bin/npm-cli.js -> /home/ubuntu/.nodebrew/node/v0.10.21/bin/npm updating shebang of /home/ubuntu/.nodebrew/node/v0.10.21/bin/npm to /home/ubuntu/.nodebrew/node/v0.10.21/bin/node
ちゃんとインストールされたか確認
ubuntu@ubuntu-armhf:~$ nodebrew ls v0.10.21 current: none
v0.10.21を使用するように指定
ubuntu@ubuntu-armhf:~$ nodebrew use v0.10.21 use v0.10.21 ubuntu@ubuntu-armhf:~$
さて、ではnodeを起動してみます
ubuntu@ubuntu-armhf:~$ node Segmentation fault _人人人人人人人人人人人_ > Segmentation fault <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
...orz