LoginSignup
24
24

More than 5 years have passed since last update.

socket.io-php-emitterを使ってsocket.ioの外(簡易API)からemitしてみる

Last updated at Posted at 2015-03-19

何をするか

前回、socket.ioでサンプルチャットアプリを作る記事をかいたのですが、今回はそれを少し拡張して、phpからsocket.ioにemitできるようにしてみます。備忘として書きます。

公式ページで下記のように書いてありました。

Sending messages from the outside-world
In some cases, you might want to emit events to sockets in Socket.IO namespaces / rooms from outside the context of your Socket.IO processes.

There’s several ways to tackle this problem, like implementing your own channel to send messages into the process.

To facilitate this use case, we created two modules:

簡単にいうと、
socket.ioのプロセスの外部から、namespaceやroomにイベントをemitするには、下記の2つ(socket.io-redis/socket.io-emitter)を実装しましょう。
ってことらしいです。ただ、これだけだと、jsからしか呼べないので、rubyとかphpでAPI書いてる場合だとちょっと保守性悪そうです。そこで、下記のツールが使えそうです。

socket.io-php-emitter
A PHP implementation of socket.io-emitter

socket.io-emitterのphp実装版を書いてくれた方がいたので、今回はこれを使って、php経由でsocket.ioの特定のroomにemitしてみます。

今回の環境

  • ec2インスタンス (Amazon Linux AMI release 2014.09)
  • Apache (v2.2.29)
  • PHP (v5.3.29)
  • redis (v2.8.19)
  • phpredis (v2.2.5)
  • socket.io (v1.3.5)
  • socket.io-emitter (v0.2.0)
  • socket.io-redis (v0.1.4)

手順

※ httpd、php環境は予め準備されているものとします

  1. redis関連ツールのインストールとredisサーバの起動
  2. socket.io-php-emitterのインストール(途中必要に応じてcomposerもインストール)
  3. socket.io-redis, socket.io-emitterのインストール
  4. server.jsをアップデート & nodeサーバ再起動
  5. 簡易APIを用意
  6. iOS側のソースも少しアップデート
  7. ready to go!

1. redis関連ツールのインストールとredisサーバの起動

redis本体のインストール

AWS EC2にredisをインストールする
以前はmakeしてたんですが、yumでinstallすると秒速且つ設定ファイルなども自動で配置してくれました...ありがとうございます。

redis実行環境を整える

僕の環境だと、/etc/redis.confにconfファイルが配置されました。中の設定を少し変更します。

37c37
< daemonize yes
---
> daemonize no

そのあと下記のようにコマンドを打っていきます。

# vm.overcommit_memory=1を現状で反映させる
sysctl vm.overcommit_memory=1

# 末尾に vm.overcommit_memory = 1 を追加
vi /etc/sysctl.conf

# redisログのgroup:userを変更
chown redis:redis /var/log/redis/redis.log

# 実行
/etc/init.d/redis start

# 実行確認
ps ax | grep [r]edis
29143 ?        Ssl    0:19 redis-server 127.0.0.1:6379 

# サーバ再起動で自動的に実行されるように
chkconfig redis on

# 2~5までonならOK
chkconfig --list redis

※ yumでいれた場合実行スクリプトは、既に /etc/init.d/redis に配置されていました
※ redisグループ/ユーザも勝手に追加されておりましたのでここでは省略(いつのまに?)
※ 参考その1: Redisインストール
※ 参考その2:さくらのVPSにredisをインストール

phpredisのインストール

sudo yum -y install php-pecl-redis --enablerepo=epel

※ 参考: PHPでRedisを使ってみる

2. socket.io-php-emitterのインストール(途中必要に応じてcomposerもインストール)

composerをインストール

今回つかうツールはcomposerパッケージとしてインストールするので、まずcomposerがないと始まりません。

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
# 必要であればpathをbashrcやzshrcに追加
# PATH=$PATH:/usr/local/bin
# vi ~.bashrc

参考:vagrant+CentOSにcomposerを導入

socket.io-php-emitterのインストール

# documentrootへ移動
cd /var/www/html

# ソースを落とす & ソースディレクトリへ移動
git clone https://github.com/rase-/socket.io-php-emitter.git
cd socket.io-php-emitter/

# composerで一括インストール
# (自分の環境では、the requested PHP extension dom is missing from your systemっていうエラーがでたので、一旦 yum install php-xml して再度 composer installしました)
composer install

3. socket.io-redis, socket.io-emitterのインストール

# server.jsがあるディレクトリまで移動
cd /path/to/server.js
# インストール
npm install socket.io-redis
npm install socket.io-emitter

4. server.jsをアップデート & nodeサーバ再起動

# 2,3行目に下記を追加
1a2,3
> var redis = require('socket.io-redis');
> var adapter = io.adapter(redis({ host: '127.0.0.1', port: 6379 }));

# node-server再度実行
node server

5. 簡易APIを用意

例えばこんな感じの簡易APIをサーバ側に用意しておきます。

SIOChatEmitter.php
<?php
    header('Content-type: application/json');

    $json_string = file_get_contents('php://input');
    $json = json_decode($json_string);

    $sepStr = ',';

    $param = $json->param;
    $params = split($sepStr, $param);
    $room = $params[0];

    if(empty($room) || empty($param)){
        exit;
    }
    //echo 'post to' . $room;

    require('src/Emitter.php');
    $redis = new \Redis();
    $redis->connect('127.0.0.1', '6379');
    $emitter = new SocketIO\Emitter($redis);
    $emitter->in($room)->emit('update', $param);

    echo json_encode(array('param' => $param));
?>

6. iOS側のソースも少しアップデート

とりあえず、ニックネームを変更すると、http POSTポストが飛ぶようにしました。
該当箇所はこんな感じ。

ChatViewController.m(289行目)
AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
NSString *postFilePath = [NSString stringWithFormat:@"%@/%@",
kHTTPHostName, kEmitFilePath];

[manager POST:postFilePath
   parameters:@{@"param":[param paramStr]}
      success:^(AFHTTPRequestOperation *operation, id responseObject)
 {
     NSLog(@"posted");
 } failure:^(AFHTTPRequestOperation *operation, NSError *error)
 {
     NSLog(@"Error: %@", error);
 }];

※ ソースは下記においてます。
https://github.com/mitolog/SIOChat

7. ready to go!

6のソースを実行して、1つのroomに2名以上参加してみます。で、自分のnicknameを変更してみると、room内の他のメンバーに 「changed nickname from "hogehoge" to "fugafuga"」という感じでメッセが飛びます。

感想

  • 概念的にはなんとなく分かるのだけど、中身がそんなに理解できていないので、要勉強
  • ステキな勉強会があったら是非いきたい

(話それるけど)勉強になりそうなもの

以上でした〜。

24
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
24