ジャックドーシーにしびれる
Square
Squareについて調べてて、ジャックドーシーの言葉がかっこよくて痺れたので。
You. You’re the future. You have the ideas. That’s your task. Sometimes you win. Sometimes you lose. But it’s up to you to make what you want to see the world.
君。君が未来だ。君がアイディアを持っている。それがあなたの勤めだ。もしかしたら勝てるかも。もしかしたら負けるかも。でも、君が見たい世界を創るか創らないかは君次第。
ちなみに、このブログのサブタイトルは、DropBoxのドゥリュー・ヒューストンの言葉です。
Computer Programming is the closest thing we have to a superpower
コンピュータープログラミングはスーパーパワーに一番近い力だ。
あー、かっこいいな
Go lang で Hello World
Go Lang
先日友達がごうこんに行ってきたらしいので詳しく聞いたら、Go Conferenceだった。
そんな形で知ったGo Langでこちらの記事を参考にHello Worldしてみた。
バージョン
CentOS Linux release 7.0.1406 (Core)
インストール
cd /usr/local/src wget https://storage.googleapis.com/golang/go1.2.2.linux-amd64.tar.gz tar -C /usr/local/ -xzf go1.2.2.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin
Hello World
package main import "fmt" func main() { fmt.Printf("hello, world\n") }
実行
go run hello.go
表示
hello, world
わーいわーい!
Websocket Railsを使って特定のユーザーにメッセージを送る
特定のユーザにメッセージを送る
前回のブログ記事でWebsocket Railsを用いて接続が確立したユーザ全員にメッセージを送る実装方法について書きました。今回はFacebookのプライベートメッセージのように特定のユーザにメッセージを送りたい時にどうしたら良いのかを書いていきたいと思います。(この記事では省略していますが、参考サイトに載せているGithubのページのInstallation Guildeに従ってWebsocket Railsのインストールをして下さい。または前回の記事を見て下さい。)
特定のユーザの指定方法
さて、どうやって実装したらいいのかな。と少し調べていたら、本家のサイトにこのような事が書いてありました。ふむふむ。UserManagerとやらを使うらしい。
You can send an event to a specific client using the UserManager which can be accessed via WebsocketRails.users.
myUser.idとは何かな?WebsocketRails.usersとは?
WebsocketRails.users[myUser.id].send_message('new_notification', {:message => 'you\'ve got an upvote '})
それは二個目の参考サイトにこのように書いてありました。
If there is a `current_user` method defined in ApplicationController and a user is signed in to your application when the connection is opened, WebsocketRails will call the method defined in `config.user_identifier` on the `current_user` object and use that value as the key.If no `current_user` method is defined or the user is not signed in when the WebsocketRails connection is opened, the connection will not be stored in the UserManager.
なるほど。application controllerにcurrent_userメソッドを定義しておけばWebsocketの接続が確立されたと同時にUserManagerにユーザの情報を格納してくれるらしい。便利ですなー。
実装方法
もう既に出来上がっているサイトで、ごちゃごちゃしていてどこから説明していいのか分からないので、必要最低限の部分をメモ程度に書いていこうと思います。既にユーザなどは存在する体でお願いします。ちなみにUIはこのような形です。画像があった方が少しはイメージし易いかもしれません!
まず参考サイトに書いてあったようにapplication_controllerに current_userを定義します。これがないと始まらない。
def current_user return unless session[:user_id] @current_user ||= User.find(session[:user_id]) end
前回のブログ同様JS側でWebsocketの接続を確立させるコード、Websocketを通してサーバー側から送られてきたメッセージを表示するコードを書きます。実際に書いたコードをかなり簡略化させています。
$(document).ready(function(e){ var ws_rails = new WebSocketRails("localhost:3000/websocket"); ws_rails.bind("websocket_message", function(message){ //json形式で送られてくるのでパースします var data = JSON.parse(message); //データをゴニョゴニョしてHtmlを生成して、appendします $("#message_box").append(ゴニョゴニョされたやつ); }); });
これでほとんど完成です。後はコントローラー側でメッセージがCreateされた時に以下のコード書きます。
message = "message" WebsocketRails.users[送りたいユーザーのID].send_message('websocket_message', message)
下記がメッセージがcreateされた時の実際のコードになります。少し汚いかもしれません。リーダブルコード読み直すので許して下さい。
def create #これらの情報はajaxで送られてきています msg_to_id = params.require(:message_to_id) message_text = params.require(:message_text) # 新しくmessageを作ります。message_from_idは今のユーザIdを格納 message = Message.new(message_to_id: msg_to_id, message_from_id: current_user.id, text: message_text) if message.save #JS側でHtmlを生成する為の情報を変数に格納します #message:メッセージの内容 image_url:送り主のプロフィール画像 nickname:送り主の名前 message_id:メッセージのID created_at: 時間 message_data = {message: message_text, image_url: current_user.image_url, nickname: current_user.nickname, message_id: message.id, created_at: message.created_at.strftime("%X %d/%m")}.to_json # Websocketを用いて今メッセージを送ったユーザと送られたユーザーにメッセージを送ります。 # 同時に二人は出来ないっぽい WebsocketRails.users[msg_to_id].send_message(:websocket_message, message_data) WebsocketRails.users[current_user.id].send_message(:websocket_message, message_data) render nothing: true else render status: 500 end end
これで動くと思います。
因みにbinding.pryでWebsocketRails.users(UserManager)の中身を見てみるとこんな感じです。ちゃんとユーザのデータが格納されています。
[1] pry(#<MessagesController>)> WebsocketRails.users => #<WebsocketRails::UserManager:0x000000091e7180 @users= {"2"=> #<WebsocketRails::UserManager::LocalConnection:0x000000091e70e0 @connections= [#<Connection::23c23305067da6ce6f36>, #<Connection::49eb23fad9a1acfd2154>, #<Connection::94af81b53170778b8d91>, #<Connection::df220cd8d761665985bc>, #<Connection::b26cc68e6842a8cff094>, #<Connection::dd73e630844a776c05a9>]>, "1"=> #<WebsocketRails::UserManager::LocalConnection:0x00000007d3d0e0[f:id:takuyanz:20150130230126p:plain] @connections=[#<Connection::88238ad7c31d08b3dc8d>, #<Connection::611d13d332b53cf85051>, #<Connection::946088f8474222d7640d>]>}>
Websocketの接続を確立させる時に以下のコードよりは、
var ws_rails = new WebSocketRails("localhost:3000/websocket");
実際にサイトをWeb上に上げる事を考えて以下のように書くと、ベターかも。
var ws_rails = new WebSocketRails(location.host + "/websocket");
この方法で以下のような通知機能や、新しいコンテンツがある場合のプラス+1なども実装する事が出来ました。
説明が少し分かりにくかったかな?技術系の記事を書いた事がないので、これから書きながら慣れていきたいと思います。
Websocketってすごいな。とにかく感動しまくりでした。Webアプリケーションを作りたいとプログラミングを始めて5か月が経とうとしています。サイトが裏でどのような動きをしているのかが分かってきて、わくわくしております。わくわくわくわく。
:)
Websocket Railsを使ってみたお話
Websocket
まず第一にWebsocketって何なのか?美味しいのか、美味しくないのか?
Websocketとはクライアントとサーバーで双方向通信ができる技術らしいです。つまり、クライエント側からサーバにリクエストする事もできるし、サーバ側からも何らかのアクションをクライエント側に起こす事ができる(サーバプッシュ)。こんな感じで大雑把に理解している。(参考サイト)
WebsocketRails
とりあえず実際に使ってみる事に。今回は主に公式のGithubページとこちらの記事がとても分かりやすかったので参考にさせて頂きました。
まずブロードキャスティングから。ブロードキャスティングとはWebsocketの接続が確立されているユーザー全員にサーバープッシュを行います。
では、初めからやってみましょう。とりあえずお決まりのコマンドを走らせます。
rails new demo bundle install --path vendor/bundle
Gemfileに以下を足す。もう一度bundle install。
gem "websocket-rails"
次にこちらのコマンド。
rails g websocket_rails:install
create config/events.rb
create config/initializers/websocket_rails.rb
append app/assets/javascripts/application.js
Development環境でwebsocketを動かすには以下のコードをconfig/environments/development.rbに足す必要があるらしい。ふむふむ
config.middleware.delete Rack::Lock
早速config/evetns.rbを開いて下記を付け足します。下記は後に書いていくJS側で呼ばれるsend_messageに対して、WebsocketMessageControllerのrecieve_messageのメソッドが呼ばれるという意味。
subscribe :send_message, :to => WebsocketMessageController, :with_method => :recieve_message
次に上のファイルで指定したコントローラーを手動で作成します(app/controller/websocket_message_controller.rb)。こちらのファイルには下記を書いていきます。これでメッセージをブロードキャスティングする準備はほぼ整いました。
class WebsocketMessageController < WebsocketRails::BaseController def recieve_message message = message(); broadcast_message :show_message, message end end
次に以下のコマンドを使い、クライエントサイドを作っていきましょう。Controllerを作成するのは、Indexページを表示する為。
bundle exec rails g controller messages index --no-helper --no-assets
作成したHtmlファイルに以下を書き足します。(app/view/messages/index.html.erb)
<div id="message_box"> <p>broadcasting message</p> <!-- message will be shown here --> </div> <input type="text" id="message_input"> <input type="button" id="send_message" value="send">
<script> $(document).ready(function(e){ var dispatcher = new WebSocketRails('localhost:3000/websocket'); $(document).on("click", "#send_message", function(e){ message_text = $("#message_input").val(); dispatcher.trigger("send_message", message_text); }); dispatcher.bind("show_message", function(message){ $("#message_box").append("<p>" + message + "</p>"); }); }); </script>
これでブロードキャスティングのメッセージ機能は完成です。rails サーバーを起動させて、http://localhost:3000/messages/index にアクセスしてみましょう。
rails s
これで動くはずです。
ここまでは結構色々な方々がやっていて比較的情報が手に入れやすくスムーズに出来ました。でも今回サイトを作るにあたって実装したかった機能は特定のユーザにのみメッセージを送る事。次回の記事で少し触れてみようと思います。
:)