2018年3月24日 星期六

Node.js 讀取儲存在 Redis 的 PHP Sesion 資料

[Node.js 安裝 php-unserialize 模組]
php-unserialize 可以反序列化 PHP serialize() 後的資料=>使用 unserialize(string)
也可以解析 PHP 儲存的 seesion 資料(例如儲存在 Redis 的Sessoin) =>使用 unserializeSession(string)
$ npm install php-unserialize --save

[Node.js 讀取儲存在 Redis 的 PHP Session 範例]
"use strict";

//redis 連線設定
const REDIS_HOST = "127.0.0.1";
const REDIS_PORT = 6379;
const REDIS_OPTS = {};
const REDIS_PASS = "密碼";

let redis = require('redis');
let redis_client = redis.createClient(REDIS_PORT, REDIS_HOST, REDIS_OPTS);
redis_client.on("error", function (err) {
    console.log("Error:" + err);
});
redis_client.auth(REDIS_PASS);//密碼驗證


var PHPUnserialize = require('php-unserialize');
let php_sess_key = "PHP Session儲存在Redis的Key";//例如PHPREDIS_SESSION:n47g4vh1qt2pltplkd3lhifes2
//讀取資料後,利用 callback function 處理取得資料
redis_client.get(php_sess_key, function (err, results) {
    if (null !== err) {
        try {
            //使用 unserializeSession 解析 session 資料
            let sess = PHPUnserialize.unserializeSession(results);
            console.log(sess);
            console.log(sess.user.u_id);
        } catch (err) {
            //錯誤處理.....
        }
    }
});


參考:
GitHub - naholyr/js-php-unserialize: JavaScript tool to unserialize data taken from PHP. It can parse "serialize()" output, or even serialized sessions data.

Node.js 使用 Redis

[安裝 Redis]
$ npm install redis --save
也可以再安裝hiredis
$ npm install hiredis --save
說明:
1.hiredis 是非阻塞的,且速度較快
2.沒裝 hiredis 時,會用純的 javascript parser,有裝 hiredis 時,則會使用 hiredis parser


安裝 hiredis 時,若出現「make: cc: Command not found」錯誤
表示系統沒有安裝 gcc,所以編譯失敗。
安裝 gcc
$ yum install gcc
若出現「make: g++: Command not found」錯誤。
安裝 gcc-c++
$ yum install gcc-c++


[Node.js 存取 Redis 快取資料]
"use strict";

//redis 連線設定
const REDIS_HOST = "127.0.0.1";
const REDIS_PORT = 6379;
const REDIS_OPTS = {};
const REDIS_PASS = "密碼";

let redis = require('redis');
let redis_client = redis.createClient(REDIS_PORT, REDIS_HOST, REDIS_OPTS);
redis_client.on("error", function (err) {
    console.log("Error:" + err);
});
redis_client.auth(REDIS_PASS);//密碼驗證

//設定、讀取資料後,從 redis.print 查看執行結果
redis_client.set("aa", "test", redis.print);//設定key aa 的資料為 test
redis_client.get("aa", redis.print);//取得key aa 的資料

//讀取資料後,利用 callback function 處理取得的資料
redis_client.get("aa", function (err, results) {
    console.log(err);//沒錯誤,會是 null
    console.log(results);//取得的資料
    //....後續處理....
});
//關閉連線(如同送出 quit 指令)
client.quit();
//強制關閉連線(不等所有回應都解析完畢)
client.end(flush);//flush=>true|false 若設為 false,則運行中的指令都會默默失敗



參考:
GitHub - NodeRedis/node_redis: redis client for node
Node Redis
发现node.js 的redis模块更新了。支持hiredis 了 - CNode技术社区
Nodejs学习笔记(九)--- 与Redis的交互(mranney/node_redis)入门 - porschev - 博客园
Using Redis with Node.js
《Redis入門指南》一5.4 Node.js與Redis - ITW01



在 CentOS7 上,Node.js 使用 npm 安裝模組出現錯誤

出現以下錯誤訊息
npm: relocation error: npm: symbol SSL_set_cert_cb, version libssl.so.10 not defined in file libssl.so.10 with link time reference

查詢目前 openssl 版本
$ openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013
更新 openssl
$ yum update openssl
更新 openssl 後,即可正常安裝
$ openssl version
OpenSSL 1.0.2k-fips  26 Jan 2017



參考:
https://stackoverflow.com/a/46476879

CentOS 安裝 Node.js

[新增 NodeSource repository]
到 Node.js 官網查看安裝說明。(若使用 epel repo 安裝,可能是很舊的版本)
https://nodejs.org/en/download/package-manager/#enterprise-linux-and-fedora
可知 NodeSource repository 有提供 Node.js
按照說明安裝 NodeSource repos (有奇數版、偶數版,一班使用偶數版)
$ curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
查看系統 repo,可發現已新增 NodeSource repository
$ yum repolist all
....
nodesource/x86_64  Node.js Packages for Enterprise Linux 7 - x86_64  enabled: 74
nodesource-source  Node.js for Enterprise Linux 7 - x86_64 - Source  disabled
....


[Node.js 安裝、指令]
安裝 Node.js 套件
$ yum install nodejs
查看 node.js 版本
$ node -v
v8.10.0
執行 JavaScript 文件。aa.js 內容為 console.log("test")
$ node aa.js
test
也可不輸入附檔名
$ node aa
test
直接執行 JavaScript
$ node -e 'console.log("test")'
test
若只輸入 node,則會進入 REPL(Read-Eval-Print Loop) 環境
$ node
> xyz
ReferenceError: xyz is not defined
> var xyz=6
undefined
> xyz
6
> _+10
16
> xyz
6
> .exit
使用嚴格模式進入 REPL 環境
$ node --use_strict
使用嚴格模式執行 JavsScript 文件
$ node --use_strict aa.js


[npm 指令]
安裝 Node.js 時,也會安裝npm(Node Package Manager)
查看 npm 版本
$ npm -v
5.6.0
查看 npm 設定
$ npm config ls -l
在專案資料夾產生 npm 使用的 package.json 文件(https://docs.npmjs.com/files/package.json)
package.json 會紀錄專案相關資訊,以及安裝的套件版本、相依性...
$ npm init
安裝 package.json 文件內的相依套件(佈署到新環境時,上傳 package.json 即可安裝)
$ npm install
查看 package 資訊
$ npm info [package_name]
$ npm info [package_name] description
$ npm info [package_name] version
搜尋相關 package
$ npm search <關鍵字(可用正規表示式)>
查看目前目錄安裝的 package
$ npm ls
查看全域安裝的 package
$ npm ls -global
列出目前目錄安裝的特定package
$ npm ls [package_name] 
在目前目錄安裝 package (加 -save 會將 package 相依性、版本寫在 package.json 文件)
$ npm install [package_name] --save
安裝 package(全域)
$npm install [package_name] -g
安裝指定版本的 package(可用來強制安裝較舊的版本)
$ npm install package_name@latest
$ npm install package_name@0.3.6
升級 package
$ npm update [package_name] --save
移除 package
$ npm uninstall [package_name] --save
通常 npm 版本更新的比 node.js 頻繁,可用以下指令更新 npm 到最新版
$ npm install npm@latest -g


[Node.js 全域物件]
console:https://nodejs.org/api/globals.html#globals_console
exports:https://nodejs.org/api/globals.html#globals_exports
module:https://nodejs.org/api/globals.html#globals_module
process:https://nodejs.org/api/globals.html#globals_process


[Node.js 全域函式]
Class: Buffer:https://nodejs.org/api/globals.html#globals_class_buffer
clearImmediate(immediateObject):https://nodejs.org/api/globals.html#globals_clearimmediate_immediateobject
clearInterval(intervalObject):https://nodejs.org/api/globals.html#globals_clearinterval_intervalobject
clearTimeout(timeoutObject):https://nodejs.org/api/globals.html#globals_cleartimeout_timeoutobject
setImmediate(callback[, ...args]):https://nodejs.org/api/globals.html#globals_setimmediate_callback_args
setInterval(callback, delay[, ...args]):https://nodejs.org/api/globals.html#globals_setinterval_callback_delay_args
setTimeout(callback, delay[, ...args]):https://nodejs.org/api/globals.html#globals_settimeout_callback_delay_args


[Node.js 全域變數]
__dirname:https://nodejs.org/api/globals.html#globals_dirname
__filename:https://nodejs.org/api/globals.html#globals_filename
require():https://nodejs.org/api/globals.html#globals_require



參考:
Node.js 教程 | 菜鸟教程
05 - Working with package.json | npm Documentation
ls | npm Documentation
npm模块管理器 -- JavaScript 标准参考教程(alpha)
CommonJS规范 -- JavaScript 标准参考教程(alpha)
https://docs.npmjs.com/getting-started/installing-node#3-update-npm
Node.js 概述 -- JavaScript 标准参考教程(alpha)
Global Objects | Node.js v9.9.0 Documentation
Index | Node.js v8.10.0 Documentation


2018年3月21日 星期三

PHP 使用 Redis 儲存 Session

將 Session 儲存在 Redis、memcached 之類的快取,可以增加效能
也方便不同的應用程式共享 Session
其中 Redis 可以設密碼、memcached 不行
所以若須開放其他 Server 存取(監聽非 127.0.0.1 的 IP),Redis 可設定密碼增加安全性。
以下設定 PHP 使用 Resid 儲存 Session

安裝 php-pecl-redis:
yum install php-pecl-redis

修改 PHP 設定檔:
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?auth=密碼"
其中 session.save_path 的格式為
session.save_path = "tcp://host1:6379?weight=1, tcp://host2:6379?weight=2&timeout=2.5, tcp://host3:6379?weight=2&read_timeout=2.5"
可設定的參數有:weight、timeout、persistent、prefix(預設"PHPREDIS_SESSION:")、auth、database...


查看儲存在 Redis 的 PHP Session:
key 的格式預設為「PHPREDIS_SESSION:seesion id」
127.0.0.1:6379> keys PHP*
1) "PHPREDIS_SESSION:n47g4vh1qt2pltplkd3lhifes2"

查看 session 在 Redis 中剩多久失效:
若 PHP 的 session.gc_maxlifetime 設定為1440,則結果應該會得到一個小於等於 1440 的秒數
127.0.0.1:6379> ttl PHPREDIS_SESSION:n47g4vh1qt2pltplkd3lhifes2
(integer) 1433

在 PHP 執行 session_destroy() 後,Redis 中的 session 也會消失:
127.0.0.1:6379> ttl PHPREDIS_SESSION:n47g4vh1qt2pltplkd3lhifes2
(integer) -2
#-1表示沒設定過期時間
#-2表示key不存在


參考:
https://github.com/phpredis/phpredis#php-session-handler
PECL :: Package :: redi
https://github.com/phpredis/phpredis/#readme(說明文件)