我的Rails聊天应用程序的FAYE_URL值应该是什么?

时间:2018-06-19 13:14:38

标签: ruby-on-rails ruby nginx faye

我正在尝试使用“ 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托管在其他服务器上?

1 个答案:

答案 0 :(得分:1)

我不知道Digital Ocean的服务器。
我已经在操作系统Ubuntu 14.04上使用Google Cloud Engine虚拟机。

这是我配置Nip的Nginx Web服务器上的HTTPS中使用Faye和dns解析器的pub / sub应用程序的方式。

Faye服务器

我将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客户

我参数化了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;
  }
}