ラベル aws の投稿を表示しています。 すべての投稿を表示
ラベル aws の投稿を表示しています。 すべての投稿を表示

2015年2月5日木曜日

RailsからRpushを使用して、スマートフォンにプッシュ通知を送る

サーバサイドの開発をしていて、プッシュ通知をクライアントに送るという機能を実装する事が多くなったのと、日本語の情報が少なかったので書きます。
私がよくRailsからプッシュ通知を送る為に使用しているのが、「Rpush」というgemです。
その他、Rubyからプッシュ通知を送る為のgemというのはあるのですが、最近はもっぱら「Rpush」です。

Rpushの特徴

  • サポートするサービス
    • Apple Push Notification Service
    • Google Cloud Messaging
    • Amazon Device Messaging
    • Windows Phone Push Notification Service
  • サポートするストレージサービス
  • Rails3, 4対応
  • デーモンかRailsの中のプロセスとして動きます
  • エラーハンドリングが簡単に書ける
  • JRubyでも動くらしい(試してない)

Rpushのしくみ

  1. Rpush用のテーブル(Rpush::Notification)にプッシュ配信のデータを書き込む(メッセージだったり、カスタムデータだったり)
  2. Rpushがテーブルに書き込まれたのを検知する
  3. 配信される
  4. エラーが出れば、Rpush用のテーブル(Rpush::Notification)に書き込まれる

導入

1. GemfileにRpushを追加
gem 'rpush'
2. Railsのルートでコマンドを実行します。
$ rails g rpush
3. 2のコマンドで、config/initializers/rpush.rb, とRpush用のマイグレーションファイルが出来たので、テーブルを作成します
$ rake db:migrate
4. 次にアプリ(Rpush::App)を作成してやります。RpushにはAppという概念があり、それをテーブルに登録してやる必要があります。実際にはseedで登録してやるのがいいでしょう。
  • APNsの場合
app = Rpush::Apns::App.new
app.name = "ios_app"   #一意なアプリ名
app.certificate = File.read("/path/to/sandbox.pem") # サーバ側の証明書
app.environment = "sandbox" # APNsの環境 開発環境なら"sandbox" 本番環境であれば"production"
app.password = "certificate password" # 証明書のパスワード
app.connections = 1 # APNsへのコネクション数(※DBへのコネクションも増えるので注意!)
app.save!
  • GCMの場合
app = Rpush::Gcm::App.new
app.name = "android_app" #一意なアプリ名
app.auth_key = "..." # GCM APIキー
app.connections = 1 # GCMへのコネクション数(※DBへのコネクションも増えるので注意!)
app.save!
以上で準備完了です。

実装

1. まずRpushをスタートさせます。
  • デーモンの場合
cd /path/to/rails/app
rpush <Rails environment> [options]
  • Railsのプロセスと同時に動作させる場合(config.ruに追加)
Rpush.embed

2. 実際にプッシュ通知を送ります。
  • APNsの場合
最初に作成した、Rpush::Apns::Appのレコードに紐づける形で、Rpush::Apns::Notificationを作成してやります。
notification = Rpush::Apns::Notification.new
notification.app = Rpush::Apns::App.find_by_name("ios_app") # Rpush::Apns::Appインスタンスを設定
notification.device_token = "..." # デバイストークン
notification.alert = "hi mom!"  # プッシュメッセージ
notification.data = { foo: :bar } # カスタムデータ
notification.save!
  • GCMの場合
最初に作成した、Rpush::Gcm::Appのレコードに紐づける形で、Rpush::Gcm::Notificationを作成してやります。
notification = Rpush::Gcm::Notification.new
notification.app = Rpush::Gcm::App.find_by_name("android_app")  # Rpush::GCM::Appインスタンスを設定
notification.registration_ids = ["token", "..."] # registration_idを設定
notification.data = { message: "hi mom!" } # カスタムデータ
notification.save!
これで、登録されたRpush::NotificationのデータをRpushが検知して、プッシュ通知を送信してくれます。

まとめ

通知を送る為に、プログラム側ではデータベースにレコードを追加するだけなので、簡潔で、テストもしやすい設計だなという印象です。
今回は、APNsとGCMを紹介しましたが、「Amazon Device Messaging」「Windows Phone Push Notification Service」にも対応しています。

RailsからiPhone、Androidへのpush通知メモ

RailsからiPhoneやAndroidにpush通知した。
使ったのは下記Gem。

必要なもの

iPhone

Android

iPhoneへpush通知

Gemfileに追加後bundle install
gem 'apns'
まずpemファイルを作ってあげないといけない
openssl pkcs12 -in cert.p12 -out cert.pem -nodes -clcerts
作ったpemファイルを/path/to/cert.pemに配置し、下記でpush通知が送れる。
APNS.host = 'gateway.push.apple.com' 
APNS.pem  = '/path/to/cert.pem'
APNS.port = 2195 

device_token = 'xxxxxxxxxxxxxxxxxxxx' # 送りたい端末のdevice token
APNS.send_notification(device_token, :alert => 'Hello iPhone!', :badge => 1, :sound => 'default')

Androidへpush通知

Gemfileに追加後bundle install
gem 'gcm'
下記実行するとandroid側に通知が飛ぶ
require 'gcm'

api_key = "xxxxxxxxxxxxxxxxxxxx"
registration_ids = ["a1", "a2", "a3"] # 送りたいregistration_idの配列
gcm = GCM.new(api_key)
options = {data: {score: "123"}, collapse_key: "updated_score"}
response = gcm.send_notification(registration_ids, options)
options内のdataハッシュ内に自由にキーを設定して送信してあげるとAndroid側で取得して色々処理できたりします

2015年2月4日水曜日

Nginix + Unicorn on AWS


メモ
  • 注意点
    • nginixの起動ユーザーをec2-userにする。
    • index.htmlを読めるようにする。LBSのヘルスチェックでNGくらうと接続できなくなる。


nginx停止

sudo /etc/init.d/nginx stop

unicorn停止

ps ax|grep unicorn|grep -v grep
これで表示されるmasterのプロセスをkillする

nginx再起動

sudo /etc/init.d/nginx restart





2015年2月3日火曜日

Rails on AWS MySQLの設定

概要

RailsのDBMSを初期設定のSQLiteからMySQLに変える方法です。


前提

  • Rails: 4.2.0
  • Ruby: 2.1.0p0
  • OS: Amazon Linux

MySQL設定

インストール

MySQLを公式サイトからダウンロードします。

初期設定

インストールしたら、MySQLを起動して初期設定をします。

# mysql -h mydbinstance.c7g4ipy6pxy7.ap-northeast-1.rds.amazonaws.com -P 3306 -u root -p mydb

作業ユーザー作成

次に作業ユーザーを作成します。
作業ユーザーはdevelopment、test、productionの3つ必要になります。
では、ターミナルでmysqlを起動してください。
で、作業ユーザーを作成します。ユーザー名は「'ユーザー名'@'localhost'」という書式になります。

mysql&gt; create user test identified by 'パスワード1';
mysql&gt; create user development identified by 'パスワード1';
mysql&gt; create user production identified by 'パスワード1';

作成したユーザーの確認は以下のコマンドで確認できます。
mysql&gt; select User,Host from mysql.user;

以下のコマンドで作成したユーザーに権限を付与します。
mysql&gt; grant all on *.* to '[ユーザー名]'@'localhost'


データベースを作成する。
mysql&gt; CREATE DATABASE test CHARACTER SET utf8;
mysql&gt; CREATE DATABASE development CHARACTER SET utf8;
mysql&gt; CREATE DATABASE production CHARACTER SET utf8;
mysql&gt; show databases;

Mysql2のインストール

$ sudo yum install mysql-devel
$ gem install mysql2

Rails設定

まず、Railsアプリを作成します。


-d mysqlとオプションを指定し、デフォルトDBMSをMySQLに変更します。

$ rails new [アプリ名] -d mysql

「{RailsRoot}/config/database.yml」を開きます。
[アプリのルート]/config/database.yml
# コメント略

development:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: development *データベース
  pool: 5
  username: root
  password: *パスワードを設定
  host: mydbinstance.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
test:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: test *データベース
  pool: 5
  username: root
  password: *パスワードを設定
  host: mydbinstance.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com

production:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: production
  pool: 5
  username: root
  password: *パスワードを設定
  host: mydbinstance.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com



以下修正を行う。

  • development、test、productionのユーザー名とパスワードを「username」と「password」に設定する。
  • hostもrdsのエンドポイントに修正する。
  • databaseの名前も修正する。
そんで、$ rake db:migrateします。
これでOKのはず
適当にテストしたい方は以下のようにscaffold使って試してみると良いでしょう。
$ rake db:create
$ rails g scaffold home name:string body:text email:string
$ rake db:migrate

以下にアクセスしてみる。

http://54.65.164.15/homes


Ruby on Rails 5.0 on AWS


環境

  • Ruby 2.1.0p0
  • Rails 4.2.0
  • nginx
  • unicorn




手順

各種インストールする。

[ec2-user@ip-xxx ~]$ sudo yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison git
[ec2-user@ip-xxx ~]$ git --version
git version 1.8.3.1

1. ruby-buildインストール
$ cd
$ git clone git://github.com/sstephenson/ruby-build.git
$ cd ruby-build
$ sudo ./install.sh
2.rbenv, rubyインストール
$ cd
$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bashrc
$ exec $SHELL -l
$ rbenv install -l
$ rbenv install 2.1.0;rbenv rehash
$ rbenv global 2.1.0

結果

[ec2-user@ip-xxx ~]$ ruby -v
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux]
[ec2-user@ip-xxx ~]$ which gem
~/.rbenv/shims/gem
[ec2-user@ip-xxx ~]$ which ruby
~/.rbenv/shims/ruby
[ec2-user@ip-xxx ~]$

3.bundle 入れる

[ec2-user@ip-xxx ~]$ bundle list
-bash: bundle: コマンドが見つかりません
[ec2-user@ip-xxx ~]$ gem install bundler --no-rdoc --no-ri
Fetching: bundler-1.6.3.gem (100%)
Successfully installed bundler-1.6.3
1 gem installed
[ec2-user@ip-xxx ~]$ gem list

*** LOCAL GEMS ***

bigdecimal (1.2.3)
bundler (1.6.3)
io-console (0.4.2)
json (1.8.1)
minitest (4.7.5)
psych (2.0.2)
rake (10.1.0)
rdoc (4.1.0)
test-unit (2.1.0.0)
[ec2-user@ip-xxx ~]$ sudo rbenv rehash
[ec2-user@ip-xxx ~]$ ll
合計 0

4. Rails 入れる

[ec2-user@ip-xxx ~]$ gem install rails 
[ec2-user@ip-xxx ~]$ rbenv rehash
[ec2-user@ip-xxx ~]$ rails -v
 4.1.4
[ec2-user@ip-xxx ~]$ which rails 
~/.rbenv/shims/rails

5. Unicornインストール

Railsアプリ${my_app}のGemfileに以下を追記して、$ bundle installするだけ。
${my_app}/Gemfile


gem 'unicorn', '4.8.3'
$ bundle install

8. Unicorn の設定

$ cd myapp
$ vi config/unicorn.rb

# ファイルの記載内容


@dir = "/home/ec2-user/rails/WebApp/"

worker_processes 2

working_directory @dir

timeout 30

listen "#{@dir}tmp/sockets/unicorn.sock", :backlog => 64

pid "#{@dir}tmp/pids/unicorn.pid"

stderr_path "#{@dir}log/unicorn.stderr.log"

stdout_path "#{@dir}log/unicorn.stdout.log"

preload_app true


9.nginxを入れる

sudo yum -y install nginx

10.nginxの確認

sudo /etc/init.d/nginx start
# http://xxx.compute.amazon.com/
# Welcome to nginx on the Amazon Linux AMI!と出れば成功
sudo /etc/init.d/nginx stop
# 公開パス /usr/share/ngin/html/

11.nginxの設定ファイル編集

sudo vi /etc/nginx/nginx.conf
worker_processes  1;

events {
    worker_connections  1024;
}

http {

    upstream unicorn_server {

        server unix:/home/ec2-user/rails/WebApp/tmp/sockets/unicorn.sock fail_timeout=0;

    }

    server {
        listen       80;
        server_name  localhost;
        location ~ ^/assets/(.*) {
           alias /home/ec2-user/rails/WebApp/public/assets/$1;
        }

        location / {

            root /usr/share/nginx/html;

            index  index.html index.htm;

            try_files $uri/index.html $uri.html $uri @unicorn_rails_app;

        }

        location @unicorn_rails_app {

           if (-f $request_filename) { break; }



           proxy_set_header X-Real-IP  $remote_addr;

           proxy_set_header X-Forwarded-Server $http_host;

           proxy_set_header X-Forwarded-Host   $http_host;

           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

           proxy_set_header Host $http_host;

           proxy_redirect off;


           proxy_pass http://unicorn_server;

        }

    }
}

sudo vi /etc/nginx/nginx.conf worker_processes 1; events { worker_connections 1024; } http { upstream unicorn_server { server unix:/home/ec2-user/rails/WebApp/tmp/sockets/unicorn.sock fail_timeout=0; } server { listen 80; server_name localhost; location ~ ^/assets/(.*) { alias /home/ec2-user/rails/WebApp/public/assets/$1; } location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri/index.html $uri.html $uri @unicorn_rails_app; } location @unicorn_rails_app { if (-f $request_filename) { break; } proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Server $http_host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://unicorn_server; } } }

sudo vi /etc/nginx/nginx.conf
worker_processes  1;

events {
    worker_connections  1024;
}

http {

    upstream unicorn_server {


        server unix:/home/ec2-user/rails/WebApp/tmp/sockets/unicorn.sock fail_timeout=0;


    }

    server {
        listen       80;
        server_name  localhost;
        location ~ ^/assets/(.*) {
           alias /home/ec2-user/rails/WebApp/public/assets/$1;
        }

        location / {


            root /usr/share/nginx/html;


            index  index.html index.htm;


            try_files $uri/index.html $uri.html $uri @unicorn_rails_app;


        }


        location @unicorn_rails_app {


           if (-f $request_filename) { break; }







           proxy_set_header X-Real-IP  $remote_addr;


           proxy_set_header X-Forwarded-Server $http_host;


           proxy_set_header X-Forwarded-Host   $http_host;


           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


           proxy_set_header Host $http_host;


           proxy_redirect off;





           proxy_pass http://unicorn_server;


        }

    }
}


再起動する。
sudo /etc/init.d/nginx stop
sudo /etc/init.d/nginx start


---