生成AIを活用したSaaSサービス提供企業

  • Company
    • Company
    • 会社概要
    • グループ会社
  • Service
  • Work
  • News
  • Recruit
  • Blog
  • Contact

ブログBlog

  • ALL

  • お知らせ

  • 技術/デザイン/制作

  • ベトナム

  • ごはん

  • 日常/プライベート

  • WebSocketでチャットアプリを作る(with Redis&Node.js) ~続き~

    どうも。営業部の伊藤です。

    先日のブログの続きです。
    Redisの準備が終わりましたので、次はWebSocketを利用するための環境を用意します。

    WebSocketを利用するため、今回はサーバー側のテクノロジーとしてNode.jsを利用する事になしました。
    Jettyなど他にも選択肢はあったのですが、参考文献が多いという理由でnodeにしました。

    では、nodeをインストールします。
    インストールには、nodeを導入するためのシェルスクリプトでインストールを簡略化してくれる「nave」(複数のバージョン管理も可能)やgit上にも様々なオープンソースがありますが、今回は複数バージョンを管理する必要もないため、普通にソースをダウンロードしてコンパイルする事にしました。
    バージョンはインストール当時(2012年9月頃)のstableだった0.8.6にしました。

    # cd /usr/local/src
    # wget http://nodejs.org/dist/v0.8.6/node-v0.8.6.tar.gz
    # tar xf node-v0.8.6.tar.gz
    # cd node-v0.8.6
    # ./configure
    # make install

    次にnode向けのパッケージマネージャであるnpm(Node Package Manager)をインストールします。
    npmで管理されているライブラリは以下URLをご覧ください。
    https://npmjs.org/
    nodeコマンドが利用できるかを確認後、以下を実行します。

    # node -v
    v0.8.6
    # curl http://npmjs.org/install.sh | sh

    対話モードを”yes”と答えていくとインストール完了です。
    これでnodeが利用できる状態であれば、npmコマンドも利用できるようになります。
    早速バージョンだけ確認してみます。

    # npm -v
    1.1.48

    次にパッケージをダウンロードするのですが、その前にnodeの動きを一度確認しておきます。
    王道のHello Worldを表示するため、nodeコンソールを開き以下スクリプトを実行します。

    # node
    > var http = require(“http”);
    > http.createServer(function(req, res){
    > res.writeHead(200, {“Content-Type”: “text/plain”});
    > res.end(“Hello World”);
    > }).listen(3000, “127.0.0.1”);

    ブラウザで上記URL(http://127.0.0.1:3000/)にアクセスすると、画面上に「Hello World」が表示されます。
    単純にテキストを表示するだけなのに、ヘッダーステータスコード200?、listen?
    普段はTomcatやApache(+CGI)といったコンテナ上でサーブレットやPHPでアプリケーションを構築する事が多いと思いますが、nodeの場合はアプリケーションだけでなく、上記サンプルのようにnode自体がコンテナとなります。
    その為、nodeで例外が発生するとサーバ機能ごとプロセスが終了してしまいますので、サーバ機能まで共倒れしないよう例外処理には気を付ける必要があります。
    ※nodeコンソール上で実行していますが、上記スクリプトをファイルに保存し(例えばtest.js)、nodeコマンドのパラメータとして実行する事も可能です。

    ではwebsocketを利用するため、幾つかのパッケージをnpmを利用してインストールします。

    1. Express
    Expressはnode用のWebフレームワークです。
    上述したようにnodeの場合はnode自身がコンテナの役割を果たす必要があるため、静的なファイルの配信についてもnode内で対応しなければなりません。この手間をWebアプリケーションフレームワークであるExpressを利用することで容易に解決できます。
    以下コマンドでパッケージをグローバルインストールします。
    ※グローバルインストールにしないとパスが通らないケースがあるため、以下コマンドでインストールすることをお勧めします。

    $ npm install -g express

    インストールディレクトリにあるapp.jsを実行します。

    $ node app.js

    http://127.0.0.1:3000/ にアクセスして「Welcome to Express」と表示されていればインストール完了です。

    2. Socket.IO
    Socket.IOは今回利用するWebSocketをブラウザの互換性を考慮せずに利用できる抽象化ライブラリです。
    WebSocketを利用できないブラウザではAjaxのロングポーリングを利用するなど、ブラウザ間の互換性を気にせずに開発が可能になります。
    以下コマンドでパッケージをインストールします。

    $ npm install socket.io

    これで一通りの準備が終わりましたので、次はスクリプトを用意します。
    publicディレクトリ内に移動し、chat.htmlファイルを作成します。

    <head>
    <script src=”/socket.io/socket.io.js”></script>
    <script src=”/javascripts/chat.js”></script>
    </head>
    <body>
    <input type=”text” id=”comment” placeholder=”入力してください” value=”” size=20 ></input>
    <button onclick=javascript:send() >送信</button>
    <p id=”list”></p>
    </body>

    次に、javascriptディレクトリに以下ファイル(chat.js)を作成します。
    クライアントサイドのJavaScriptです。

    var postList;
    window.onload=function(){
    postList = document.getElementById(“list”);
    }var listleft = function(){
    postList.innerHTML+=”<div align=’left’><img src=’/images/left.gif’>”+arguments[0]+”</div>”;
    }var listright = function(){
    postList.innerHTML+=”<div align=’right’>”+arguments[0]+”<img src=’/images/right.gif’></div>”;
    }

    var socket = io.connect(“http://127.0.0.1”, {port:3000});
    socket.on(“connect”, function() {
    listleft(“接続開始”); //接続した当人にだけ表示
    socket.emit(“msg send”, “皆さん宜しくお願いします。”);

    // 自分のコメントを表示
    socket.on(“msg mycommnet”, function(commnet){
    listleft(commnet);
    });

    // 他人のコメントを表示
    socket.on(“msg elsecommnet”, function(commnet){
    listright(commnet);
    });

    socket.on(“disconnect”, function(){
    listleft(“接続が切れました。”);
    });
    });

    function send(){
    var comment = document.getElementById(“comment”).value;
    socket.emit(“commnet send”, comment);
    }

    自分が投稿した内容は左側に表示し、自分以外の投稿は右側に表示するようにします。
    最後に先ほど動作確認したapp.jsの下段にsocketインスタンス作成処理を追記します。

    var express = require(“express”);
    var app = module.exports = express.createServer();app.configure(function(){
    app.set(“views”, __dirname + “/views”);
    app.set(“view engine”, “ejs”);
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser());
    app.use(express.session({ secret: “your secret here” }));
    app.use(app.router);
    app.use(express.static(__dirname + “/public”));
    });app.configure(“development”, function(){
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
    });

    app.configure(“production”, function(){
    app.use(express.errorHandler());
    });

    app.get(“/”, function(req, res){
    res.render(“index”, {
    title: “Express”
    });
    });

    app.listen(3000);
    console.log(“Express server listening on port %d in %s mode”, app.address().port, app.settings.env);

    //socketインスタンスを作成
    var io = require(“socket.io”).listen(app);
    io.sockets.on(“connection”, function(socket){
    socket.on(“commnet send”, function (commnet) {
    socket.emit(“msg mycommnet””, commnet); //自分自身に通知
    socket.broadcast.emit(“msg elsecommnet”, commnet); //自分以外で同一ソケットとハンドシェイク中の人にキャスト
    });
    socket.on(“disconnect”, function() {
    log(接続が切れました。”);
    });
    });

    スクリプトの準備が整いましたので、再度サーバーを起動します。

    $ node app.js

    その後、publicディレクトリ内に新規作成したchat.htmlにアクセスします。
    http://127.0.0.1:3000/chat.html

    まず始めに、アイコンがダサ過ぎる点については無視してください。。。
    クライアント側からハンドシェイク要求を送信し、サーバー側からハンドシェイクの応答があれば自身のブラウザだけに「接続開始」というメッセージが表示されます。
    その後、既に同一ソケットにアクセス中のユーザーに接続が確立した旨を伝えるため、「皆さん宜しくお願いします。」とうメッセージを発信(emit)します。
    上記画像の場合、左側のブラウザが先にアクセスしたブラウザで、右側のブラウザが後にアクセスしたブラウザです。
    右側のブラウザで接続後にコメントを送信すると、リアルアイムに左側のブラウザに投稿内容が反映されました。いい感じ♪
    例外処理、DBを利用した機能(過去データ取得など)などは未実装の状態ですが、一旦これでチャットWebアプリの基盤はできました。
    次はRedisを利用した過去データ取得、Publish/Subscribe型(Pub/Sub型)とnodeを連携した冗長化を進めていきます。
    こちらについては進展があればまたブログに投稿させていただきます。

    それでは。

    このエントリーをはてなブックマークに追加
    Share on Tumblr
    Tweet

    伊藤 康平投稿者 伊藤 康平

    投稿日: 2012/10/292012/11/13

    カテゴリー 技術 / デザイン / 制作
  • CS6でCreateJS

    こんにちは守谷です。

    遅ばせながらFlash CS6の拡張機能である「Toolkit for CreateJS」を試してみました。

    CS6でCreateJSのテスト
    ※なぜかiframeが使えない

    「Toolkit for CreateJS」を使えばFlashのGUIで手軽にCreateJSのコードが書けちゃいます。アクションウィンドウにはActionScriptではなくJavascript(CreateJSのメソッド)を書くというなんとも面白い作り方ですが、用意されているメソッドもgotoAndPlayだったりしてFLASHを触った事がある人ならいつもの感覚で作る事ができます。

    細かい検証に関しては、まだ中途半端というのと、もう色々な人が紹介されてますのでそちらを御覧いただければ!

    こいつでブラウザベースのスマホゲームを作ったら面白そうですね。いつかは挑戦してみたいと思います。

    このエントリーをはてなブックマークに追加
    Share on Tumblr
    Tweet

    アバター投稿者 staff

    投稿日: 2012/10/292012/11/13

    カテゴリー 技術 / デザイン / 制作
  • ブースト系アプリ

    最近ブースト系アプリの相談を受けること、耳にすることが多い。
    ブースト系アプリとは懸賞系のアプリなどで自社アプリなのどの順位を上げる為のものになる。
    アプリのプロモーションにはとても効果があるようだ。
    自分はまめじゃないので、懸賞アプリはあまり興味がないが、何もしなくても1日数十円単位のお金が貰えたり大きなインセンティブがあるので、食いつきは良いはずだ。
    但し、ステマ扱いされたりレビューに酷いことが書かれりするので、リリースの仕方には注意が必要と思う。本体のアプリに悪影響がでれば本末転倒である。
    しかし懸賞系アプリ自体がすぐにランキング上位に行くので、上手くやれば効果は絶大なはずだ。

    このエントリーをはてなブックマークに追加
    Share on Tumblr
    Tweet

    山下 祐典投稿者 山下 祐典

    投稿日: 2012/10/242012/11/13

    カテゴリー 技術 / デザイン / 制作
  • WebSocketでチャットアプリを作る with Redis&Node.js

    どうも。営業部の伊藤です。

    もともとHTML5の仕様の一部として策定が進められていたWebSocketについて勉強するため、Node.jsを利用して簡単なチャットアプリを作ってみました。(目指せブラウザ版LINE!)

    今回はデータベースとしてRedisを採用しましたので、まずはRedisのインストールとコマンドラインを使った簡単な動作確認までを書きます。

    まず、Redisをインストールします。
    yumでもインストールはできますが、最新をインストールするため、ソースからインストールします。
    ※2012年9月頃

    # wget http://redis.googlecode.com/files/redis-2.4.16.tar.gz
    # tar zxvf redis-2.4.16.tar.gz
    # cd redis-2.4.16
    # make
    # make install

    あっという間です。
    RedisはANSI-Cで実装されているため、インストール時に依存ライブラリなどのインストールが不要です。
    よって、コンパイルは上記ステップで完了となります。

    既知の情報だと思いますが、念のため。
    Redisはインメモリベースの
    KVSです。
    KVSはRDB(リレーショナルデータベース)のJOINのように複雑、且つ高負荷なSQLは発行せず、高速化/拡張性に趣をおいたNoSQLのデータベース管理システムとなります。
    いわゆる分散型データ保管技術の1つです。
    同様のデータベースにはGoogle検索で採用されているBigtable(ビッグテーブル)、Amazonで採用されているDynamo(ダイナモ)、有名どころだとmemcachedなど様々な種類があります。
    また、RDBのような複雑なシステムではないため、サービス(mixi、Amazonなど)や大学の研究で独自のKVSが開発/採用されているケースも多々あります。

    そんなKVSですが、KVSごとの特徴は?ということで、今回選定したRedisの特徴をいくつか記載します。
    1. 永続化機構
    通常メモリ上でデータを管理しているため、memcachedのように障害時、再起動時にはデータを喪失してしまいますが、Redisは定期的にデータのスナップショットをダンプファイルにし、再起動時にこのファイルをメモリに読み込むことでデータを復元する仕組みを備えています。
    定期的という事で不安を抱く方も多いと思いますが、”Append Only File”という仕組みを利用することで全ての更新コマンドを管理しておき、再起動時にこのコマンドを読み込むという方法もあります。これであればデータの喪失は最小限に食い止めれます。
    注意すべきなのは、永続化機構といってもあくまでもインメモリベースのため、最大容量はRAMに依存します。
    RAM容量より多くのデータを保存したい場合はスワップファイルを利用し、一部のデータをHDDに退避させる必要があります。(RedisVM)

    2. 豊富なデータ型とコマンド
    Redisはハッシュ(HASH)以外の型もサポートしており、リスト型(LIST)、集合型(SET)、順序付き集合型(SORTED SET)などのデータ構造が扱えます。
    また、コマンドが非常に豊富、且つアトミックに操作が可能なため、CAS操作などトランザクションを考慮した処理が不要です。
    ただし注意すべき点として、アトミック実行(MULTI/EXEC)は一般的なトランザクションとして実行されている訳ではないため、実行中にエラーが発生した場合にROOLLBACKはされません。残りの処理も実行されます…ここは要注意です!
    (値を設定&取得くらいのアトミック操作であれば”GETSET”という1つのコマンドで対応可能)
    KVSの利用用途としてはデータの整合性よりもスピード重視の利用用途が多いと思いますので、トランザクションを考慮する機会は少ないと思いますが、アトミックに操作が可能な事でデータ管理方法の幅が広がります。

    3. レプリケーション
    Redisはマスター/スレーブのレプリケーションが設定ができ、スケールアウトが非常に容易です。
    設定は簡単で、スレーブ側の設定ファイルに以下項目を追加するだけです。

    # cp redis.conf redis_slave.conf
    # vi redis_slave.conf
    …
    # port 7000 <= スレーブはポート7000番で稼働
    # slaveof localhost 6379 <= slaveofにマスターのホスト名とポート番号を指定
    …
    # redis-server redis_slave.conf

    設定できているか否かの確認はinfoコマンドを実行するか、実際に値を設定して確認します。
    infoコマンドの場合、実行後に「role」を確認してください。

    # redis-cli -p 6379 -h localhost <= マスターに接続
    redis 127.0.0.1:6379>info
    …
    role:master
    …

    役割がマスターになっていますね。次にスレーブに接続します。

    # redis-cli -p 7000 -h localhost <= スレーブに接続
    redis 127.0.0.1:7000>info
    …
    role:slave
    …

    役割がスレーブになっていますね。無事設定できているようです。

    最後に、実際にレプリケーションできているかを確認するため、マスターにデータを登録し、その後スレーブでデータを取得してみます。

    # redis-cli -p 6379 -h localhost
    redis localhost:6379> set test “test-data”
    OK
    redis localhost:6379> get test
    “test-data”
    redis localhost:6379>exit# redis-cli -p 7000 -h localhost
    redis localhost:7000> get test
    “test-data”
    redis localhost:7000>

    問題なさそうです。

    4. Publish/Subscribe型(Pub/Sub型)の通信をサポート
    今回DBにRedisを採用したのはこの「Pub/Sub型通信」をRedisがサポートしているためです。
    送信側と受信側がトピックを介して”多対多”で通信できるモデルのため、Redisを中継サーバとしてWebSocketサーバを冗長化する事ができます。
    Node.jsについて説明できていないため順番が前後しますが、Nodeを利用してPub/Sub通信の動きを確認してみます。

    nodeのコンソールを起動し、以下スクリプトを実行します。

    # node
    > var sys = require(“sys”);
    > var redis = require(“redis”);> var subscriber = redis.createClient(6379, “localhost”);
    > subscriber.subscribe(“I am subscriber”);
    > subscriber.on(“message”, function(channel, message){
    > sys.puts(channel + “に「” + message + “」というメッセージが送信されたようです。”);
    > });

    > var publisher = redis.createClient(6379, “localhost”); //publisherは敢えて作る必要ないです。var subscriberを使って問題無いですが、分かりやすくするため!
    > publisher.publish(“I am subscriber”, “I am publisher”);

    6379番ポートのredisの「I am subscriber」というトピックに対して配信を申し込み(subscribe)、配信があればコンソール上に受信内容を出力するようにします。
    その後、6379番ポートのredisの「I am subscriber」というトピックに対して”I am publisher”というメッセージを配信します。

    上記スクリプトを実行すると、以下メッセージが表示されます。

    > I am subscriberに「I am publisher」というメッセージが送信されたようです。

    Pub/Sub通信のイメージ湧きましたでしょうか?
    分かり辛いですね…なんというか…自作自演ってな感じですね。

    という事で、上記コンソールはそのままにしておき、別コンソールを起動して以下コマンドを実行してみます。

    # redis-cli -p 6379 -h localhost
    redis localhost:6379> publish “I am subscriber” “I am publisher”

    するとnodeコンソール上に先ほどと同様に以下メッセージが表示されます。

    > I am subscriberに「I am publisher」というメッセージが送信されたようです。

    これこそがPub/Sub型の配信モデルです。
    node側ではトピック「I am subscriber」を購読(subscribe)状態のため、
    別イベントで「I am subscriber」にメッセージが登録されたと同時にメッセージをお知らせしてもらっています。

    今回は受信/購読者(Subscriber)、発行/公表者(Publisher)共に単一で確認しましたが、前述したように多対多の通信モデルのため、複数のSubscriber、またはPublisherでも上記通信が可能となります。
    WebSocketサーバーを冗長化した際に各々のサーバーでsubscribeしておき、連携したいデータをpublishすればサーバー間連系はこの中継サーバーに委ねられます。
    単一であればWebSocketでブロードキャストすればいいだけですが、冗長化を考えるとPub/Sub型を利用できるredisは非常に便利です。
    エンドポイントはWebSocketで管理しているため、サーバー間はPub/Sub型じゃなくてTriggerでもいいんじゃない?という方も居ると思いますが、サービス独自の特殊な通信制御が必要でない限りはPub/Sub型通信モデルの方が便利だと思います。

    Redisの準備は一旦ここまでとし、次はNodeの準備を進めます。
    少し長くなってしまったため、Nodeと各種ライブラリ(Socket.IOやExpressなど)のインストールについては
    次回ブログで投稿させていただきます。

    このエントリーをはてなブックマークに追加
    Share on Tumblr
    Tweet

    伊藤 康平投稿者 伊藤 康平

    投稿日: 2012/10/182012/11/13

    カテゴリー 技術 / デザイン / 制作
  • 究極のUX

    UXとかUIとか大好き竹内です。こんにちは。
    究極のUXって多数決でしかない様な気がするのは気のせいですかね。

    元々は何用語なんでしょうか?詳しいことはわかりませんが、WEB界隈ではかなり頻繁にこの言葉を目にしたり聞いたりする様になりました。
    仕事柄、WEBサイトのUIや、サービスフローや動きに関するUXなどにはいつも「なんで?」「どうして?」と疑問を抱きながら接するようにしています。

    もちろんそれはPCやスマートフォンの画面の中だけではないです。
    「どうしてここは引き戸なんだろう?」「どうして左が登りで右が下りなんだろう?」「手すりがここで終わってるのは何でなんだろう?」「こっちにもあれば便利なのにな」「どっちがどっちかわからないよ」「なんで何も書いてないの?」「一見お洒落なだけで使いにくいね」・・・などなど、それがUXとかUIとかいう言葉で括られる物とは特に意識しなくても生活していれば色々と感じるものです。

    そんな中、先日、ちょっと「おやっ?」と思う蛇口に出会いました。
    皆さんは蛇口は「ひねる(まわす)もの」という感覚が強いですよね?
    もちろん他にも上下に上げ下げするものや、自動で出るものなどもありますが、多くの人が蛇口と言えば「ひねる(まわす)」と思うのではないでしょうか。
    ではそんな決め付けの文章を書いた後ですが、皆さんは
    こんな水道を見たらどうしますか?
    自分だったら上にあげます。
    こんな水道だったらどうでしょう?もう「ひねる(まわす)」と思う人は少ないと思います。
    では、この白い部分が蛇口の両サイドに付いていたらどうでしょうか?
    (今、写真を撮ってこなかったを猛烈に後悔しています)
    いかにも「上にあげる」と思われる形のものが蛇口の両サイドにある場合、人は慣習的に「ひねる」のか「あげる」のか?

    ちなみにその蛇口は「ひねる」のが正解でした。
    何度かその洗面台を使ったのですが、自分は無意識に「あげる」操作をしようとしていて少しイラついたのを覚えています。

    蛇口だとそれほど違和感のあるものへの遭遇機会は少ないと思いますが、ドアの取っ手(ドアノブ)などであれば遭遇機会はそこそこあるのではないかと思います。
    「まわす」のか「下におろす」のか、「押す」のか「引く」のか「横にスライドさせる」のかなどなど。
    横へスライドして開けるドアにまるいドアノブが付いている所を想像してもらえればかなりの違和感を想像できるのではないでしょうか。
    上の蛇口については全然伝わらなかったと思いますが、このドアの例と同じくらいの違和感でした。

    実生活での体感も、画面の中での体感もそれほど大きくは変わらないはずですので、ユーザに不便や違和感や気持ち悪さを感じさせないものづくりをして行けたらなと思いました。

    このエントリーをはてなブックマークに追加
    Share on Tumblr
    Tweet

    アバター投稿者 staff

    投稿日: 2012/10/172012/11/13

    カテゴリー 技術 / デザイン / 制作
  • RoRと格闘中

    お疲れ様です。横井です。

    現在、案件と案件の谷間におりまして、ちょっと時間に余裕ができましたので、
    普段できないことをやろうと思い、Ruby on RailsをMy PC(Windows7上)にインストールしていろいろ触っているとろこになります。

    最近、Rubyの本を読みだしたこともあり、非常に気になっていたので、ちょうど良いタイミングと思い、始めてみました。
    がしかし、環境を構築するだけでもなかなかどうしての状態で思うように進んでいない状態です。

    まず、はまったところは、RMagick(ImageMagickをRubyで扱えるようにした関数)のインストールのところです。
    最新の環境(Ruby1.9.2 + rails3.2.8)でRMagickをインストールしようとしましたが、どうしても途中でアボートしてしまって、インストールできませんでした。
    (Google先生に聞くとインストールできた方を紹介してくれましたので、マネをしてみましたが、無残な結果となりました。結局、Rubyのバージョンを1.8系に入れ直して、無事インストールできました。)

    現在は、FacebookのOAuth認証をやってみようとがんばっておりますが、エラーの嵐から抜けられないくなっております。

    RoRはフレームワークと言うより、ミドルウェアに近い感覚で、扱いに慣れていないと設定している時間をかなり取られそうだなという感じです。

    しばらくは戦いから抜け出せないと思いますが、戦いから抜けだせるレベルになったら、案件でも使ってみたいと思っております。

    ではでは。

    このエントリーをはてなブックマークに追加
    Share on Tumblr
    Tweet

    アバター投稿者 staff

    投稿日: 2012/09/252024/04/26

    カテゴリー 技術 / デザイン / 制作

投稿ナビゲーション

前のページ ページ 1 … ページ 42 ページ 43 ページ 44 … ページ 48 次のページ