Use Node.js DDP Client on Arduino Yun to Access Meteor Server

概述

在Arduino Yun上安装 Node.js, 并測试与 Meteor 通过 DDP Client 通讯。

所用硬件

  • Arduino Yun
  • SD Card(至少 2GB,我使用的是 8G )

所用软件

PC 软件:

  • Arduino IDE
  • SSH Terminal(Putty / Screen)

升级 Arduino Yun固件

  1. 从站点上下载 Arduino Yun 最新的 openWRT 固件, 当前升级包的版本号是 YunSysupgradeImage_v1.5.3.zip。

  2. 选用 MS-DOS 方式格式化 SD Card,将所下载的 ZIP 文件展开出的 bin 文件复制到 SD Card 的根文件夹下。

  3. 将 SD Card 插入 Arduino Yun, 并重新启动 Arduino Yun。正常情况下,应该能够在 Web Page 点按 “RESET” 按钮运行升级。

raw=true" alt="RESET" title="">

也能够用 SSH 登陆后,先检查一下 /mnt/sda1 文件夹下是否有升级文件,并运行下面命令。

    # ls /mnt/sda1
openwrt-ar71xx-generic-yun-16M-squashfs-sysupgrade.bin # run-sysupgrade /mnt/sda1/openwrt-ar71xx-generic-yun-16M-squashfs-sysupgrade.bin
  1. 升级完毕后。选择 ArduinoYun 的初始 WIFI。并通过 Web 页面訪问 192.168.240.1。设置 Arduino Yun 的网络连接。

利用 SD Card 扩展 Arduino Yun 空间

Arduino Yun 的板上存储仅有 16M,要想安装很多其它地东西就必须利用 SD Card 扩展磁盘空间。參考链接

  1. 重新启动后,通过本地局域网。SSH 到 Arduino Yun上,检查现有的分区情况。

    # df
    Filesystem 1K-blocks Used Available Use% Mounted on
    rootfs 7104 364 6740 5% /
    /dev/root 7680 7680 0 100% /rom
    tmpfs 30560 148 30412 0% /tmp
    tmpfs 512 0 512 0% /dev
    /dev/mtdblock3 7104 364 6740 5% /overlay
    overlayfs:/overlay 7104 364 6740 5% /
    /dev/sda1 7746772 1008 7745764 0% /mnt/sda1
  2. 下载 YunDiskSpaceExpander.zip

  3. 通过 USB 连接 Arduino Yun,打开 Arduino IDE 上传此 ino 文件, 然后打开 Serial Monitor。在屏幕右下方选择 “Newline”, 并依照提示进行操作。下面的操作记录了我为分区方式,供參考。须要注意的是,此处输入的 4096 的意思是,将 4G 的空间保留为 /mnt/sda1 下的数据存储,剩下的空间留给根文件夹。

    整个过程须要等待几分钟。

    Open the Serial Monitor and double check the dropdown menu "Newline" has been selected.
    
    This sketch will format your micro SD card and use it as additional disk space for your Arduino Yun.
    Please ensure you have ONLY your micro SD card plugged in: no pen drives, hard drives or whatever.
    Do you wish to proceed (yes/no)? yes Starting Bridge... Ready to install utility software. Please ensure your Arduino Yun is connected to internet.
    Ready to proceed (yes/no)? yes
    Updating software list...
    Software list updated. Installing software (this will take a while)...
    e2fsprogs mkdosfs fdisk rsync installed Proceed with partitioning micro SD card (yes/no)? yes
    Enter the size of the data partition in MB: 4096
    Partitioning (this will take a while)...
    Micro SD card correctly partitioned Creating 'arduino' folder structure...
    Copying files from Arduino Yun flash to micro SD card...
    Enabling micro SD as additional disk space... enabled We are done! Yeah! Now press the YUN RST button to apply the changes.
  4. 按下 YUN RST 后等待系统全然重新启动,再次检查分区情况,能够看到,Root 文件夹已经被放置在 /dev/sda2 下了,大小已经被扩大。

    # df
    Filesystem 1K-blocks Used Available Use% Mounted on
    rootfs 3556712 120920 3257464 4% /
    /dev/root 7680 7680 0 100% /rom
    tmpfs 30560 100 30460 0% /tmp
    tmpfs 512 0 512 0% /dev
    /dev/sda2 3556712 120920 3257464 4% /overlay
    overlayfs:/overlay 3556712 120920 3257464 4% /
    /dev/sda1 4186104 12 4186092 0% /mnt/sda1

安装 Node.js

确认 Arduino Yun 能够正常联网,然后运行下面安装 Node.js。 原文參考链接

# opkg update
# opkg install node

安装完毕之后,能够用下面命令检查 Node.js 成功安装

# node -e "console.log('Hello_Yun')"
Hello_Yun

Arduino Yun 可用的全部 Package 能够在这里找到。

您还能够依据须要,安装很多其它的 Node.js 基础包,比如:

# opkg install node-serialport
# opkg install node-noble

设置 Swap 区

Arduino Yun 提供的 Node.js 包非常有限。还须要通过 npm 安装很多其它可扩展包。可是由于 npm 所需的内存比較大,我们必须打开 Swap 才干够顺利运行,否则会报内存不足。

  1. 检查现有的 Swap 设置

    # free -m
    total used free shared buffers
    Mem: 61116 31712 29404 0 8364
    -/+ buffers: 23348 37768
    Swap: 0 0 0
  2. SSH 登陆后。创建 Swap 分区。这一步要等比較长的时间。

    # mkdir /swap
    
    # dd if=/dev/zero of=/swap/yunswapfile bs=1M count=1024
    1024+0 records in
    1024+0 records out
  3. 设置 Swapon。此时已经能够看到 Swap 区正确创建了。

    # mkswap /swap/yunswapfile
    # swapon /swap/yunswapfile # free -m
    total used free shared buffers
    Mem: 61116 59704 1412 0 7676
    -/+ buffers: 52028 9088
    Swap: 1048572 0 1048572
  4. 设置启动时自己主动载入 Swap。重新启动 Arduino Yun 后。Swap 区应该正常。

    # uci add fstab swap
    # uci set fstab.@swap[0].device=/swap/yunswapfile
    # uci set fstab.@swap[0].enabled=1
    # uci set fstab.@swap[0].fstype=swap
    # uci set fstab.@swap[0].options=default
    # uci set fstab.@swap[0].enabled_fsck=0
    # uci commit

安装 DDP Client

此时,我们再使用 npm 安装 DDP Client。

我使用的 DDP Client 是 https://www.npmjs.com/package/ddp

# npm install ddp
# npm install underscore # npm list
/root
├─┬ ddp@0.11.0
│ ├── ddp-ejson@0.8.1-3
│ ├── ddp-underscore-patched@0.8.1-2
│ ├─┬ faye-websocket@0.9.4
│ │ └─┬ websocket-driver@0.5.4
│ │ └── websocket-extensions@0.1.1
│ └─┬ request@2.53.0
│ ├── aws-sign2@0.5.0
│ ├─┬ bl@0.9.4
│ │ └─┬ readable-stream@1.0.33
│ │ ├── core-util-is@1.0.1
│ │ ├── inherits@2.0.1
│ │ ├── isarray@0.0.1
│ │ └── string_decoder@0.10.31
│ ├── caseless@0.9.0
│ ├─┬ combined-stream@0.0.7
│ │ └── delayed-stream@0.0.5
│ ├── forever-agent@0.5.2
│ ├─┬ form-data@0.2.0
│ │ └── async@0.9.2
│ ├─┬ hawk@2.3.1
│ │ ├── boom@2.7.2
│ │ ├── cryptiles@2.0.4
│ │ ├── hoek@2.14.0
│ │ └── sntp@1.0.9
│ ├─┬ http-signature@0.10.1
│ │ ├── asn1@0.1.11
│ │ ├── assert-plus@0.1.5
│ │ └── ctype@0.5.3
│ ├── isstream@0.1.2
│ ├── json-stringify-safe@5.0.1
│ ├─┬ mime-types@2.0.13
│ │ └── mime-db@1.11.0
│ ├── node-uuid@1.4.3
│ ├── oauth-sign@0.6.0
│ ├── qs@2.3.3
│ ├── stringstream@0.0.4
│ ├── tough-cookie@1.2.0
│ └── tunnel-agent@0.4.0
└── underscore@1.8.3

使用 DDP Client 訪问 Meteor

下面的參考实现展示了怎样用 DDP Client 与 Meteor 交互。

var DDPClient = require("ddp"),
_ = require('underscore'); var ddpclient = new DDPClient({
// url: 'ws://192.168.199.240:3000/websocket'
url: 'ws://mcotton-01.chinacloudapp.cn/websocket'
}); var useremail = "iasc@163.com";
var pwd = "123456"; var user_id = null, token = null; var appkit_weather_station, myappkit_weather_station, my_app_kit_id;
var data_observer, control_observer; /*
* Connect to the Meteor Server
*/
ddpclient.connect(function (error, wasReconnect) {
// If autoReconnect is true, this callback will be invoked each time
// a server connection is re-established if (error) {
console.log("DDP connection error!");
return;
} if (wasReconnect) {
console.log("Reestablishment of a connection.");
} console.log("connected!"); ddpclient.call("login", [
{user: {email: useremail}, password: pwd}
], function (err, result) {
console.log(result);
user_id = result.id;
token = result.token; if (token) {
console.log("Logined!", user_id, token); //var observer = ddpclient.observe("appkits"); /*
* Subscribe to a Meteor Collection
*/
ddpclient.subscribe(
"appkits", // name of Meteor Publish function to subscribe to
[], // any parameters used by the Publish function
function () { // callback when the subscription is complete
console.log("appkits all ==> ", ddpclient.collections.appkits); appkit_weather_station = _(ddpclient.collections.appkits).findWhere({name: 'Weather Station'});
console.log("appkits weather_station ==> ", appkit_weather_station);
console.log("appkits weather_station id ==> ", appkit_weather_station._id); // Create myAppKit var myAppKit = ddpclient.call(
'myAppKitInsert',
[{
name: 'My Weather Station',
app_kit_id: appkit_weather_station._id
}],
function (err, result) {
console.log('myAppKitInsert, error: ' + error);
console.log('myAppKitInsert, result: ' + result._id); my_app_kit_id = result._id; /*
* Subscribe to a Meteor Collection
*/
ddpclient.subscribe(
"myappkits", // name of Meteor Publish function to subscribe to
[user_id], // any parameters used by the Publish function
function () { // callback when the subscription is complete
console.log("myappkits all ==> ", ddpclient.collections.myappkits); console.log("appkit_weather_station id ==> ", appkit_weather_station._id); myappkit_weather_station = _(ddpclient.collections.myappkits).filter({_id: my_app_kit_id});
console.log("myappkits weather_station ==> ", myappkit_weather_station);
}
); ddpclient.subscribe(
"dataevents", // name of Meteor Publish function to subscribe to
[user_id], // any parameters used by the Publish function
function () { // callback when the subscription is complete
console.log("dataevents all ==> ", ddpclient.collections.dataevents);
}
); ddpclient.subscribe(
"controlevents", // name of Meteor Publish function to subscribe to
[user_id], // any parameters used by the Publish function
function () { // callback when the subscription is complete
console.log("controlevents all ==> ", ddpclient.collections.controlevents);
}
); /*
* observe DataEvents
*/
data_observer = ddpclient.observe("dataevents"); data_observer.added = function (id) {
console.log("[ADDED] to " + data_observer.name + ": " + id); var event = _(ddpclient.collections.dataevents).findWhere({_id: id});
console.log("[ADDED] dataevents ", event)
}; /*
* observe ControlEvents
*/
control_observer = ddpclient.observe("controlevents"); control_observer.added = function (id) {
console.log("[ADDED] to " + control_observer.name + ": " + id); var event = _(ddpclient.collections.controlevents).findWhere({_id: id});
console.log("[ADDED] controlevents ", event)
}; /*
* Send new Control Event to Server
* */
var newControlEvent = ddpclient.call(
'controlEventInsert',
[{
my_app_kit_id: my_app_kit_id,
control_name: "Status",
control_value: "true"
}],
function (err, result) {
console.log('controlEventInsert, error: ' + error);
console.log('controlEventInsert, result: ' + result._id);
});
}
);
}
);
}
}); ////Debug information
//
//ddpclient.on('message', function (msg) {
// console.log("ddp message: " + msg);
//}); /*
ddpclient.on('socket-close', function (code, message) {
console.log("Close: %s %s", code, message);
}); ddpclient.on('socket-error', function (error) {
console.log("Error: %j", error);
});
*/ // close setTimeout(function () {
// observer.stop();
ddpclient.close();
}, 5000); });

代码地址

https://github.com/iascchen/arduino_study/tree/master/src/yun_ddp


转载请注明出处

Author : iascchen(at)gmail(dot)com

Date : 2015-6-3

Github : https://github.com/iascchen/arduino_study

新浪微博 : @问天鼓


Use Node.js DDP Client on Arduino Yun to Access Meteor Server的更多相关文章

  1. 《深入浅出Node.js》第7章 网络编程

    @by Ruth92(转载请注明出处) 第7章 网络编程 Node 只需要几行代码即可构建服务器,无需额外的容器. Node 提供了以下4个模块(适用于服务器端和客户端): net -> TCP ...

  2. Node.js Web 开发框架大全《中间件篇》

    这篇文章与大家分享优秀的 Node.js 中间件模块.Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用程序,编写能够处 ...

  3. TCP Socket Programming in Node.js

    TCP Socket Programming in Node.js Posted on October 26th, 2011 under Node.jsTags: Client, node.js, S ...

  4. Node.js 给前端带来了什么

    在软件开发领域,前端工程师曾经是一个比较纠结的职业.在Web技术真正发展起来之前的相当长一段时间里,由于技术门槛很低,前端工程师行业一直是鱼龙混杂的状态.其中很多号称是Web开发者的人实际上并没有什么 ...

  5. Node.js模块

    每一个Node.js都是一个Node.js模块,包括JavaScript文件(.js).JSON文本文件(.json)和二进制模块文件(.node). mymodul.js function Hell ...

  6. node.js 基础学习笔记3 -http

    http模块,其中封装了一个高效的HTTP服务器和一个建议的HTTP客户端 http.server是一个基于事件的HTTP服务器 http.request则是一个HTTP客户端工具,用户向服务器发送请 ...

  7. Node.js学习笔记(一)基础介绍

    什么是Node.js 官网介绍: Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js us ...

  8. Node.js 基础介绍

    什么是Node.js 官网介绍: Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js us ...

  9. 忽略node.js服务中favicon.icon的请求

    场景 一个最简单的node.js的http服务 const http = require('http'); const server = http.createServer(function(req, ...

随机推荐

  1. 利用相关的Aware接口

    Struts 2提供了Aware接口.Aware为"感知"的意思,实现了相关Aware接口的Action能够感知相应的资源.Struts在实例化一个Action实例时,如果发现它实 ...

  2. HDOJ 1253 胜利大逃亡(bfs)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1253 思路分析:因为问题需要寻找到达终点的最短的距离(最短的步数),即在状态转换图上需要找出层次最浅的 ...

  3. CSS+DIV标签命名规范 搜索引擎最喜欢

    搜索引擎优化(seo)有很多工作要做,其中对代码的优化是一个很关键的步骤.为了更加符合SEO的规范,下面是目前流行的CSS+DIV的命名规则: 登录条:loginBar  标志:logo  侧栏:si ...

  4. 飘逸的python - 一个最简单的服务器

    python拥有这种单独起一个服务器监听端口的能力,用标准库的wsgiref就行. from wsgiref.simple_server import make_server def simple_a ...

  5. jz2440不能成功地启动文件系统, Failed to execute /linuxrc.

    文件系统加载失败,错误信息提示:    VFS: Mounted root (nfs filesystem).    Freeing init memory: 140K    Failed to ex ...

  6. Oracle数据库的安装详解

    1.写在安装前的话 可能有很多的菜鸟十分害怕大型软件的安装,因为安装过程中的一些错误很让他们头疼.下面我就写一个教程,希望能对大家有帮助,在安装ORACLE之前给大家一点点的意见: (1)尽量要安装L ...

  7. unity之uv贴图画圆弧,圆弧面,不规则图形

    由于最近一直没有时间,所以这篇博客一直没发,下面我说说uv画圆弧,圆面,不规则面拼接. 先来两张效果图 图截的不咋滴,凑合着看吧,画圆弧主要用的贝塞尔曲线画的,我感觉这个比较简单,当然大家也可以使用圆 ...

  8. C# 常用参数

    主函数调用 public static void Fun_Param() { ; ; ChangeValue(x, y); //外部调用Ref函数,必须初始化变量 ChangeValue(ref x, ...

  9. centos主机建立ssh互信

    ssh-keygen 生成密钥 1.ssh-keygen -t rsa 可以加密和签名 rsa 只能加密不能签名 2.ssh-copy-id -i /root/.ssh/id_rsa.pub USER ...

  10. apache加载php模块失败

    LoadModule php5_module "G:/php54/php5apache2_2.dll" apache2 conf加入这个之后无法加载 解决办法 在这句之前加入PHP ...