rails5 ActionCable in chatroom, 为之后开发狼人多人游戏做准备
- 整个流程
Afterrails new chat
andbundle install
, we add some related in Gemfile, so now it will look like this:
1 | source 'https://rubygems.org' |
[1] in routes.rb, we set the root page to be1
root ‘sessions#new’
which means that it will first find the SessionsController’s new method and implement it. We know in rails that when it runs a controller method, it will also render the corresponding views html.erb in view folder. Thus the views/sessions/new.html.erb
will be first rendered.
Further observing in routes.rb:1
2
3
4
5Rails.application.routes.draw do
resources :messages, only: [:index, :create]
resources :sessions, only: [:new, :create]
root 'sessions#new'
end
we find the use of resources
, which means we treat those objects as RESTFUL as we could, those objects in their controllers will have all seven methods like new, create, update, destroy and so on which corresponds to the Http Verbs like post, get and so on.
Then, we look at the new.html.erb
1 | <%= form_for :session, url: sessions_path do |f| %> |
where :session
is the name for this form, when in use in SessionsController, we obtain the information in this form by1
cookies.signed[:username] = params[:session][:username]
And url: sessions_path
is for directing the action to SessionsController#create.
In MessagesController.rb
we use index to render the view1
2
3
4
5
6
7
8
9
10
11Signed in as @<%= cookies.signed[:username] %>.
<br><br>
<div id="messages"></div>
<br><br>
<%= form_for :message, url: messages_path, remote: true, id: messages-form do |f| %>
<%= f.label :body, 'Enter a message:' %> <br>
<%= f.text_field :body %> <br>
<%= f.submit 'Send message' %>
<% end %>
where the cookies are carrying the parameters we need in another controller, while the empty div
will eventually be filled with previous content. As for the form, it will pretty similar as the SessionsController#new.
- here we use
remote: true
, which is calling with Ajax. In usual case, we will need to specify the partial js file we want to implement in MessagesContrller#create method. * But, here we just want it to reload again without refreshing the page.
ActionCable
ActionCable uses Redis for publishihng and subscribing to the messages, so we need to configure Redis in config/redis/cable.yml. You will need Redis installed and running for ActionCable to work.
Redis
reds is a key-value store, often referred to as a NoSQL database. Key features are that: [1] the data can be retrieved by key later in use. [2] the key-value will be stored permanently.
1 | SET server:name “fido” |
Compared with1
2
3x = GET count
x = x + 1
SET count x
we choose to use INCR because it is a atomic operation which will work as expected if multiple users want to access this value.1
2EXPIRE server:name 120 //after 120s this value will vanish
TTL server:name // obtain after how long it will vanish
List operation
RPUSH, LPUSH, LLEN, LRANGE, LPOP, RPOP
Set operation
SADD, SREM, SISMEMBER, SMEMBERS, SUNION
where SMEMBERS
returns a list of all members of this set.
Sorted Set
ZADD, ZRANGE
Hashes
HSET, HGETALL, HMSET, HGET, HINCRBY, HDEL
like
1 | HMSET user:1001 name "Mary Jones" password "hidden" email "[email protected]" |
Adding our MessagesChannel
1 | # app/channels/messages_channel.rb |
whenever a client subscribes to MessageChannel, the #subscribed
method will be called, which starts streaming anything you broadcast to the “messages” stream.