今はOpenFeintやGoogleAppEngineを使っています。
GoogleAppEngineでも独自機能を作ることはできるのですが、最近node.jsをよく聞くので試してみようと思います。
まずはnode.jsについてまったく知らないので探してみました。
サーバサイドJavaScriptの本命「Node.js」の基礎知識
http://www.atmarkit.co.jp/fwcr/rensai2/nodejs01/01.html
なるほど。使ってみたい。
ということで、ざっとした流れ。
(1) ローカル環境でnode.jsを動かす ← 今回はこれ
(2) さくらVPSでnode.jsを動かす
(3) AndroidアプリとさくらVPSのnode.jsを連携させる
===========================================================================
(1) Windows端末にnode.jsをインストールする
以下のサイトを参考にnode.jsをインストール。
目的はnode.jsだけなので、Socket.IOはインストールしませんでした。簡単!
Windows+Node.js+Socket.IO
http://www.koikikukan.com/archives/2012/01/10-015555.php
これはまだコマンドラインだけで確認できる状態です。
今後のことを考えてWebページに表示したいなぁということで、
良さげなサイトがありました。
node.jsとMySQLで割と普通のデータベースウェブアプリを作ってみるチュートリアル
http://sakuratan.biz/archives/3101
(2) モジュールのインストール
(1)でnode.jsをインストールしたときにnpmも一緒にインストールされていました。
なので、node.jsをインストールしたディレクトリで以下のコマンドを実行して、
参考サイトに書いてある必要なモジュールをインストールしました。
ディレクトリ
C:\Program Files (x86)\nodejs
コマンド
npm install mysql
npm install express
npm install ejs
いざ開発!の前に、MySQLをインストールしてデータベースとテーブルを用意する必要があります。
(3) MySQLのインストール
参考サイトではMySQLのインストールが割愛されていたので調べてみました。
MySQL バージョン 5.5 のダウンロードとインストールと設定 (Windows の場合)
http://www.kkaneko.com/rinkou/mysql/mysqlinstall.html
この手順のとおり進めてMySQLをインストールできました。
ネットって便利。
MySQLのリファレンスはこれを参考にしてます。
MySQLクイックリファレンス
http://www.bitscope.co.jp/tep/MySQL/quickMySQL.html
(4) データベースとテーブルを作成する
(3)でインストールした後、スタートメニューに「MySQL 5.5 Command Line Client」が追加されるので
それをクリックすると、ローカル環境でMySQLの操作ができるコマンドラインが現れます↓

ログインしたら、参考サイトにあるとおりにデータベースを作成します。
CREATE DATABASE nodejs_url_shortener;
データベースを切替えます。
use nodejs_url_shortener;
テーブルを作成します。
CREATE TABLE shorten_urls (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
long_url VARCHAR(256) UNIQUE NOT NULL COLLATE utf8_bin);
↓エラー
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
あれ?
原因はこれのようです↓
http://d.hatena.ne.jp/takihiro/20080306/1219295452
修正した↓
CREATE TABLE shorten_urls (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
long_url VARCHAR(255) UNIQUE NOT NULL COLLATE utf8_bin);
【参考】
データベースサーバー構築(MySQL)
http://fedorasrv.com/mysql.shtml
(5) テスト用ユーザーを作成する
今後のことを考えて、rootのまま操作するのは嫌だなぁということで、テスト用ユーザーを作りました。
MySQLのユーザー管理
http://linux.kororo.jp/cont/server/mysql_user.php
MySQLのコマンドラインで以下を実行。
GRANT ALL PRIVILEGES ON nodejs_url_shortener.*
TO 'test'@'localhost'
IDENTIFIED BY '[パスワード]';
ユーザー追加を確定。
FLUSH PRIVILEGES;
追加されたかを確認。
SELECT host,user,password FROM mysql.user;
+-----------+------+-------------------------------------------+
| host | user | password |
+-----------+------+-------------------------------------------+
| localhost | root | *XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| localhost | test | *XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | <-- 成功
+-----------+------+-------------------------------------------+
(6) node.jsとMySQLを連携させる
準備が整いました。
参考サイトの「MySQL との連動」から続けます。
現在でのディレクトリ構成↓
参考サイトのserver.jsは、現バージョンでは一部書き換える必要があります。
C:\Program Files (x86)\nodejs\base62.js
\nodejs\server.js
\nodejs\views\index.ejs
\views\layout.ejs
\views\result.ejs
require('sys'),
↓
require('util'),
express.bodyDecoder();
↓
express.bodyParser()
[node.js]MySQLからデータを取得(node-mysql v0.9.4)
http://d.hatena.ne.jp/mitsuto/20110921/p1
をもとに、↓の修正。
var client = new Client();
↓
var client = mysql.createClient();
この修正を行わないと、
Error: deprecated: connect() is now done automatically.
というエラーが出て、データベースへの接続がうまくいきません。
ということで、参考サイトのserver.jsを修正したバージョン↓
※[パスワード]部分は適宜書換えてください
-------------------------------------------------------------
// サーバのアドレスとポート
var HOSTNAME = 'localhost';
var PORT = 8124;
// MySQL データベース名、ユーザー名、パスワード
var DBNAME = 'nodejs_url_shortener';
var DBUSER = 'test';
var DBPASSWD = '[パスワード]';
var sys = require('util'),
express = require('express'),
ejs = require('ejs'),
Client = require('mysql').Client,
mysql = require('mysql'),
base62 = require('./base62');
var app = express.createServer();
app.use(express.bodyParser());
app.register('.ejs', ejs);
// ルート GET
app.get('/', function(req, res) {
res.render('index.ejs');
});
// ルート POST
app.post('/', function(req, res) {
// テンプレート変数
var locals = {
error: null,
short_url: null
};
// パラメータをチェック
if (!req.body.url) {
locals.error = 'Missing url parameter';
} else if (req.body.url > 255) {
locals.error = 'url parameter too long';
}
if (locals.error) {
res.render('result.ejs', {
locals: locals
});
return;
}
// idを短縮URLに変換して出力
function render_short_url(id) {
locals.short_url = 'http://' + HOSTNAME;
if (PORT != 80) {
locals.short_url += ':' + PORT;
}
locals.short_url += '/' + base62.int_to_base62_string(id);
res.render('result.ejs', {
locals: locals
});
}
// データベースに短縮URLを登録して表示
var client = mysql.createClient({
database: DBNAME,
user: DBUSER,
password: DBPASSWD
});
client.query(
'INSERT INTO shorten_urls (long_url) VALUES (?)',
[req.body.url],
function(err, results) {
// キー重複は無視
if (err && err.number != Client.ERROR_DUP_ENTRY) {
client.end();
throw err;
}
// インサート成功
if (!err) {
render_short_url(results.insertId);
return;
}
// インサート失敗時はlong_urlをキーで検索する
client.query(
'SELECT id FROM shorten_urls WHERE long_url = ?',
[req.body.url],
function(err, results, fields) {
if (err) {
client.end();
throw err;
}
if (results.length == 0) {
client.end();
throw new Error('Something wrong');
}
client.end();
render_short_url(results[0].id);
}
);
}
);
});
// 短縮URLをリダイレクト
app.get(/^\/([0-9A-Z]{5,})$/, function(req, res) {
// 修正箇所
var client = mysql.createClient({
database: DBNAME,
user: DBUSER,
password: DBPASSWD
});
// idからurlを検索してリダイレクト
client.query(
'SELECT long_url FROM shorten_urls WHERE id = ?',
[base62.base62_string_to_int(req.params[0])],
function(err, results, fields) {
if (err) {
client.end();
throw err;
}
client.end();
if (results.length == 0) {
// データが無い
res.send('Not Found', 404);
} else {
res.redirect(results[0].long_url);
}
}
);
});
app.listen(PORT, HOSTNAME);
-------------------------------------------------------------
(7) 動作確認
起動。
C:\Program Files (x86)\nodejs\node server.js
ブラウザでアクセスして確認。
http://localhost:8124
参考サイトのとおりに動作したら成功です!