我正在尝试使用“ private_pub” gem创建基于Rails的聊天Web应用程序,该应用程序可以在我的本地主机服务器上完美运行。现在,我的网站托管在DigitalOcean上,我想将聊天代码推送到服务器上,以查看实时聊天应用程序将如何工作。
这是我的private_pub.yml文件
development:
server: "http://localhost:9292/faye"
secret_token: "secret"
test:
server: "http://localhost:9292/faye"
secret_token: "secret"
staging:
server: <%= ENV["FAYE_URL"] %>
secret_token:"secret_key"
signature_expiration: 3600 # one hour
production:
server: <%= ENV["FAYE_URL"] %>
secret_token: "secret_key"
signature_expiration: 3600 # one hour
我的问题是我应该怎么做才能使其在任何Linux服务器上工作(对我而言是Digital Ocean)。我正在DigitalOcean上使用Nginx服务器。
private_pub.yml文件中FAYE_URL的值应该是什么?
rackup private_pub.ru -s thin -E production
我是否必须在服务器终端上运行rack命令?还是还有其他方法可以将Faye托管在其他服务器上?
答案 0 :(得分:1)
我不知道Digital Ocean的服务器。
我已经在操作系统Ubuntu 14.04上使用Google Cloud Engine虚拟机。
这是我配置Nip的Nginx Web服务器上的HTTPS中使用Faye和dns解析器的pub / sub应用程序的方式。
我将Faye服务器设置为Rack应用程序,以便在启动时通过“ Thin” Web服务器自动启动。
使用参数启动/停止Thin的脚本:thin配置文件,faye-rackup-server-script。
/home/user/apps/myapp/config/thin.sh
#!/bin/sh
set -e
TIMEOUT=${TIMEOUT-60}
APP_ROOT=/home/user/apps/myapp
PID=$APP_ROOT/tmp/pids/thin.pid
CMD="cd $APP_ROOT; thin -C $APP_ROOT/config/thin.yml -R $APP_ROOT/faye.ru"
AS_USER=user
set -u
startme() {
run "$CMD start"
}
stopme() {
run "thin stop"
}
run () {
if [ "$(id -un)" = "$AS_USER" ]; then
eval $1
else
su -c "$1" - $AS_USER
fi
}
case "$1" in
start) startme ;;
stop) stopme ;;
restart) stopme; startme ;;
*) echo "usage: $0 start|stop|restart" >&2
exit 1
;
esac
所以我设置了脚本Thin.sh的执行许可权
chmod ugo+x /home/user/apps/myappconfig/thin.sh
-rwxr-xr-x 1个用户... thin.sh *
然后我将脚本Thin.sh定义为服务
cd /etc/init.d
sudo ln -s /home/user/apps/myapp/config/thin.sh thin
lrwxrwxrwx 1 root root ... Thin-> /home/user/apps/myapp/config/thin.sh *
最后我在启动时配置了启动
sudo update-rc.d thin defaults
我已经定义了脚本Thin.sh所需的参数(作为config / thin.sh中$ CMD中的参数)
首先是瘦Web服务器配置文件
/home/user/apps/myapp/config/thin.yml
chdir: "/home/user/apps/myapp"
environment: production
address: 127.0.0.1
port: 9292
timeout: 30
wait: 30
max_conns: 1024
log: /home/user/apps/myapp/log/thin.log
pid: /home/user/apps/myapp/tmp/pids/thin.pid
max_persistent_conns: 100
require: []
threadpool_size: 20
daemonize: true
ssl: true
ssl-key-file: "/etc/ssl/private/example_com.key"
ssl-cert-file: "/etc/ssl/certs/example_com.crt"
#ssl-disable-verify: true
然后是Faye服务器启动脚本(通过机架)
/home/user/apps/myapp/faye.ru
require 'eventmachine'
require 'rack'
require 'thin'
require 'faye'
# set FAYE_TOKEN you prefer for faye authentication
require File.expand_path('../config/initializers/faye_token.rb', __FILE__)
Faye::WebSocket.load_adapter('thin')
#define authentication extension
class ServerAuth
def incoming(message, callback)
if message['channel'] !~ %r{^/meta/}
if !message['ext'].nil?
if message['ext']['auth_token'] != FAYE_TOKEN
message['error'] = 'Invalid authentication token'
end
end
end
if message['channel'] =~ %r{/meta/subscribe}
...
end
callback.call(message)
end
end
faye_server = Faye::RackAdapter.new(:mount => '/faye', :timeout => 30)
faye_server.add_extension(ServerAuth.new)
run faye_server
此时,将设置faye服务器的自动启动。
在启动“ /etc/init.d/thin”服务时,使用config / thin.yml可执行文件机架脚本“ faye.ru”启动“瘦服务器”。
我参数化了faye客户的网址
/home/user/apps/myapp/config/initializers/urls.rb
FAYE_MOUNTPOINT_URL='https://example.com/faye'
FAYE_JSCLIENT_URL='https://example.com/faye/client.js'
我在
中包含了faye客户端javascript/home/user/apps/myapp/app/views/layouts/application.html.erb
因此,当您访问应用程序时会向他们收费
<!DOCTYPE html>
<html lang="it">
<head>
<%= javascript_include_tag FAYE_JSCLIENT_URL %>
</head>
...
当您访问有聊天室(作为频道)的页面时,将创建Faye客户端。
正确的地方是
/home/user/apps/myapp/app/assets/javascript/application.js
...
var faye = null;
$(document).ready(function(){
// https
faye = new Faye.Client('<%= FAYE_MOUNTPOINT_URL %>');
faye.disable('autodisconnect');
// divs with '.subscribe' class contain channels name
$('.subscribe').each(function() {
// subscribe each channel
faye.subscribe('/'+$(this).text(), function (data) {
// here I process 'data' to refresh page with new content using jquery
// I'm using hidden div
// when I receive notification I clone hidden div, then I fill some fields and I exhibit the new cloned div
...
msg = $('#message_template').clone();
msg.html(data.message.content);
msg.css('visibility','visible');
});
});
});
从客户端向服务器Faye发送新消息:
(创建带有远程呼叫的新消息模型:true(ajax))
由controller_message#create触发的create.js响应作为ajax响应渲染器调用
/home/user/apps/myapp/app/helpers/application_helper.rb
def broadcast(channel, <your_params>)
# prepare 'data' as json format
data = { your_key: your_params.as_json }
message = { channel: '/' + channel.name, data: data, ext: { auth_token: FAYE_TOKEN } }
# https
uri = URI.parse(FAYE_MOUNTPOINT_URL)
Net::HTTP.post_form(uri, message: message.to_json, use_ssl: true)
end
仅此而已
为了更好的理解,我附上了Nginx配置文件
worker_processes 1;
error_log logs/err.log debug;
events {
worker_connections 1024;
}
http {
upstream faye {
server unix:/tmp/faye.0.sock;
server unix:/tmp/faye.1.sock;
}
passenger_root /home/user/.rvm/gems/ruby-2.3.0/gems/passenger-5.1.11;
server {
listen 80;
server_name example.com;
return 301 https://example.com/$request_uri;
}
server {
listen 443 ssl default_server;
server_name example.com;
ssl_certificate /etc/ssl/certs/example_com.crt;
ssl_certificate_key /etc/ssl/private/example_com.key;
ssl on;
passenger_enabled on;
passenger_app_root /home/user/apps/myapp;
passenger_ruby /home/user/.rvm/gems/ruby-2.3.0/wrappers/ruby;
location / {
root /home/user/apps/myapp/public;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /faye {
proxy_pass https://127.0.0.1:9292/faye;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
}
}