Skip to content

Getting Started With Social Stream Presence

agordillo edited this page Apr 12, 2012 · 107 revisions

Social Stream Presence provides everything you need for including presence, instant messaging and video chat services in your social network website, including a complete chat fully integrated with Social Stream.

Features

  • Transparent presence service.
  • Secure authentication for web clients and external Xmpp clients.
  • Chat based on Xmpp.
  • Multi-User-Chat (MUC) service.
  • Video chat service.
  • Multiplayer games core.
  • Remote presence server support.
  • Multidomain support.
  • Automatic installation and configuration.

 
The services architecture is as shown below:

Therefore we need, in addition to the web server, a reverse proxy and a xmpp server.
The web and xmpp server can be hosted in the same server, in this case, the gem needs to work in local mode, otherwise, the web and xmpp server will be hosted on different servers and the gem will work in remote mode.
We will use Ejabberd as Jabber/XMPP server, and Strophe as javascript xmpp client, Strophe uses BOSH, a binding of XMPP to HTTP using long polling.
It will not be necessary to use a specific reverse proxy, Apache, Nginx or any other will be good.

Xmpp server communicates with the web server through a REST API, also, the web server can execute scripts in the xmpp server remotely (which is not necessary in local mode). The scripts provided by Social Stream Presence are written in ruby, but any of them can be replaced for another written in the landguage you want.
One of this scripts: emanagement, provided important functions to manage ejabberd rosters and other features using ejabberdctl, a control interface of ejabberd server, designed to help the administrator control the functioning of the running ejabberd daemon. For more information read the Emanagement guide.

Shoulders to the wheel!
We are going to install and set up Social Stream Presence step by step:

  1. Install and setting up Social Stream Presence
  2. Setting up the XMPP Server
  3. Setting up the Reverse Proxy
  4. Get it Up and Running
  5. Troubleshooting
  6. Other configuration features

 

At this point we assume that Social Stream (or at least Social Stream Base) is properly installed, otherwise, you must install it following this instructions.
Note that if you have already installed Social Stream, you already have, in addition to the Social Stream base module, the Social Stream Presence module, so, you don't need to add it to your gemfile.

Installation

Add to your Gemfile (if you install only Social Stream Base) :
gem 'social_stream-presence'

Then run:
bundle update

Run the following command that will copy migrations and initializer files:
rails g social_stream:presence:install

And don’t forget to migrate your database:
rake db:migrate

Initializer

You can find the Social Stream Presence initializer at yourApp/config/initializers/social_stream_presence.rb

  1. Main Parameters
  #Configures Web Server Domain served by XMPP Server
  config.domain = "localhost"
  #Configures Bosh Service Path
  #config.bosh_service = "http://xmpp-proxy/http-bind"
  #Configures Authentication Method: "cookie" or "password"
  config.auth_method = "cookie"
  #Configures XMPP Server Password
  config.xmpp_server_password = "autogenerated random password"
  #Uncomment to enable REST API Security
  #config.secure_rest_api = true
  #Remote or local mode
  config.remote_xmpp_server = false
  #Scripts path to execute ejabberd scripts: local or remote
  config.scripts_path = "/scripts_path"
  #Ejabberd module path in the xmpp server
  config.ejabberd_module_path = "/usr/lib/ejabberd/ebin"
  #Uncomment to enable Social Stream Presence
  #config.enable = true

In config.domain we must put our Web Server domain (for example social-stream-node.com).

config.bosh_service default value is http://root_url/http-bind/ , which should be valid for local mode. For remote mode you must replace root_url by the correct XMPP server domain (for example http://social-stream-xmpp-node.com/http-bind/).

By default, the authentication method is by encrypted session cookie (recommended option), but we can change it to allow users login with its password (config.auth_method = "password"). This setting only affects the authentication performed from the browser, access from external xmpp clients is always perform using username and password.

In config.xmpp_server_password there will be an autogenerated random password, but you can change it if you want.

By default the access to the Social Stream Presence REST API will be performed with basic access, that it's perfectly valid (and recommended) to work in local mode or to work in remote mode when traffic between Web and Xmpp server is exchanged by trust networks.
Anyway, if you want to enable secure access to Social Stream Presence REST API, you must uncomment this line config.secure_rest_api = true and you need also to install the OpenSSL library.

We need to store the scripts in a folder (in the xmpp server host) of our choice (for example /etc/ejabberd/ejabberd_scripts/), from now we will refer to this folder as scripts_path.
So, we also need to specify the full path to the script files: config.scripts_path = "/scripts_path" .

To allow the automatic installation of the Xmpp Server we need to specify the ejabberd module path in the Xmpp Server host:
config.ejabberd_module_path = "/usr/lib/ejabberd/ebin"
Default value will be /usr/lib/ejabberd/ebin or /lib/ejabberd/ebin .

We must enable the gem (by default it's disable):
config.enable = true

As mentioned above, we must specify if the Social Stream Presence gem is going to work in local mode (with XMPP and Rails Server hosted in the same server):
config.remote_xmpp_server = false
or if it will work in remote mode:
config.remote_xmpp_server = true
In that case, we must specify the settings for the remote access too.

  2. Remote access

The remote access must be provided by SSH, with authentication by user and password or by user and key.
If we comment this line config.ssh_password , the authentication will performed by user and key automatically.
To allow SSH authentication with key instead of password you must include the user's public key into the ssh/authorized_keys list of the xmpp server. This guide could help you.

  #Parameters for remote mode
  #SSH Login
  #config.ssh_domain = "domain"
  #config.ssh_user = "login"
  #Comment to allow SSH authentication with key instead of password
  #config.ssh_password= "password"

Remember that config.ssh_user is the user who will executed the scripts in the xmpp server host, you must account for this when you set up file permissions .

 

Install Ejabberd in UNIX

You must install the ejabberd packet for UNIX:

sudo apt-get install ejabberd

If you want to work with the Social Stream Presence Ejabberd module to add new features or modify existing, you must install Ejabberd and Erlang/OTP from source, in this case this guide will help you: Social Stream Presence Development Guide.
If you want to run ejabberd in lived mode you must install ejabberd from the sources too.

Install ruby and rubygems

In order to execute the ruby scripts, we need to install ruby in the xmpp server, we also need install rubygems to install gems later. If you are going to work in local mode you probably can skip this step.

sudo apt-get install ruby-full

To install rubygems this guide will help you.

Install rest-client gem

gem install rest-client

Install Social Stream Presence Ejabberd files

Social Stream Presence provides a rake task that automatically copy the files to the xmpp server and performs an automatic installation:

rake presence:install:xmpp_server

If the gem is working in remote mode, SSH access must be configured properly before execute the rake task.

If you only want to download the files (without installation), you can execute the following task: presence:install:copy_xmpp_server_files or download the latest version from https://github.com/ging/social_stream/blob/master/presence/ejabberd/ejabberd_files.zip .

 

If you execute the automatic installation, you can [ SKIP ] the following steps:

- Include Ejabberd modules

mod-admin-extra for implement many additional administrative commands using ejabberdctl:
Copy social_stream/presence/ejabberd/mod_admin_extra/mod_admin_extra.beam to ejabberds module path: /lib/ejabberd/ebin/ or /usr/lib/ejabberd/ebin/ by default.
* mod-muc-admin for implement many additional administrative MUC (Multi-User-Chat) commands using ejabberdctl:
Copy social_stream/presence/ejabberd/mod_muc_admin/mod_muc_admin.beam to ejabberds module path: /lib/ejabberd/ebin/ or /usr/lib/ejabberd/ebin/ by default.
* mod-sspresence to comunicate Ejabberd Server with our Social Stream Rails Application:
Copy social_stream/presence/ejabberd/mod_sspresence/mod_sspresence.beam to ejabberds module path: /lib/ejabberd/ebin/ or /usr/lib/ejabberd/ebin/ by default.

- Include Scripts

We need to copy the scripts located in social_stream/presence/ejabberd/ejabberd_scripts/ to the scripts_path folder previously determined (/etc/ejabberd/ejabberd_scripts/ if you follow the example).

- Include Config Files

Copy ssconfig_example.cfg from social_stream/presence/ejabberd/conf/ to the ejabberd configuration files path: /etc/ejabberd/, and rename it as ssconfig.cfg .

- Include Loggers

Ejabberd stores its log in /var/log/ejabberd/ejabberd.log .
We need to add two new files in this folder: auth.log and scripts.log where the authentication log and the scripts log will be stored respectively:
touch /var/log/ejabberd/auth.log
touch /var/log/ejabberd/scripts.log

 

 1. Edit the file ejabberd.cfg located in the ejabberd configuration files path: /etc/ejabberd/.

   1.1. Enable Ejabberd Modules
   Add or uncomment the following lines in the module section:

%%  
%% Modules enabled in all ejabberd virtual hosts.  
%%  
{modules,  
 [  
  {mod_...,    []}, 
  {mod_http_bind, []},  
  {mod_sspresence, []},
  {mod_admin_extra, []},
  {mod_muc_admin, []},
  {mod_...,    []},    
 ]}.  

 

   1.2. Setting up MUC (Multi-User-Chat) configuration.
    You need to configure the MUC permissions:

%%  
%% MODULES
%% Modules enabled in all ejabberd virtual hosts.  
%%  
 {modules,
 ...
 {mod_muc,      [
		  %%{host, "conference.@HOST@"},
		  {access, muc},
		  {access_create, muc_create},
		  {access_persistent, muc_create},
		  {access_admin, muc_admin}
		 ]},
  ...
  } 

    Define the access rules:

%%%.   ============
%%%'   ACCESS RULES

[...]

%%%%%%%%%%%%%%%%%%
%% MUC permissions
%%%%%%%%%%%%%%%%%%

%% All users can create rooms:
{access, muc_create, [{allow, all}]}.
%% Admins of this server are also admins of the MUC service:
{access, muc_admin, [{allow, admin}]}.
%% All users are allowed to use the MUC service:
{access, muc, [{allow, all}]}.

    If you want, you can deny creation room permissions to all users, the group rooms will continue create properly and users will be able to access them, but they will not be able to create new rooms:

%% No user can create rooms:
{access, muc_create, [{deny, all}]}.

 

   1.3. Define the web domains served by ejabberd
{hosts, ["social-stream-node.com"]}.

   1.4. Authentication method
We need to change the authentication method from internal (default option) to external, to allow ejabberd to authenticate using an external script. Comment this line %%{auth_method, internal}.
And uncomment or add this line {auth_method, external}.
We also need to specify the full path to the authentication script file, so, check that the authentication script located in social_stream/presence/ejabberd/ejabberd_scripts/authentication_script has been copied to the scripts path, and if not copy it.
Specify the path: {extauth_program, "/scripts_path/authentication_script"}.
Also we can specify the number of scripts that that will be operating simultaneously.
For example to allow 3: {extauth_instances, 3}.
Finally, this section of ejabberd.cfg should look something like this:

%%%.   ==============
%%%'   AUTHENTICATION

%%
%% auth_method: Method used to authenticate the users.
%% The default method is the internal.
%% If you want to use a different method,
%% comment this line and enable the correct ones.
%%
%%{auth_method, internal}.

%%
%% Authentication using external script
%% Make sure the script is executable by ejabberd.
%% Exauth Response Timeout is a extauth module constant and its value is 60 seconds.
%%
{auth_method, external}.
{extauth_program, "/scripts_path/authentication_script"}.
{extauth_instances, 3}.

 

   1.5. Allow secure communication with TLS.
To allow this feature you need to generate a SSL certificate, if you want to generate a simple self-signed certificate for ejabberd the following instructions will help you:

   1.5.1 Generate a simple self-signed certificate for ejabberd
We will use make-ssl-cert :
apt-get install ssl-cert
The template is located in /usr/share/ssl-cert/ssleay.cnf, we modify it to add this line days = 7000, to generate a 20 years duration certificate.
Finally we generate the certificate:
make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ejabberd/ejabberdCertificate.pem

   1.5.2 Enable TLS
We need to specify the full path to the SSL certificate file and uncomment this line:

%%%.   ===============
%%%'   LISTENING PORTS

%%
%% listen: The ports ejabberd will listen on, which service each is handled
%% by and what options to start it with.
%%
{listen,
 [
  {5222, ejabberd_c2s, [
			%%{certfile, "/path/to/ssl.pem"}, starttls,
			{certfile, "/etc/ejabberd/ejabberdCertificate.pem"}, starttls,

			{access, c2s},
			{shaper, c2s_shaper},
			{max_stanza_size, 65536}
		       ]},  
[...]

 

  2. Edit the file ssconfig.cfg that should be located in the ejabberd configuration files path: /etc/ejabberd/ .

If you execute the automatic installation, many parameters (like cookie_name or ejabberd_password) will be already configured correctly , you just need to configure the following parameters:

   2.1 Specify the Web Domain (Social Stream Rails App Domain) for REST API:
web_domains=[social-stream-node.com]
If the gem is working in local mode (with XMPP and Rails Server hosted in the same server) the localhost value it's ok.
If the web domain name and its url do not match, you need also to specify the web domain url:
social-stream-node.com=social-stream-node:3000.com

   2.2 Specify the Ejabberd user.
By default if you install ejabberd with sudo apt-get install ejabberd the user name will be 'ejabberd', therefore you don't need to modify anything.
ejabberd_server_user=ejabberd

 
If you execute the automatic installation, you can [ SKIP ] the following steps :

   2.3 Specify the scripts path
scripts_path=/my_scripts_path

   2.4 Cookie name
Social Stream Presence allow two different user authentication methods: authentication by user and password (http://social-stream-node.com/users/sign_in), and authentication by encrypted session cookie (http://social-stream-node.com/api/me), if we will use authentication by encrypted cookie we need also specify the cookie name used in the Social Stream rails application.
So check this line in your app/config/initializers/session_store.rb:
Global::Application.config.session_store :cookie_store, :key => '_rails_server_cookie'
and write the _rails_server_cookie value in this ssconfig.cfg line:
cookie_name=_rails_server_cookie

   2.5 Xmpp Server password
In order to allow Ejabberd to call the API methods, we need to specify a password:
ejabberd_password=password
We must put the same password as we write in the Social Stream initializer: yourApp/config/initializers/social_stream_presence.rb .
When the initializer is generated, a random password is generated too, but if we want we can generate a new password with the provided script social_stream/presence/ejabberd/ejabberd_scripts/development_scripts/generate_random_password passing the password's length as a parameter.

   2.6 Enable Secure Access to Social Stream Presence REST API
By default the access will be performed with basic access, that it's perfectly valid (and recommended) to work in local mode or to work in remote mode when traffic between Web and Xmpp server is exchanged by trust networks.
Anyway, if you want to allow secure access to Social Stream Presence REST API, you need to change or add this line in the ssconfig.cfg file:

#True to enable REST API Security
secure_rest_api=true

 

The default installation of ejabberd via repository will create an user called ejabberd, and the ejabberd server always try to access and execute files with this user.
We need to give permissions to the ejabberd user to read all the configuration files (ssconfig.cfg,...), to write in all logs (auth.log, scripts.log) and execute all the scripts located in the scripts path.
If the gem is going to work in local mode, the rails application's user needs to get permissions too.
If the gem is going to work in remote mode accesing xmpp server via SSH, the user used to login via SSH needs to get permissions.

Before starting take a look at this scheme:

Emanagement script require to execute ejabberdctl commands with sudo -u ejabberd (where ejabberd is the xmpp server user), so, we need to do one more step (for all users except ejabberd):

   3.1 Allow an user to execute sudo without password
  sudo visudo
  Add this line at the end (change “user” to your username):
  user ALL = (ALL) NOPASSWD: ALL

For more control, we can replace (ALL) for (ejabberd) that ensures that the command only will be execute without password for sudo -u ejabberd.

   3.2 [Optional] Filter users allowed to use sudo -u ejabberd on Emanagement
   [ SKIP ]

By default:

#Emanagement configuration
users_require_sudo=all

Instead of all, we can select the users allowed to execute emanegement commands as sudo -u ejabberd in ssconfig.cfg (remember that it is not necessary to add the ejabberd user) in this way:

#Emanagement configuration
users_require_sudo=user1,user2,... 

We need to install (if we don't have one) and configure a reverse proxy, to redirect the BOSH requests sended to the route /http-bind/ and port 80, to the appropriate ejabberd port.
First, we must ensure that http-bind is active on ejabberd and its working fine.
Check the ejabberd.cfg file and add the http_bind option if it isn't present at the port 5280.

{listen,
 [
 [...]
{5280, ejabberd_http, [
			 captcha,
			 http_bind,
			 http_poll,
			 web_admin
			]}

 ]}.

 
If everything works fine, when you visit http://social-stream-xmpp-node.com:5280/http-bind/ you should see a page like this:


If you get an error check if the http-bind ejabberd module (mod_http_bind) is included and enabled, and check if the ejabberd server is running, if isn't you can start it executing sudo /etc/init.d/ejabberd start.
 

Finally, we have to configure the reverse proxy, there are several options of reverse proxies, in this guide we will explain how to running the reverse proxy with Apache and Nginx, but if you choose another option, the config should be very similar.

  1. Running the reverse proxy with Apache
    Edit the file /etc/apache2/sites-available/mySocialStreamRailsApp and add the following lines:
<VirtualHost *:80>
  [...]
  ProxyRequests Off
  ProxyPass /http-bind/ http://127.0.0.1:5280/http-bind
  ProxyPassReverse /http-bind/ http://127.0.0.1:5280/http-bind
</VirtualHost>

 
    2. Running the reverse proxy with Nginx
       Edit the file /etc/nginx/nginx.conf and add the following lines:

http {
    [...]

    server {
	listen 8080;
	server_name localhost;

      location /http-bind {
	  proxy_buffering off;
	  tcp_nodelay on;
	  keepalive_timeout 55;
	  proxy_pass http://localhost:5280;
      }

    }
}

If everything works fine, when you visit http://social-stream-xmpp-node.com/http-bind/ you should see again this page:

If you get an error check the proxy reverse and your firewall configuration.
 
 

Start the Social Stream Rails Application if you haven't started yet:
rails server

Start the ejabberd server
sudo /etc/init.d/ejabberd start

We need to synchronize the Social Stream Rails Application database with Ejabberd database.
Synchronize rosters (xmpp server buddy lists).
bundle exec rake presence:synchronize:rosters
Synchronize rooms (Group's chat rooms).
bundle exec rake presence:synchronize:rooms

To keep the presence synchronize we need to run the presence:synchronize:connections rake task before each deployment, for example, if you use capistrano, add the following lines to deploy.rb file could help:

before 'deploy:restart', 'deploy:synchronize_presence'

namespace(:deploy) do
  task :synchronize_presence do
    run "cd #{current_path} && bundle exec \\"rake presence:synchronize:connections RAILS_ENV=production\\""
  end
end

Also you can synchronize presence from the Xmpp Server side executing the synchronize_presence_script .

  

If everything works fine, after log in, you should see a chat widget in the home's page toolbar:

When another contact is logged in, you should see a box with his avatar in the chat widget:

Now we are ready to enjoy with all the features of Social Stream Presence!

If you contact us here we will be pleased to help you and answer your questions.

General advices

  • We recommend this order to get Social Stream Presence up and running.

  • To test the Ejabberd Xmpp Server individually, without the web application, we recommend connect with a external Xmpp client like Pidgin, this guide explain how to do it: How to enable Social Stream Chat in external XMPP clients like Pidgin.

  • To check if the Ejabberd database is correctly synchronized, you can use Emanagement, a ruby script that provides important functions to manage ejabberd rosters and other features using ejabberdctl, this guide explain how to use it: Emanagement guide .

  • When you integrate the web application, set the permissions carefully and verify that the users can run the scripts and they can write in the appropriate logs before continue.

  • Read log files always help:
    Ejabberd crash? Read /var/log/ejabberd/ejabberd.log .
    Authentication issues? Read /var/log/ejabberd/auth.log .
    What scripts were executed? Read /var/log/ejabberd/scripts.log .
    If the logs are empty, scripts are not running (look at script header issue) or the user who execute them dont have permissions to write in the logs.

  • If ejabberd crash on start, review ejabberd.cfg file and check if there isn't another ejabberd instance running.

Frequent issues

By default the ruby scripts header is:
#!/usr/bin/env ruby

Maybe you dont have ruby in your path (or you are using RVM) and you need to change the scripts header. In this case you must open the script files and change the header manually. Be careful modifying script headers, because, as shown in the file permissions scheme , different users can require different headers.

It's probably a database synchronization problem, to check if the Ejabberd database is correctly synchronized, you can use Emanagement, a ruby script that provides important functions to manage ejabberd rosters and other features using ejabberdctl, this guide explain how to use it: Emanagement guide .

Clone this wiki locally