<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hwang40</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hwang40"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Hwang40"/>
	<updated>2026-05-18T11:43:53Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96925</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96925"/>
		<updated>2015-04-24T03:44:29Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Synchronization between server and local mobile application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. Sahana Eden Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot; style=&amp;quot;float:{{{align|right}}}&amp;quot;&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; |[[File:SahanaLogo.png|center|Sahana]]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project aims at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to add new shelters and hospitals, get information of hospitals and shelters offline/online, get GPS location of device, and provide multilingual support.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &lt;br /&gt;
&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/ Sahana Eden Instroduction]&amp;lt;/ref&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
*Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
*To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
*Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://docs.google.com/a/ncsu.edu/document/d/11bblC7klisYjN7Gjw6hDcs5TZ8uesJD3o2xnM2gI914/edit# overview of all the Sahana Eden projects]&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Edenmobile Introduction]&amp;lt;/ref&amp;gt;  &lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile#J2ME list] of all the requirements need to be done in this project. &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*[https://github.com/szhao8/eden Open source code about Sahana Eden]&amp;lt;ref&amp;gt;[https://github.com/szhao8/eden Sahana Eden Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
*[https://github.com/szhao8/EdenMobile Open source code about Eden Mobile]&amp;lt;ref&amp;gt;[https://github.com/szhao8/EdenMobile EdenMobile Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
&lt;br /&gt;
Below is the overview of the Eden Mobile Platform. It uses a Model-View-Controller design pattern as the foundation of the project. And it also introduces a &amp;quot;plugin&amp;quot; mechanism, from which developers can add new modules (pages) to the main menu by adding them to &amp;quot;plugins&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Architecture.png |frame‎|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
==Use Cases==&lt;br /&gt;
&lt;br /&gt;
* '''1. Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''2. Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''3. Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''4. Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''5. Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''6. Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
==Login==&lt;br /&gt;
&lt;br /&gt;
The Sahana Eden website already has a login page, so our initial thought is to find the web service URL for login function, and use it in our log in page on Sahana Mobile. After scrutinize the python code of Sahana Eden, we found the login url, which is &amp;quot;localhost:8000/eden/default/user/login?_next=%2Feden%2Fdefault%2Findex&amp;quot;, then we use this URL as the post destination and created the login page as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Login.png]]&lt;br /&gt;
&lt;br /&gt;
However, if we input the correct login information and then click &amp;quot;login&amp;quot; to post our login request, we will be redirected to the Sahana Eden's original login page, rather than log into the system, as the following picture shows. Unfortunately, we have found a solution to this problem.&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_LoginAfter.png]]&lt;br /&gt;
&lt;br /&gt;
==Hospital plugin==&lt;br /&gt;
===Customize hospital form===&lt;br /&gt;
According to the [http://pastebin.com/Gj6nEnSu create.s3json file] in the hospital module on the official website, we create the hospital form in the Eden mobile application.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    var editHospitalForm = [&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;name&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;,&lt;br /&gt;
            required: true&lt;br /&gt;
        },&lt;br /&gt;
        ///*&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;aka1&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;code&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;facility_type&amp;quot;,&lt;br /&gt;
            control: &amp;quot;integer&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;organisation_id&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;L0&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            common_name: &amp;quot;Country&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_street&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_postcode&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;location&amp;quot;,&lt;br /&gt;
            control: &amp;quot;gis_button&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;address&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;postcode&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;city&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        }, &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_exchange&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_business&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },    &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_emergency&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;website&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;email&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },   &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;fax&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;obsolete&amp;quot;,&lt;br /&gt;
            control: &amp;quot;checkbox&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;footer&amp;quot;,&lt;br /&gt;
            control: &amp;quot;text&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Synchronization between server and local mobile application===&lt;br /&gt;
Utilizing the framework provided by the developer, we realized to synchronize hospital data from server to the local mobile application. You can see what we did in the following image. We create a new hospital name Hospital in the Sahana, after clicking the &amp;quot;save&amp;quot; button, the new hospital is saved in the server. Then if we click the &amp;quot;refresh list&amp;quot; the button in the mobile application,  the new hospital will show in the view of our mobile application.&lt;br /&gt;
&lt;br /&gt;
[[File:synchronization.gif]]&lt;br /&gt;
&lt;br /&gt;
Another synchronization work is to submit forms from Mobile Client to Eden Server, as the picture below shows. Here we created a new shelter on Mobile Client and then clickec &amp;quot;Save&amp;quot;, from the GIF we can see that the Mobile Client displayed the newly created shelter, then after refreshing the Eden Server, the shelter is showed int the server side too.&lt;br /&gt;
&lt;br /&gt;
==Add Multilanguage Support==&lt;br /&gt;
===Development-before preparation===&lt;br /&gt;
This program is hosted by a very experienced software engineering, who set the blueprint of this whole program. So we communicated with him serval times to get a better understanding of the project need and expectation. Also, he introduced the framework he used and showed some little tricky to us on google group discussion. Then we understand a mapping relationship and the implementation details about how to build a multilanguage support.&lt;br /&gt;
&lt;br /&gt;
[[File:mapping.png]]&lt;br /&gt;
&lt;br /&gt;
===Code Changes===&lt;br /&gt;
The html button changes in languages.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
        events: {&lt;br /&gt;
            &amp;quot;click #Chinese-button&amp;quot;: &amp;quot;onChinese&amp;quot;,&lt;br /&gt;
            &amp;quot;click #Bosnian-button&amp;quot;: &amp;quot;onBosnian&amp;quot;,&lt;br /&gt;
            &amp;quot;click #French-button&amp;quot;: &amp;quot;onFrench&amp;quot;,&lt;br /&gt;
             &amp;quot;click #English-button&amp;quot;: &amp;quot;onEnglish&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onChinese: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onChinese &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onChinese();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onEnglish: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onEnglish &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onEnglish();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onBosnian: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onBosnian();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onFrench: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);&lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onFrench();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The html button changes in languagesController.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.init = function (options) {&lt;br /&gt;
        $(&amp;quot;#Chinese-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onChinese.bind(this));&lt;br /&gt;
        $(&amp;quot;#Bosnian-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onBosnian.bind(this));&lt;br /&gt;
        $(&amp;quot;#French-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onFrench.bind(this));&lt;br /&gt;
        $(&amp;quot;#English-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onEnglish.bind(this));&lt;br /&gt;
        app.controller.setControllerByModel(&amp;quot;languages&amp;quot;, this);&lt;br /&gt;
    };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.onChinese = function(evt) {&lt;br /&gt;
        app.onChinese();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onBosnian = function(evt) {&lt;br /&gt;
        app.onBosnian();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onFrench = function(evt) {&lt;br /&gt;
        app.onFrench();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onEnglish = function(evt) {&lt;br /&gt;
        app.onEnglish();&lt;br /&gt;
    };&lt;br /&gt;
    app.pluginManager.addObject(controller);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code changes in index.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onChinese: function(){&lt;br /&gt;
        this.controller.translate();&lt;br /&gt;
    },&lt;br /&gt;
    onBosnian: function(){&lt;br /&gt;
        this.controller.translateToBosnian();&lt;br /&gt;
    },&lt;br /&gt;
    onFrench: function(){&lt;br /&gt;
        this.controller.translateToFrench();&lt;br /&gt;
    },&lt;br /&gt;
    onEnglish: function(){&lt;br /&gt;
        this.controller.translateToEnglish();&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our basic implementation translation in controller.js function goes like this: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.translate = function(){&lt;br /&gt;
    var language = 'Chinese';&lt;br /&gt;
    //alert(&amp;quot;asd&amp;quot;);&lt;br /&gt;
    $.ajax({&lt;br /&gt;
        url: 'languages.xml',&lt;br /&gt;
        success: function(xml) {&lt;br /&gt;
            $(xml).find('translation').each(function(){&lt;br /&gt;
                var id = $(this).attr('id');&lt;br /&gt;
&lt;br /&gt;
                var text = $(this).find(language).text();&lt;br /&gt;
                $(&amp;quot;.&amp;quot; + id).html(text);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
    }&lt;br /&gt;
The rest omitted //&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
languages.xml mapping information: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;translations&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;translation&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Hello there, how are you?&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;你好&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Zdravo&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Bonjour&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Shelter&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Shelter Name&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;避难所名称&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;sklonište&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;nom de l'abri&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Street Address&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;地址&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;adresa&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;adresse&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Postcode&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Postcode&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮编&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;poštanski broj&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;code postal&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Phone&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Phone&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;电话&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;telefon&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;téléphone&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Email&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Email&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮箱&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;E-mail&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;E-mail&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Population&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Estimated Population&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;受灾人口&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;la population touchée&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Day&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Evacuees Capacity (Day and Night)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（全天）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije (Dan i noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(Jour et nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Night&amp;quot;&amp;gt;&amp;lt;english&amp;gt;Evacuees Capacity (Night only)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（夜晚）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije(noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;primjedba&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Shelter1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Raleigh Rescue Mission&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;罗利市救援中心&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Raleigh Grad U pomoć centar&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Raliegh ville Aidez-Moi centre&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;314 E Hargett St&lt;br /&gt;
Raleigh, NC&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;北卡州罗利市东哈格特街314号&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;314 istok hargett ulica Raleigh Grad,sjever Karolina&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;314 est hargett rue Raleigh ville, nord caroline&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
   &amp;lt;!-- &amp;lt;translation id=&amp;quot;Postcode1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;27601&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;27601&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Phone1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;919.828.9014&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;919.828.9014&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;--&amp;gt;s&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;No Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;无备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Bez Napomene&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;aucun commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&amp;lt;/translations&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Multilanguage UI===&lt;br /&gt;
After serval times of discussion and communication, we finally realize the following UI. You can click the language you need to change to it. It's very easy-using and user comfortable. The following screenshot is what it looks like.&lt;br /&gt;
&lt;br /&gt;
After clicking the English button, the English UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:English.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Chinese button, the Chinese UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Chinese.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the French button, the French UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:French.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Bosnian button, the Bosnian UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Bosnian.png]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
1. When loading Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Error1.png‎  |frame|center|underscore-min.map not found error]]&lt;br /&gt;
&lt;br /&gt;
The problem can be solved by downloading the file [https://github.com/jashkenas/underscore/blob/master/underscore-min.map underscore-min.map] and put it in the directory where underscore-min.js is stored. More information about this error can be found [http://stackoverflow.com/questions/18429625/missing-javascript-map-file-for-underscore-js-when-loading-asp-net-web-page here].&lt;br /&gt;
&lt;br /&gt;
2. When adding multi-language module to Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
After adding a language plugin module, users can see a new button called &amp;quot;Language&amp;quot;, but it cannot be clicked and what makes worse is that the module affect other modules, for example, we cannot new a shelter. The framework is super complex and we are new here. After discussion, we write a email describing our problems to Tom Baker, the host developer, for help.&lt;br /&gt;
&lt;br /&gt;
[[File:problem.png]] &lt;br /&gt;
&lt;br /&gt;
After we received his short reply, we tried to follow his instruction to check some files but still get no idea what's our problem.&lt;br /&gt;
&lt;br /&gt;
[[File:reply.png]]&lt;br /&gt;
&lt;br /&gt;
Finally, we set breakpoints and used chrome's developer tool to help us debug. Fortunately, we found the an object is NULL, which affect the initiation. Then we found that in our controller there is a little error which leaded to this problem. After revised that, it run well now.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96924</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96924"/>
		<updated>2015-04-24T03:18:07Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Synchronization between server and local mobile application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. Sahana Eden Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot; style=&amp;quot;float:{{{align|right}}}&amp;quot;&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; |[[File:SahanaLogo.png|center|Sahana]]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project aims at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to add new shelters and hospitals, get information of hospitals and shelters offline/online, get GPS location of device, and provide multilingual support.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &lt;br /&gt;
&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/ Sahana Eden Instroduction]&amp;lt;/ref&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
*Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
*To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
*Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://docs.google.com/a/ncsu.edu/document/d/11bblC7klisYjN7Gjw6hDcs5TZ8uesJD3o2xnM2gI914/edit# overview of all the Sahana Eden projects]&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Edenmobile Introduction]&amp;lt;/ref&amp;gt;  &lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile#J2ME list] of all the requirements need to be done in this project. &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*[https://github.com/szhao8/eden Open source code about Sahana Eden]&amp;lt;ref&amp;gt;[https://github.com/szhao8/eden Sahana Eden Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
*[https://github.com/szhao8/EdenMobile Open source code about Eden Mobile]&amp;lt;ref&amp;gt;[https://github.com/szhao8/EdenMobile EdenMobile Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
&lt;br /&gt;
Below is the overview of the Eden Mobile Platform. It uses a Model-View-Controller design pattern as the foundation of the project. And it also introduces a &amp;quot;plugin&amp;quot; mechanism, from which developers can add new modules (pages) to the main menu by adding them to &amp;quot;plugins&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Architecture.png |frame‎|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
==Use Cases==&lt;br /&gt;
&lt;br /&gt;
* '''1. Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''2. Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''3. Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''4. Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''5. Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''6. Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
==Login==&lt;br /&gt;
&lt;br /&gt;
The Sahana Eden website already has a login page, so our initial thought is to find the web service URL for login function, and use it in our log in page on Sahana Mobile. After scrutinize the python code of Sahana Eden, we found the login url, which is &amp;quot;localhost:8000/eden/default/user/login?_next=%2Feden%2Fdefault%2Findex&amp;quot;, then we use this URL as the post destination and created the login page as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Login.png]]&lt;br /&gt;
&lt;br /&gt;
However, if we input the correct login information and then click &amp;quot;login&amp;quot; to post our login request, we will be redirected to the Sahana Eden's original login page, rather than log into the system, as the following picture shows. Unfortunately, we have found a solution to this problem.&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_LoginAfter.png]]&lt;br /&gt;
&lt;br /&gt;
==Hospital plugin==&lt;br /&gt;
===Customize hospital form===&lt;br /&gt;
According to the [http://pastebin.com/Gj6nEnSu create.s3json file] in the hospital module on the official website, we create the hospital form in the Eden mobile application.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    var editHospitalForm = [&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;name&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;,&lt;br /&gt;
            required: true&lt;br /&gt;
        },&lt;br /&gt;
        ///*&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;aka1&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;code&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;facility_type&amp;quot;,&lt;br /&gt;
            control: &amp;quot;integer&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;organisation_id&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;L0&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            common_name: &amp;quot;Country&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_street&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_postcode&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;location&amp;quot;,&lt;br /&gt;
            control: &amp;quot;gis_button&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;address&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;postcode&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;city&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        }, &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_exchange&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_business&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },    &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_emergency&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;website&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;email&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },   &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;fax&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;obsolete&amp;quot;,&lt;br /&gt;
            control: &amp;quot;checkbox&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;footer&amp;quot;,&lt;br /&gt;
            control: &amp;quot;text&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Synchronization between server and local mobile application===&lt;br /&gt;
Utilizing the framework provided by the developer, we realized to synchronize hospital data from server to the local mobile application. You can see what we did in the following image. We create a new hospital name Hospital in the Sahana, after clicking the &amp;quot;save&amp;quot; button, the new hospital is saved in the server. Then if we click the &amp;quot;refresh list&amp;quot; the button in the mobile application,  the new hospital will show in the view of our mobile application.&lt;br /&gt;
&lt;br /&gt;
[[File:synchronization.gif]]&lt;br /&gt;
&lt;br /&gt;
==Add Multilanguage Support==&lt;br /&gt;
===Development-before preparation===&lt;br /&gt;
This program is hosted by a very experienced software engineering, who set the blueprint of this whole program. So we communicated with him serval times to get a better understanding of the project need and expectation. Also, he introduced the framework he used and showed some little tricky to us on google group discussion. Then we understand a mapping relationship and the implementation details about how to build a multilanguage support.&lt;br /&gt;
&lt;br /&gt;
[[File:mapping.png]]&lt;br /&gt;
&lt;br /&gt;
===Code Changes===&lt;br /&gt;
The html button changes in languages.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
        events: {&lt;br /&gt;
            &amp;quot;click #Chinese-button&amp;quot;: &amp;quot;onChinese&amp;quot;,&lt;br /&gt;
            &amp;quot;click #Bosnian-button&amp;quot;: &amp;quot;onBosnian&amp;quot;,&lt;br /&gt;
            &amp;quot;click #French-button&amp;quot;: &amp;quot;onFrench&amp;quot;,&lt;br /&gt;
             &amp;quot;click #English-button&amp;quot;: &amp;quot;onEnglish&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onChinese: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onChinese &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onChinese();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onEnglish: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onEnglish &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onEnglish();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onBosnian: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onBosnian();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onFrench: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);&lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onFrench();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The html button changes in languagesController.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.init = function (options) {&lt;br /&gt;
        $(&amp;quot;#Chinese-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onChinese.bind(this));&lt;br /&gt;
        $(&amp;quot;#Bosnian-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onBosnian.bind(this));&lt;br /&gt;
        $(&amp;quot;#French-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onFrench.bind(this));&lt;br /&gt;
        $(&amp;quot;#English-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onEnglish.bind(this));&lt;br /&gt;
        app.controller.setControllerByModel(&amp;quot;languages&amp;quot;, this);&lt;br /&gt;
    };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.onChinese = function(evt) {&lt;br /&gt;
        app.onChinese();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onBosnian = function(evt) {&lt;br /&gt;
        app.onBosnian();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onFrench = function(evt) {&lt;br /&gt;
        app.onFrench();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onEnglish = function(evt) {&lt;br /&gt;
        app.onEnglish();&lt;br /&gt;
    };&lt;br /&gt;
    app.pluginManager.addObject(controller);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code changes in index.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onChinese: function(){&lt;br /&gt;
        this.controller.translate();&lt;br /&gt;
    },&lt;br /&gt;
    onBosnian: function(){&lt;br /&gt;
        this.controller.translateToBosnian();&lt;br /&gt;
    },&lt;br /&gt;
    onFrench: function(){&lt;br /&gt;
        this.controller.translateToFrench();&lt;br /&gt;
    },&lt;br /&gt;
    onEnglish: function(){&lt;br /&gt;
        this.controller.translateToEnglish();&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our basic implementation translation in controller.js function goes like this: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.translate = function(){&lt;br /&gt;
    var language = 'Chinese';&lt;br /&gt;
    //alert(&amp;quot;asd&amp;quot;);&lt;br /&gt;
    $.ajax({&lt;br /&gt;
        url: 'languages.xml',&lt;br /&gt;
        success: function(xml) {&lt;br /&gt;
            $(xml).find('translation').each(function(){&lt;br /&gt;
                var id = $(this).attr('id');&lt;br /&gt;
&lt;br /&gt;
                var text = $(this).find(language).text();&lt;br /&gt;
                $(&amp;quot;.&amp;quot; + id).html(text);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
    }&lt;br /&gt;
The rest omitted //&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
languages.xml mapping information: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;translations&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;translation&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Hello there, how are you?&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;你好&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Zdravo&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Bonjour&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Shelter&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Shelter Name&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;避难所名称&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;sklonište&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;nom de l'abri&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Street Address&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;地址&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;adresa&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;adresse&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Postcode&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Postcode&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮编&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;poštanski broj&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;code postal&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Phone&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Phone&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;电话&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;telefon&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;téléphone&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Email&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Email&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮箱&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;E-mail&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;E-mail&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Population&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Estimated Population&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;受灾人口&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;la population touchée&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Day&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Evacuees Capacity (Day and Night)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（全天）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije (Dan i noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(Jour et nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Night&amp;quot;&amp;gt;&amp;lt;english&amp;gt;Evacuees Capacity (Night only)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（夜晚）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije(noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;primjedba&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Shelter1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Raleigh Rescue Mission&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;罗利市救援中心&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Raleigh Grad U pomoć centar&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Raliegh ville Aidez-Moi centre&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;314 E Hargett St&lt;br /&gt;
Raleigh, NC&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;北卡州罗利市东哈格特街314号&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;314 istok hargett ulica Raleigh Grad,sjever Karolina&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;314 est hargett rue Raleigh ville, nord caroline&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
   &amp;lt;!-- &amp;lt;translation id=&amp;quot;Postcode1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;27601&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;27601&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Phone1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;919.828.9014&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;919.828.9014&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;--&amp;gt;s&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;No Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;无备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Bez Napomene&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;aucun commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&amp;lt;/translations&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Multilanguage UI===&lt;br /&gt;
After serval times of discussion and communication, we finally realize the following UI. You can click the language you need to change to it. It's very easy-using and user comfortable. The following screenshot is what it looks like.&lt;br /&gt;
&lt;br /&gt;
After clicking the English button, the English UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:English.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Chinese button, the Chinese UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Chinese.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the French button, the French UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:French.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Bosnian button, the Bosnian UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Bosnian.png]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
1. When loading Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Error1.png‎  |frame|center|underscore-min.map not found error]]&lt;br /&gt;
&lt;br /&gt;
The problem can be solved by downloading the file [https://github.com/jashkenas/underscore/blob/master/underscore-min.map underscore-min.map] and put it in the directory where underscore-min.js is stored. More information about this error can be found [http://stackoverflow.com/questions/18429625/missing-javascript-map-file-for-underscore-js-when-loading-asp-net-web-page here].&lt;br /&gt;
&lt;br /&gt;
2. When adding multi-language module to Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
After adding a language plugin module, users can see a new button called &amp;quot;Language&amp;quot;, but it cannot be clicked and what makes worse is that the module affect other modules, for example, we cannot new a shelter. The framework is super complex and we are new here. After discussion, we write a email describing our problems to Tom Baker, the host developer, for help.&lt;br /&gt;
&lt;br /&gt;
[[File:problem.png]] &lt;br /&gt;
&lt;br /&gt;
After we received his short reply, we tried to follow his instruction to check some files but still get no idea what's our problem.&lt;br /&gt;
&lt;br /&gt;
[[File:reply.png]]&lt;br /&gt;
&lt;br /&gt;
Finally, we set breakpoints and used chrome's developer tool to help us debug. Fortunately, we found the an object is NULL, which affect the initiation. Then we found that in our controller there is a little error which leaded to this problem. After revised that, it run well now.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96914</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96914"/>
		<updated>2015-04-24T02:57:57Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Login */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. Sahana Eden Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot; style=&amp;quot;float:{{{align|right}}}&amp;quot;&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; |[[File:SahanaLogo.png|center|Sahana]]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project aims at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to add new shelters and hospitals, get information of hospitals and shelters offline/online, get GPS location of device, and provide multilingual support.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &lt;br /&gt;
&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/ Sahana Eden Instroduction]&amp;lt;/ref&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
*Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
*To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
*Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://docs.google.com/a/ncsu.edu/document/d/11bblC7klisYjN7Gjw6hDcs5TZ8uesJD3o2xnM2gI914/edit# overview of all the Sahana Eden projects]&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Edenmobile Introduction]&amp;lt;/ref&amp;gt;  &lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile#J2ME list] of all the requirements need to be done in this project. &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*[https://github.com/szhao8/eden Open source code about Sahana Eden]&amp;lt;ref&amp;gt;[https://github.com/szhao8/eden Sahana Eden Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
*[https://github.com/szhao8/EdenMobile Open source code about Eden Mobile]&amp;lt;ref&amp;gt;[https://github.com/szhao8/EdenMobile EdenMobile Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
&lt;br /&gt;
Below is the overview of the Eden Mobile Platform. It uses a Model-View-Controller design pattern as the foundation of the project. And it also introduces a &amp;quot;plugin&amp;quot; mechanism, from which developers can add new modules (pages) to the main menu by adding them to &amp;quot;plugins&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Architecture.png |frame‎|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
==Use Cases==&lt;br /&gt;
&lt;br /&gt;
* '''1. Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''2. Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''3. Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''4. Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''5. Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''6. Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
==Login==&lt;br /&gt;
&lt;br /&gt;
The Sahana Eden website already has a login page, so our initial thought is to find the web service URL for login function, and use it in our log in page on Sahana Mobile. After scrutinize the python code of Sahana Eden, we found the login url, which is &amp;quot;localhost:8000/eden/default/user/login?_next=%2Feden%2Fdefault%2Findex&amp;quot;, then we use this URL as the post destination and created the login page as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Login.jpg]]&lt;br /&gt;
&lt;br /&gt;
However, if we input the correct login information and then click &amp;quot;login&amp;quot; to post our login request, we will be redirected to the Sahana Eden's original login page, rather than log into the system, as the following picture shows. Unfortunately, we have found a solution to this problem.&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_LoginAfter.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Hospital plugin==&lt;br /&gt;
===Customize hospital form===&lt;br /&gt;
According to the [http://pastebin.com/Gj6nEnSu create.s3json file] in the hospital module on the official website, we create the hospital form in the Eden mobile application.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    var editHospitalForm = [&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;name&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;,&lt;br /&gt;
            required: true&lt;br /&gt;
        },&lt;br /&gt;
        ///*&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;aka1&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;code&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;facility_type&amp;quot;,&lt;br /&gt;
            control: &amp;quot;integer&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;organisation_id&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;L0&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            common_name: &amp;quot;Country&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_street&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_postcode&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;location&amp;quot;,&lt;br /&gt;
            control: &amp;quot;gis_button&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;address&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;postcode&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;city&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        }, &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_exchange&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_business&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },    &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_emergency&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;website&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;email&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },   &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;fax&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;obsolete&amp;quot;,&lt;br /&gt;
            control: &amp;quot;checkbox&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;footer&amp;quot;,&lt;br /&gt;
            control: &amp;quot;text&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Synchronization between server and local mobile application===&lt;br /&gt;
Utilizing the framework provided by the developer, we realized to synchronize hospital data from server to the local mobile application. You can see what we did in the following image. We create a new hospital name Hospital in the Sahana, after clicking the &amp;quot;save&amp;quot; button, the new hospital is saved in the server. Then if we click the &amp;quot;refresh list&amp;quot; the button in the mobile application,  the new hospital will show in the view of our mobile application.&lt;br /&gt;
&lt;br /&gt;
[[File:synchronization.gif]]&lt;br /&gt;
&lt;br /&gt;
==Add Multilanguage Support==&lt;br /&gt;
===Development-before preparation===&lt;br /&gt;
This program is hosted by a very experienced software engineering, who set the blueprint of this whole program. So we communicated with him serval times to get a better understanding of the project need and expectation. Also, he introduced the framework he used and showed some little tricky to us on google group discussion. Then we understand a mapping relationship and the implementation details about how to build a multilanguage support.&lt;br /&gt;
&lt;br /&gt;
[[File:mapping.png]]&lt;br /&gt;
&lt;br /&gt;
===Code Changes===&lt;br /&gt;
The html button changes in languages.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
        events: {&lt;br /&gt;
            &amp;quot;click #Chinese-button&amp;quot;: &amp;quot;onChinese&amp;quot;,&lt;br /&gt;
            &amp;quot;click #Bosnian-button&amp;quot;: &amp;quot;onBosnian&amp;quot;,&lt;br /&gt;
            &amp;quot;click #French-button&amp;quot;: &amp;quot;onFrench&amp;quot;,&lt;br /&gt;
             &amp;quot;click #English-button&amp;quot;: &amp;quot;onEnglish&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onChinese: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onChinese &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onChinese();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onEnglish: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onEnglish &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onEnglish();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onBosnian: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onBosnian();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onFrench: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);&lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onFrench();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The html button changes in languagesController.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.init = function (options) {&lt;br /&gt;
        $(&amp;quot;#Chinese-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onChinese.bind(this));&lt;br /&gt;
        $(&amp;quot;#Bosnian-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onBosnian.bind(this));&lt;br /&gt;
        $(&amp;quot;#French-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onFrench.bind(this));&lt;br /&gt;
        $(&amp;quot;#English-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onEnglish.bind(this));&lt;br /&gt;
        app.controller.setControllerByModel(&amp;quot;languages&amp;quot;, this);&lt;br /&gt;
    };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.onChinese = function(evt) {&lt;br /&gt;
        app.onChinese();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onBosnian = function(evt) {&lt;br /&gt;
        app.onBosnian();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onFrench = function(evt) {&lt;br /&gt;
        app.onFrench();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onEnglish = function(evt) {&lt;br /&gt;
        app.onEnglish();&lt;br /&gt;
    };&lt;br /&gt;
    app.pluginManager.addObject(controller);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code changes in index.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onChinese: function(){&lt;br /&gt;
        this.controller.translate();&lt;br /&gt;
    },&lt;br /&gt;
    onBosnian: function(){&lt;br /&gt;
        this.controller.translateToBosnian();&lt;br /&gt;
    },&lt;br /&gt;
    onFrench: function(){&lt;br /&gt;
        this.controller.translateToFrench();&lt;br /&gt;
    },&lt;br /&gt;
    onEnglish: function(){&lt;br /&gt;
        this.controller.translateToEnglish();&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our basic implementation translation in controller.js function goes like this: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.translate = function(){&lt;br /&gt;
    var language = 'Chinese';&lt;br /&gt;
    //alert(&amp;quot;asd&amp;quot;);&lt;br /&gt;
    $.ajax({&lt;br /&gt;
        url: 'languages.xml',&lt;br /&gt;
        success: function(xml) {&lt;br /&gt;
            $(xml).find('translation').each(function(){&lt;br /&gt;
                var id = $(this).attr('id');&lt;br /&gt;
&lt;br /&gt;
                var text = $(this).find(language).text();&lt;br /&gt;
                $(&amp;quot;.&amp;quot; + id).html(text);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
    }&lt;br /&gt;
The rest omitted //&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
languages.xml mapping information: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;translations&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;translation&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Hello there, how are you?&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;你好&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Zdravo&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Bonjour&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Shelter&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Shelter Name&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;避难所名称&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;sklonište&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;nom de l'abri&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Street Address&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;地址&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;adresa&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;adresse&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Postcode&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Postcode&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮编&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;poštanski broj&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;code postal&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Phone&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Phone&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;电话&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;telefon&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;téléphone&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Email&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Email&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮箱&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;E-mail&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;E-mail&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Population&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Estimated Population&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;受灾人口&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;la population touchée&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Day&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Evacuees Capacity (Day and Night)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（全天）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije (Dan i noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(Jour et nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Night&amp;quot;&amp;gt;&amp;lt;english&amp;gt;Evacuees Capacity (Night only)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（夜晚）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije(noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;primjedba&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Shelter1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Raleigh Rescue Mission&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;罗利市救援中心&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Raleigh Grad U pomoć centar&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Raliegh ville Aidez-Moi centre&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;314 E Hargett St&lt;br /&gt;
Raleigh, NC&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;北卡州罗利市东哈格特街314号&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;314 istok hargett ulica Raleigh Grad,sjever Karolina&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;314 est hargett rue Raleigh ville, nord caroline&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
   &amp;lt;!-- &amp;lt;translation id=&amp;quot;Postcode1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;27601&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;27601&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Phone1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;919.828.9014&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;919.828.9014&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;--&amp;gt;s&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;No Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;无备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Bez Napomene&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;aucun commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&amp;lt;/translations&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Multilanguage UI===&lt;br /&gt;
After serval times of discussion and communication, we finally realize the following UI. You can click the language you need to change to it. It's very easy-using and user comfortable. The following screenshot is what it looks like.&lt;br /&gt;
&lt;br /&gt;
After clicking the English button, the English UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:English.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Chinese button, the Chinese UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Chinese.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the French button, the French UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:French.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Bosnian button, the Bosnian UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Bosnian.png]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
1. When loading Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Error1.png‎  |frame|center|underscore-min.map not found error]]&lt;br /&gt;
&lt;br /&gt;
The problem can be solved by downloading the file [https://github.com/jashkenas/underscore/blob/master/underscore-min.map underscore-min.map] and put it in the directory where underscore-min.js is stored. More information about this error can be found [http://stackoverflow.com/questions/18429625/missing-javascript-map-file-for-underscore-js-when-loading-asp-net-web-page here].&lt;br /&gt;
&lt;br /&gt;
2. When adding multi-language module to Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
After adding a language plugin module, users can see a new button called &amp;quot;Language&amp;quot;, but it cannot be clicked and what makes worse is that the module affect other modules, for example, we cannot new a shelter. The framework is super complex and we are new here. After discussion, we write a email describing our problems to Tom Baker, the host developer, for help.&lt;br /&gt;
&lt;br /&gt;
[[File:problem.png]] &lt;br /&gt;
&lt;br /&gt;
After we received his short reply, we tried to follow his instruction to check some files but still get no idea what's our problem.&lt;br /&gt;
&lt;br /&gt;
[[File:reply.png]]&lt;br /&gt;
&lt;br /&gt;
Finally, we set breakpoints and used chrome's developer tool to help us debug. Fortunately, we found the an object is NULL, which affect the initiation. Then we found that in our controller there is a little error which leaded to this problem. After revised that, it run well now.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96913</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96913"/>
		<updated>2015-04-24T02:47:47Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Login */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. Sahana Eden Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot; style=&amp;quot;float:{{{align|right}}}&amp;quot;&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; |[[File:SahanaLogo.png|center|Sahana]]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project aims at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to add new shelters and hospitals, get information of hospitals and shelters offline/online, get GPS location of device, and provide multilingual support.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &lt;br /&gt;
&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/ Sahana Eden Instroduction]&amp;lt;/ref&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
*Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
*To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
*Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://docs.google.com/a/ncsu.edu/document/d/11bblC7klisYjN7Gjw6hDcs5TZ8uesJD3o2xnM2gI914/edit# overview of all the Sahana Eden projects]&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Edenmobile Introduction]&amp;lt;/ref&amp;gt;  &lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile#J2ME list] of all the requirements need to be done in this project. &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*[https://github.com/szhao8/eden Open source code about Sahana Eden]&amp;lt;ref&amp;gt;[https://github.com/szhao8/eden Sahana Eden Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
*[https://github.com/szhao8/EdenMobile Open source code about Eden Mobile]&amp;lt;ref&amp;gt;[https://github.com/szhao8/EdenMobile EdenMobile Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
&lt;br /&gt;
Below is the overview of the Eden Mobile Platform. It uses a Model-View-Controller design pattern as the foundation of the project. And it also introduces a &amp;quot;plugin&amp;quot; mechanism, from which developers can add new modules (pages) to the main menu by adding them to &amp;quot;plugins&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Architecture.png |frame‎|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
==Use Cases==&lt;br /&gt;
&lt;br /&gt;
* '''1. Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''2. Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''3. Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''4. Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''5. Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''6. Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
==Login==&lt;br /&gt;
&lt;br /&gt;
The Sahana Eden website already has a login page, so our initial thought is to find the web service URL for login function, and use it in our log in page on Sahana Mobile. After scrutinize the python code of Sahana Eden, we found the login url, which is &amp;quot;localhost:8000/eden/default/user/login?_next=%2Feden%2Fdefault%2Findex&amp;quot;, then we use this URL as the post destination and created the login page as follows:&lt;br /&gt;
&lt;br /&gt;
==Hospital plugin==&lt;br /&gt;
===Customize hospital form===&lt;br /&gt;
According to the [http://pastebin.com/Gj6nEnSu create.s3json file] in the hospital module on the official website, we create the hospital form in the Eden mobile application.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    var editHospitalForm = [&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;name&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;,&lt;br /&gt;
            required: true&lt;br /&gt;
        },&lt;br /&gt;
        ///*&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;aka1&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;code&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;facility_type&amp;quot;,&lt;br /&gt;
            control: &amp;quot;integer&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;organisation_id&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;L0&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            common_name: &amp;quot;Country&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_street&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_postcode&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;location&amp;quot;,&lt;br /&gt;
            control: &amp;quot;gis_button&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;address&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;postcode&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;city&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        }, &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_exchange&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_business&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },    &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_emergency&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;website&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;email&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },   &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;fax&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;obsolete&amp;quot;,&lt;br /&gt;
            control: &amp;quot;checkbox&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;footer&amp;quot;,&lt;br /&gt;
            control: &amp;quot;text&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Synchronization between server and local mobile application===&lt;br /&gt;
Utilizing the framework provided by the developer, we realized to synchronize hospital data from server to the local mobile application. You can see what we did in the following image. We create a new hospital name Hospital in the Sahana, after clicking the &amp;quot;save&amp;quot; button, the new hospital is saved in the server. Then if we click the &amp;quot;refresh list&amp;quot; the button in the mobile application,  the new hospital will show in the view of our mobile application.&lt;br /&gt;
&lt;br /&gt;
[[File:synchronization.gif]]&lt;br /&gt;
&lt;br /&gt;
==Add Multilanguage Support==&lt;br /&gt;
===Development-before preparation===&lt;br /&gt;
This program is hosted by a very experienced software engineering, who set the blueprint of this whole program. So we communicated with him serval times to get a better understanding of the project need and expectation. Also, he introduced the framework he used and showed some little tricky to us on google group discussion. Then we understand a mapping relationship and the implementation details about how to build a multilanguage support.&lt;br /&gt;
&lt;br /&gt;
[[File:mapping.png]]&lt;br /&gt;
&lt;br /&gt;
===Code Changes===&lt;br /&gt;
The html button changes in languages.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
        events: {&lt;br /&gt;
            &amp;quot;click #Chinese-button&amp;quot;: &amp;quot;onChinese&amp;quot;,&lt;br /&gt;
            &amp;quot;click #Bosnian-button&amp;quot;: &amp;quot;onBosnian&amp;quot;,&lt;br /&gt;
            &amp;quot;click #French-button&amp;quot;: &amp;quot;onFrench&amp;quot;,&lt;br /&gt;
             &amp;quot;click #English-button&amp;quot;: &amp;quot;onEnglish&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onChinese: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onChinese &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onChinese();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onEnglish: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onEnglish &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onEnglish();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onBosnian: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onBosnian();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onFrench: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);&lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onFrench();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The html button changes in languagesController.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.init = function (options) {&lt;br /&gt;
        $(&amp;quot;#Chinese-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onChinese.bind(this));&lt;br /&gt;
        $(&amp;quot;#Bosnian-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onBosnian.bind(this));&lt;br /&gt;
        $(&amp;quot;#French-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onFrench.bind(this));&lt;br /&gt;
        $(&amp;quot;#English-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onEnglish.bind(this));&lt;br /&gt;
        app.controller.setControllerByModel(&amp;quot;languages&amp;quot;, this);&lt;br /&gt;
    };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.onChinese = function(evt) {&lt;br /&gt;
        app.onChinese();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onBosnian = function(evt) {&lt;br /&gt;
        app.onBosnian();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onFrench = function(evt) {&lt;br /&gt;
        app.onFrench();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onEnglish = function(evt) {&lt;br /&gt;
        app.onEnglish();&lt;br /&gt;
    };&lt;br /&gt;
    app.pluginManager.addObject(controller);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code changes in index.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onChinese: function(){&lt;br /&gt;
        this.controller.translate();&lt;br /&gt;
    },&lt;br /&gt;
    onBosnian: function(){&lt;br /&gt;
        this.controller.translateToBosnian();&lt;br /&gt;
    },&lt;br /&gt;
    onFrench: function(){&lt;br /&gt;
        this.controller.translateToFrench();&lt;br /&gt;
    },&lt;br /&gt;
    onEnglish: function(){&lt;br /&gt;
        this.controller.translateToEnglish();&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our basic implementation translation in controller.js function goes like this: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.translate = function(){&lt;br /&gt;
    var language = 'Chinese';&lt;br /&gt;
    //alert(&amp;quot;asd&amp;quot;);&lt;br /&gt;
    $.ajax({&lt;br /&gt;
        url: 'languages.xml',&lt;br /&gt;
        success: function(xml) {&lt;br /&gt;
            $(xml).find('translation').each(function(){&lt;br /&gt;
                var id = $(this).attr('id');&lt;br /&gt;
&lt;br /&gt;
                var text = $(this).find(language).text();&lt;br /&gt;
                $(&amp;quot;.&amp;quot; + id).html(text);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
    }&lt;br /&gt;
The rest omitted //&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
languages.xml mapping information: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;translations&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;translation&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Hello there, how are you?&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;你好&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Zdravo&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Bonjour&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Shelter&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Shelter Name&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;避难所名称&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;sklonište&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;nom de l'abri&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Street Address&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;地址&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;adresa&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;adresse&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Postcode&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Postcode&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮编&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;poštanski broj&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;code postal&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Phone&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Phone&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;电话&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;telefon&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;téléphone&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Email&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Email&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮箱&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;E-mail&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;E-mail&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Population&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Estimated Population&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;受灾人口&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;la population touchée&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Day&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Evacuees Capacity (Day and Night)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（全天）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije (Dan i noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(Jour et nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Night&amp;quot;&amp;gt;&amp;lt;english&amp;gt;Evacuees Capacity (Night only)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（夜晚）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije(noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;primjedba&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Shelter1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Raleigh Rescue Mission&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;罗利市救援中心&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Raleigh Grad U pomoć centar&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Raliegh ville Aidez-Moi centre&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;314 E Hargett St&lt;br /&gt;
Raleigh, NC&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;北卡州罗利市东哈格特街314号&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;314 istok hargett ulica Raleigh Grad,sjever Karolina&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;314 est hargett rue Raleigh ville, nord caroline&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
   &amp;lt;!-- &amp;lt;translation id=&amp;quot;Postcode1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;27601&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;27601&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Phone1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;919.828.9014&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;919.828.9014&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;--&amp;gt;s&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;No Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;无备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Bez Napomene&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;aucun commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&amp;lt;/translations&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Multilanguage UI===&lt;br /&gt;
After serval times of discussion and communication, we finally realize the following UI. You can click the language you need to change to it. It's very easy-using and user comfortable. The following screenshot is what it looks like.&lt;br /&gt;
&lt;br /&gt;
After clicking the English button, the English UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:English.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Chinese button, the Chinese UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Chinese.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the French button, the French UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:French.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Bosnian button, the Bosnian UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Bosnian.png]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
1. When loading Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Error1.png‎  |frame|center|underscore-min.map not found error]]&lt;br /&gt;
&lt;br /&gt;
The problem can be solved by downloading the file [https://github.com/jashkenas/underscore/blob/master/underscore-min.map underscore-min.map] and put it in the directory where underscore-min.js is stored. More information about this error can be found [http://stackoverflow.com/questions/18429625/missing-javascript-map-file-for-underscore-js-when-loading-asp-net-web-page here].&lt;br /&gt;
&lt;br /&gt;
2. When adding multi-language module to Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
After adding a language plugin module, users can see a new button called &amp;quot;Language&amp;quot;, but it cannot be clicked and what makes worse is that the module affect other modules, for example, we cannot new a shelter. The framework is super complex and we are new here. After discussion, we write a email describing our problems to Tom Baker, the host developer, for help.&lt;br /&gt;
&lt;br /&gt;
[[File:problem.png]] &lt;br /&gt;
&lt;br /&gt;
After we received his short reply, we tried to follow his instruction to check some files but still get no idea what's our problem.&lt;br /&gt;
&lt;br /&gt;
[[File:reply.png]]&lt;br /&gt;
&lt;br /&gt;
Finally, we set breakpoints and used chrome's developer tool to help us debug. Fortunately, we found the an object is NULL, which affect the initiation. Then we found that in our controller there is a little error which leaded to this problem. After revised that, it run well now.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96909</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96909"/>
		<updated>2015-04-24T02:35:55Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. Sahana Eden Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot; style=&amp;quot;float:{{{align|right}}}&amp;quot;&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; |[[File:SahanaLogo.png|center|Sahana]]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project aims at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to add new shelters and hospitals, get information of hospitals and shelters offline/online, get GPS location of device, and provide multilingual support.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &lt;br /&gt;
&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/ Sahana Eden Instroduction]&amp;lt;/ref&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
*Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
*To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
*Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://docs.google.com/a/ncsu.edu/document/d/11bblC7klisYjN7Gjw6hDcs5TZ8uesJD3o2xnM2gI914/edit# overview of all the Sahana Eden projects]&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Edenmobile Introduction]&amp;lt;/ref&amp;gt;  &lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile#J2ME list] of all the requirements need to be done in this project. &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*[https://github.com/szhao8/eden Open source code about Sahana Eden]&amp;lt;ref&amp;gt;[https://github.com/szhao8/eden Sahana Eden Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
*[https://github.com/szhao8/EdenMobile Open source code about Eden Mobile]&amp;lt;ref&amp;gt;[https://github.com/szhao8/EdenMobile EdenMobile Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
&lt;br /&gt;
Below is the overview of the Eden Mobile Platform. It uses a Model-View-Controller design pattern as the foundation of the project. And it also introduces a &amp;quot;plugin&amp;quot; mechanism, from which developers can add new modules (pages) to the main menu by adding them to &amp;quot;plugins&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Architecture.png |frame‎|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
==Use Cases==&lt;br /&gt;
&lt;br /&gt;
* '''1. Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''2. Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''3. Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''4. Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''5. Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''6. Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
==Login==&lt;br /&gt;
==Hospital plugin==&lt;br /&gt;
===Customize hospital form===&lt;br /&gt;
According to the [http://pastebin.com/Gj6nEnSu create.s3json file] in the hospital module on the official website, we create the hospital form in the Eden mobile application.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    var editHospitalForm = [&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;name&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;,&lt;br /&gt;
            required: true&lt;br /&gt;
        },&lt;br /&gt;
        ///*&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;aka1&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;code&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;facility_type&amp;quot;,&lt;br /&gt;
            control: &amp;quot;integer&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;organisation_id&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;L0&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            common_name: &amp;quot;Country&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_street&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_postcode&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;location&amp;quot;,&lt;br /&gt;
            control: &amp;quot;gis_button&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;address&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;postcode&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;city&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        }, &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_exchange&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_business&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },    &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_emergency&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;website&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;email&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },   &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;fax&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;obsolete&amp;quot;,&lt;br /&gt;
            control: &amp;quot;checkbox&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;footer&amp;quot;,&lt;br /&gt;
            control: &amp;quot;text&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Media:[[Media:Example.ogg]][[Media:Example.ogg]]]]&lt;br /&gt;
&lt;br /&gt;
==Add Multilanguage Support==&lt;br /&gt;
===Development-before preparation===&lt;br /&gt;
This program is hosted by a very experienced software engineering, who set the blueprint of this whole program. So we communicated with him serval times to get a better understanding of the project need and expectation. Also, he introduced the framework he used and showed some little tricky to us on google group discussion. Then we understand a mapping relationship and the implementation details about how to build a multilanguage support.&lt;br /&gt;
&lt;br /&gt;
[[File:mapping.png]]&lt;br /&gt;
&lt;br /&gt;
===Code Changes===&lt;br /&gt;
The html button changes in languages.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
        events: {&lt;br /&gt;
            &amp;quot;click #Chinese-button&amp;quot;: &amp;quot;onChinese&amp;quot;,&lt;br /&gt;
            &amp;quot;click #Bosnian-button&amp;quot;: &amp;quot;onBosnian&amp;quot;,&lt;br /&gt;
            &amp;quot;click #French-button&amp;quot;: &amp;quot;onFrench&amp;quot;,&lt;br /&gt;
             &amp;quot;click #English-button&amp;quot;: &amp;quot;onEnglish&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onChinese: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onChinese &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onChinese();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onEnglish: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onEnglish &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onEnglish();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onBosnian: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onBosnian();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onFrench: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);&lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onFrench();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The html button changes in languagesController.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.init = function (options) {&lt;br /&gt;
        $(&amp;quot;#Chinese-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onChinese.bind(this));&lt;br /&gt;
        $(&amp;quot;#Bosnian-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onBosnian.bind(this));&lt;br /&gt;
        $(&amp;quot;#French-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onFrench.bind(this));&lt;br /&gt;
        $(&amp;quot;#English-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onEnglish.bind(this));&lt;br /&gt;
        app.controller.setControllerByModel(&amp;quot;languages&amp;quot;, this);&lt;br /&gt;
    };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.onChinese = function(evt) {&lt;br /&gt;
        app.onChinese();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onBosnian = function(evt) {&lt;br /&gt;
        app.onBosnian();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onFrench = function(evt) {&lt;br /&gt;
        app.onFrench();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onEnglish = function(evt) {&lt;br /&gt;
        app.onEnglish();&lt;br /&gt;
    };&lt;br /&gt;
    app.pluginManager.addObject(controller);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code changes in index.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onChinese: function(){&lt;br /&gt;
        this.controller.translate();&lt;br /&gt;
    },&lt;br /&gt;
    onBosnian: function(){&lt;br /&gt;
        this.controller.translateToBosnian();&lt;br /&gt;
    },&lt;br /&gt;
    onFrench: function(){&lt;br /&gt;
        this.controller.translateToFrench();&lt;br /&gt;
    },&lt;br /&gt;
    onEnglish: function(){&lt;br /&gt;
        this.controller.translateToEnglish();&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our basic implementation translation in controller.js function goes like this: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.translate = function(){&lt;br /&gt;
    var language = 'Chinese';&lt;br /&gt;
    //alert(&amp;quot;asd&amp;quot;);&lt;br /&gt;
    $.ajax({&lt;br /&gt;
        url: 'languages.xml',&lt;br /&gt;
        success: function(xml) {&lt;br /&gt;
            $(xml).find('translation').each(function(){&lt;br /&gt;
                var id = $(this).attr('id');&lt;br /&gt;
&lt;br /&gt;
                var text = $(this).find(language).text();&lt;br /&gt;
                $(&amp;quot;.&amp;quot; + id).html(text);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
    }&lt;br /&gt;
The rest omitted //&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
languages.xml mapping information: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;translations&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;translation&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Hello there, how are you?&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;你好&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Zdravo&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Bonjour&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Shelter&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Shelter Name&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;避难所名称&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;sklonište&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;nom de l'abri&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Street Address&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;地址&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;adresa&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;adresse&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Postcode&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Postcode&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮编&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;poštanski broj&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;code postal&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Phone&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Phone&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;电话&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;telefon&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;téléphone&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Email&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Email&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮箱&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;E-mail&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;E-mail&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Population&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Estimated Population&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;受灾人口&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;la population touchée&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Day&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Evacuees Capacity (Day and Night)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（全天）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije (Dan i noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(Jour et nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Night&amp;quot;&amp;gt;&amp;lt;english&amp;gt;Evacuees Capacity (Night only)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（夜晚）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije(noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;primjedba&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Shelter1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Raleigh Rescue Mission&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;罗利市救援中心&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Raleigh Grad U pomoć centar&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Raliegh ville Aidez-Moi centre&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;314 E Hargett St&lt;br /&gt;
Raleigh, NC&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;北卡州罗利市东哈格特街314号&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;314 istok hargett ulica Raleigh Grad,sjever Karolina&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;314 est hargett rue Raleigh ville, nord caroline&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
   &amp;lt;!-- &amp;lt;translation id=&amp;quot;Postcode1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;27601&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;27601&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Phone1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;919.828.9014&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;919.828.9014&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;--&amp;gt;s&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;No Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;无备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Bez Napomene&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;aucun commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&amp;lt;/translations&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Multilanguage UI===&lt;br /&gt;
After serval times of discussion and communication, we finally realize the following UI. You can click the language you need to change to it. It's very easy-using and user comfortable. The following screenshot is what it looks like.&lt;br /&gt;
&lt;br /&gt;
After clicking the English button, the English UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:English.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Chinese button, the Chinese UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Chinese.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the French button, the French UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:French.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Bosnian button, the Bosnian UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Bosnian.png]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
1. When loading Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Error1.png‎  |frame|center|underscore-min.map not found error]]&lt;br /&gt;
&lt;br /&gt;
The problem can be solved by downloading the file [https://github.com/jashkenas/underscore/blob/master/underscore-min.map underscore-min.map] and put it in the directory where underscore-min.js is stored. More information about this error can be found [http://stackoverflow.com/questions/18429625/missing-javascript-map-file-for-underscore-js-when-loading-asp-net-web-page here].&lt;br /&gt;
&lt;br /&gt;
2. When adding multi-language module to Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
After adding a language plugin module, users can see a new button called &amp;quot;Language&amp;quot;, but it cannot be clicked and what makes worse is that the module affect other modules, for example, we cannot new a shelter. The framework is super complex and we are new here. After discussion, we write a email describing our problems to Tom Baker, the host developer, for help.&lt;br /&gt;
&lt;br /&gt;
[[File:problem.png]] &lt;br /&gt;
&lt;br /&gt;
After we received his short reply, we tried to follow his instruction to check some files but still get no idea what's our problem.&lt;br /&gt;
&lt;br /&gt;
[[File:reply.png]]&lt;br /&gt;
&lt;br /&gt;
Finally, we set breakpoints and used chrome's developer tool to help us debug. Fortunately, we found the an object is NULL, which affect the initiation. Then we found that in our controller there is a little error which leaded to this problem. After revised that, it run well now.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96905</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96905"/>
		<updated>2015-04-24T02:04:49Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. Sahana Eden Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot; style=&amp;quot;float:{{{align|right}}}&amp;quot;&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; |[[File:SahanaLogo.png|center|Sahana]]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project aims at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to add new shelters and hospitals, get information of hospitals and shelters offline/online, get GPS location of device, and provide multilingual support.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &lt;br /&gt;
&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/ Sahana Eden Instroduction]&amp;lt;/ref&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
*Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
*To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
*Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://docs.google.com/a/ncsu.edu/document/d/11bblC7klisYjN7Gjw6hDcs5TZ8uesJD3o2xnM2gI914/edit# overview of all the Sahana Eden projects]&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Edenmobile Introduction]&amp;lt;/ref&amp;gt;  &lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile#J2ME list] of all the requirements need to be done in this project. &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*[https://github.com/szhao8/eden Open source code about Sahana Eden]&amp;lt;ref&amp;gt;[https://github.com/szhao8/eden Sahana Eden Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
*[https://github.com/szhao8/EdenMobile Open source code about Eden Mobile]&amp;lt;ref&amp;gt;[https://github.com/szhao8/EdenMobile EdenMobile Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
&lt;br /&gt;
Below is the overview of the Eden Mobile Platform. It uses a Model-View-Controller design pattern as the foundation of the project. And it also introduces a &amp;quot;plugin&amp;quot; mechanism, from which developers can add new modules (pages) to the main menu by adding them to &amp;quot;plugins&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Architecture.png |frame‎|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
==Use Cases==&lt;br /&gt;
&lt;br /&gt;
* '''1. Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''2. Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''3. Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''4. Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''5. Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''6. Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
==Hospital plugin==&lt;br /&gt;
===Customize hospital form===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    var editHospitalForm = [&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;name&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;,&lt;br /&gt;
            required: true&lt;br /&gt;
        },&lt;br /&gt;
        ///*&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;aka1&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;code&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;facility_type&amp;quot;,&lt;br /&gt;
            control: &amp;quot;integer&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
            form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;organisation_id&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;L0&amp;quot;,&lt;br /&gt;
            control: &amp;quot;select&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            common_name: &amp;quot;Country&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_street&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;addr_postcode&amp;quot;,&lt;br /&gt;
            control: &amp;quot;string&amp;quot;,&lt;br /&gt;
            form_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            data_path: &amp;quot;$_gis_location/field&amp;quot;,&lt;br /&gt;
            reference: &amp;quot;$k_location_id&amp;quot;,&lt;br /&gt;
            form: &amp;quot;gis-location-form&amp;quot;,&lt;br /&gt;
            label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;location&amp;quot;,&lt;br /&gt;
            control: &amp;quot;gis_button&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;address&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;postcode&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;city&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        }, &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_exchange&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_business&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },    &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;phone_emergency&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;website&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;email&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },   &lt;br /&gt;
        {&lt;br /&gt;
             name: &amp;quot;fax&amp;quot;,&lt;br /&gt;
             control: &amp;quot;string&amp;quot;,&lt;br /&gt;
             form_path: &amp;quot;$_hms_hospital/field&amp;quot;,&lt;br /&gt;
             form: &amp;quot;hospital-form&amp;quot;,&lt;br /&gt;
             label: &amp;quot;&amp;quot;&lt;br /&gt;
        },  &lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;obsolete&amp;quot;,&lt;br /&gt;
            control: &amp;quot;checkbox&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;footer&amp;quot;,&lt;br /&gt;
            control: &amp;quot;text&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Add Multilanguage Support==&lt;br /&gt;
===Development-before preparation===&lt;br /&gt;
This program is hosted by a very experienced software engineering, who set the blueprint of this whole program. So we communicated with him serval times to get a better understanding of the project need and expectation. Also, he introduced the framework he used and showed some little tricky to us on google group discussion. Then we understand a mapping relationship and the implementation details about how to build a multilanguage support.&lt;br /&gt;
&lt;br /&gt;
[[File:mapping.png]]&lt;br /&gt;
&lt;br /&gt;
===Code Changes===&lt;br /&gt;
The html button changes in languages.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
        events: {&lt;br /&gt;
            &amp;quot;click #Chinese-button&amp;quot;: &amp;quot;onChinese&amp;quot;,&lt;br /&gt;
            &amp;quot;click #Bosnian-button&amp;quot;: &amp;quot;onBosnian&amp;quot;,&lt;br /&gt;
            &amp;quot;click #French-button&amp;quot;: &amp;quot;onFrench&amp;quot;,&lt;br /&gt;
             &amp;quot;click #English-button&amp;quot;: &amp;quot;onEnglish&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onChinese: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onChinese &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onChinese();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onEnglish: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onEnglish &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onEnglish();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onBosnian: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onBosnian();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onFrench: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);&lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onFrench();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The html button changes in languagesController.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.init = function (options) {&lt;br /&gt;
        $(&amp;quot;#Chinese-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onChinese.bind(this));&lt;br /&gt;
        $(&amp;quot;#Bosnian-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onBosnian.bind(this));&lt;br /&gt;
        $(&amp;quot;#French-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onFrench.bind(this));&lt;br /&gt;
        $(&amp;quot;#English-button&amp;quot;).on(&amp;quot;click&amp;quot;,this.onEnglish.bind(this));&lt;br /&gt;
        app.controller.setControllerByModel(&amp;quot;languages&amp;quot;, this);&lt;br /&gt;
    };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.onChinese = function(evt) {&lt;br /&gt;
        app.onChinese();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onBosnian = function(evt) {&lt;br /&gt;
        app.onBosnian();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onFrench = function(evt) {&lt;br /&gt;
        app.onFrench();&lt;br /&gt;
    };&lt;br /&gt;
    controller.prototype.onEnglish = function(evt) {&lt;br /&gt;
        app.onEnglish();&lt;br /&gt;
    };&lt;br /&gt;
    app.pluginManager.addObject(controller);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code changes in index.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onChinese: function(){&lt;br /&gt;
        this.controller.translate();&lt;br /&gt;
    },&lt;br /&gt;
    onBosnian: function(){&lt;br /&gt;
        this.controller.translateToBosnian();&lt;br /&gt;
    },&lt;br /&gt;
    onFrench: function(){&lt;br /&gt;
        this.controller.translateToFrench();&lt;br /&gt;
    },&lt;br /&gt;
    onEnglish: function(){&lt;br /&gt;
        this.controller.translateToEnglish();&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our basic implementation translation in controller.js function goes like this: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    controller.prototype.translate = function(){&lt;br /&gt;
    var language = 'Chinese';&lt;br /&gt;
    //alert(&amp;quot;asd&amp;quot;);&lt;br /&gt;
    $.ajax({&lt;br /&gt;
        url: 'languages.xml',&lt;br /&gt;
        success: function(xml) {&lt;br /&gt;
            $(xml).find('translation').each(function(){&lt;br /&gt;
                var id = $(this).attr('id');&lt;br /&gt;
&lt;br /&gt;
                var text = $(this).find(language).text();&lt;br /&gt;
                $(&amp;quot;.&amp;quot; + id).html(text);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
    }&lt;br /&gt;
The rest omitted //&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
languages.xml mapping information: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;translations&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;translation&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Hello there, how are you?&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;你好&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Zdravo&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Bonjour&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Shelter&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Shelter Name&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;避难所名称&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;sklonište&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;nom de l'abri&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Street Address&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;地址&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;adresa&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;adresse&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Postcode&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Postcode&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮编&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;poštanski broj&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;code postal&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Phone&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Phone&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;电话&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;telefon&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;téléphone&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
        &amp;lt;translation id=&amp;quot;Email&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Email&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;邮箱&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;E-mail&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;E-mail&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Population&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Estimated Population&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;受灾人口&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;la population touchée&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Day&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Evacuees Capacity (Day and Night)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（全天）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije (Dan i noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(Jour et nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Night&amp;quot;&amp;gt;&amp;lt;english&amp;gt;Evacuees Capacity (Night only)&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;容纳能力（夜晚）&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;pogođene populacije(noć)&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Capacité évacués(nuit)&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;primjedba&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Shelter1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;Raleigh Rescue Mission&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;罗利市救援中心&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Raleigh Grad U pomoć centar&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;Raliegh ville Aidez-Moi centre&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Address1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;314 E Hargett St&lt;br /&gt;
Raleigh, NC&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;北卡州罗利市东哈格特街314号&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;314 istok hargett ulica Raleigh Grad,sjever Karolina&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;314 est hargett rue Raleigh ville, nord caroline&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
   &amp;lt;!-- &amp;lt;translation id=&amp;quot;Postcode1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;27601&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;27601&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Phone1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;919.828.9014&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;919.828.9014&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;--&amp;gt;s&lt;br /&gt;
    &amp;lt;translation id=&amp;quot;Comments1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;english&amp;gt;No Comments&amp;lt;/english&amp;gt;&lt;br /&gt;
        &amp;lt;Chinese&amp;gt;无备注&amp;lt;/Chinese&amp;gt;&lt;br /&gt;
        &amp;lt;Bosnian&amp;gt;Bez Napomene&amp;lt;/Bosnian&amp;gt;&lt;br /&gt;
        &amp;lt;French&amp;gt;aucun commentaire&amp;lt;/French&amp;gt;&lt;br /&gt;
    &amp;lt;/translation&amp;gt;&lt;br /&gt;
&amp;lt;/translations&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Multilanguage UI===&lt;br /&gt;
After serval times of discussion and communication, we finally realize the following UI. You can click the language you need to change to it. It's very easy-using and user comfortable. The following screenshot is what it looks like.&lt;br /&gt;
&lt;br /&gt;
After clicking the English button, the English UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:English.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Chinese button, the Chinese UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Chinese.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the French button, the French UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:French.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Bosnian button, the Bosnian UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Bosnian.png]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
1. When loading Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Error1.png‎  |frame|center|underscore-min.map not found error]]&lt;br /&gt;
&lt;br /&gt;
The problem can be solved by downloading the file [https://github.com/jashkenas/underscore/blob/master/underscore-min.map underscore-min.map] and put it in the directory where underscore-min.js is stored. More information about this error can be found [http://stackoverflow.com/questions/18429625/missing-javascript-map-file-for-underscore-js-when-loading-asp-net-web-page here].&lt;br /&gt;
&lt;br /&gt;
2. When adding multi-language module to Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
After adding a language plugin module, users can see a new button called &amp;quot;Language&amp;quot;, but it cannot be clicked and what makes worse is that the module affect other modules, for example, we cannot new a shelter. The framework is super complex and we are new here. After discussion, we write a email describing our problems to Tom Baker, the host developer, for help.&lt;br /&gt;
&lt;br /&gt;
[[File:problem.png]] &lt;br /&gt;
&lt;br /&gt;
After we received his short reply, we tried to follow his instruction to check some files but still get no idea what's our problem.&lt;br /&gt;
&lt;br /&gt;
[[File:reply.png]]&lt;br /&gt;
&lt;br /&gt;
Finally, we set breakpoints and used chrome's developer tool to help us debug. Fortunately, we found the an object is NULL, which affect the initiation. Then we found that in our controller there is a little error which leaded to this problem. After revised that, it run well now.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96876</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96876"/>
		<updated>2015-04-24T00:41:24Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Architecture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. Sahana Eden Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project aims at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to add new shelters and hospitals, get information of hospitals and shelters offline/online, get GPS location of device, and provide multilingual support.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &lt;br /&gt;
&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/ Sahana Eden Instroduction]&amp;lt;/ref&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
*Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
*To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
*Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://docs.google.com/a/ncsu.edu/document/d/11bblC7klisYjN7Gjw6hDcs5TZ8uesJD3o2xnM2gI914/edit# overview of all the Sahana Eden projects]&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source&amp;lt;ref&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Edenmobile Introduction]&amp;lt;/ref&amp;gt;  &lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile#J2ME list] of all the requirements need to be done in this project. &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*[https://github.com/szhao8/eden Open source code about Sahana Eden]&amp;lt;ref&amp;gt;[https://github.com/szhao8/eden Sahana Eden Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
*[https://github.com/szhao8/EdenMobile Open source code about Eden Mobile]&amp;lt;ref&amp;gt;[https://github.com/szhao8/EdenMobile EdenMobile Github]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
&lt;br /&gt;
Below is the overview of the Eden Mobile Platform. It uses a Model-View-Controller design pattern as the foundation of the project. And it also introduces a &amp;quot;plugin&amp;quot; mechanism, from which developers can add new modules (pages) to the main menu by adding them to &amp;quot;plugins&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Architecture.png |frame‎|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
==Use Cases==&lt;br /&gt;
&lt;br /&gt;
* '''1. Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''2. Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''3. Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''4. Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''5. Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* '''6. Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
==Add Multilanguage Support==&lt;br /&gt;
===Development-before preparation===&lt;br /&gt;
This program is hosted by a very experienced software engineering, who set the blueprint of this whole program. So we communicated with him serval times to get a better understanding of the project need and expectation. Also, he introduced the framework he used and showed some little tricky to us on google group discussion. Then we understand a mapping relationship and the implementation details about how to build a multilanguage support.&lt;br /&gt;
&lt;br /&gt;
[[File:mapping.png]]&lt;br /&gt;
&lt;br /&gt;
===Code Changes===&lt;br /&gt;
The html button changes in languages.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
        events: {&lt;br /&gt;
            &amp;quot;click #Chinese-button&amp;quot;: &amp;quot;onChinese&amp;quot;,&lt;br /&gt;
            &amp;quot;click #Bosnian-button&amp;quot;: &amp;quot;onBosnian&amp;quot;,&lt;br /&gt;
            &amp;quot;click #French-button&amp;quot;: &amp;quot;onFrench&amp;quot;,&lt;br /&gt;
             &amp;quot;click #English-button&amp;quot;: &amp;quot;onEnglish&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onChinese: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onChinese &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onChinese();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onEnglish: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onEnglish &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onEnglish();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onBosnian: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);       &lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onBosnian();&lt;br /&gt;
            } &lt;br /&gt;
        },&lt;br /&gt;
        onFrench: function (event) {&lt;br /&gt;
            console.log(&amp;quot;onBosnian &amp;quot;);&lt;br /&gt;
            var controller = app.controller.getControllerByModel(&amp;quot;languages&amp;quot;);&lt;br /&gt;
            if (controller) {&lt;br /&gt;
                controller.onFrench();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The html button changes in languagesController.js:&lt;br /&gt;
&lt;br /&gt;
[[File:languagecontroller.png]]&lt;br /&gt;
&lt;br /&gt;
Code changes in index.js:&lt;br /&gt;
&lt;br /&gt;
[[File:index.png]]&lt;br /&gt;
&lt;br /&gt;
Our basic implementation translation in controller.js function goes like this: &lt;br /&gt;
&lt;br /&gt;
[[File:basic.png]]&lt;br /&gt;
&lt;br /&gt;
languages.xml mapping information: &lt;br /&gt;
&lt;br /&gt;
[[File:xml.png]]&lt;br /&gt;
&lt;br /&gt;
===Multilanguage UI===&lt;br /&gt;
After serval times of discussion and communication, we finally realize the following UI. You can click the language you need to change to it. It's very easy-using and user comfortable. The following screenshot is what it looks like.&lt;br /&gt;
&lt;br /&gt;
After clicking the English button, the English UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:English.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Chinese button, the Chinese UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Chinese.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the French button, the French UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:French.png]]&lt;br /&gt;
&lt;br /&gt;
After clicking the Bosnian button, the Bosnian UI shows as following:&lt;br /&gt;
&lt;br /&gt;
[[File:Bosnian.png]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
1. When loading Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Error1.png‎  |frame|center|underscore-min.map not found error]]&lt;br /&gt;
&lt;br /&gt;
The problem can be solved by downloading the file [https://github.com/jashkenas/underscore/blob/master/underscore-min.map underscore-min.map] and put it in the directory where underscore-min.js is stored. More information about this error can be found [http://stackoverflow.com/questions/18429625/missing-javascript-map-file-for-underscore-js-when-loading-asp-net-web-page here].&lt;br /&gt;
&lt;br /&gt;
2. When adding multi-language module to Sahana Eden Mobile's main page, browser console will print the following error message:&lt;br /&gt;
After adding a language plugin module, users can see a new button called &amp;quot;Language&amp;quot;, but it cannot be clicked and what makes worse is that the module affect other modules, for example, we cannot new a shelter. The framework is super complex and we are new here. After discussion, we write a email describing our problems to Tom Baker, the host developer, for help.&lt;br /&gt;
&lt;br /&gt;
[[File:problem.png]] &lt;br /&gt;
&lt;br /&gt;
After we received his short reply, we tried to follow his instruction to check some files but still get no idea what's our problem.&lt;br /&gt;
&lt;br /&gt;
[[File:reply.png]]&lt;br /&gt;
&lt;br /&gt;
Finally, we set breakpoints and used chrome's developer tool to help us debug. Fortunately, we found the an object is NULL, which affect the initiation. Then we found that in our controller there is a little error which leaded to this problem. After revised that, it run well now.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96309</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96309"/>
		<updated>2015-04-01T02:26:31Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Sahana Eden Architecture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
*Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
*To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
*Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source  &lt;br /&gt;
* [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
==Use Case==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96307</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96307"/>
		<updated>2015-04-01T02:26:02Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Sahana Eden Architecture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
*Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
*To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
*Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows&amp;lt;ref&amp;gt;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source  &lt;br /&gt;
* [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
==Use Case==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96299</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96299"/>
		<updated>2015-04-01T02:21:17Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* What does Sahana Eden do? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
*Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
*To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
*Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source  &lt;br /&gt;
* [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
==Use Case==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96296</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96296"/>
		<updated>2015-04-01T02:20:38Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Background */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''&amp;lt;br&amp;gt;	&lt;br /&gt;
*Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
*Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source  &lt;br /&gt;
* [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
==Use Case==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96286</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96286"/>
		<updated>2015-04-01T02:16:22Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''	&amp;lt;br&amp;gt;	&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source  &lt;br /&gt;
* [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96283</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96283"/>
		<updated>2015-04-01T02:15:25Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* What does Sahana Eden do? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html &amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;hospitalController.js (controller)&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mVehicles.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (views)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;vehiclesController.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (controller)&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;config.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''	&amp;lt;br&amp;gt;	&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;				&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Documentation===&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction] about the framework of Edenmobile including application design, source  &lt;br /&gt;
* [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96267</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96267"/>
		<updated>2015-04-01T02:07:06Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* What does Sahana Eden do? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html (views)&lt;br /&gt;
*hospitalController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*mVehicles.js (model)&lt;br /&gt;
*vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html (views)&lt;br /&gt;
*vehiclesController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''	&amp;lt;br&amp;gt;	&lt;br /&gt;
  Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;						&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
  Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
    There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
    Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
    Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
    Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
    To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
    Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
    When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
    Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Documentation===&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;, explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; about the framework of Edenmobile including application design, source  &lt;br /&gt;
* &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96261</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96261"/>
		<updated>2015-04-01T02:05:57Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* What does Sahana Eden do? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;communication.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;controller.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;model.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;view.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*&amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;mHospital.js&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; (model)&lt;br /&gt;
*hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html (views)&lt;br /&gt;
*hospitalController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*mVehicles.js (model)&lt;br /&gt;
*vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html (views)&lt;br /&gt;
*vehiclesController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''	&amp;lt;br&amp;gt;	&lt;br /&gt;
    Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;						&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
    Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
    There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
    Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
    Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
    Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
    To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
    Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
    When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
    Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Documentation===&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;, explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; about the framework of Edenmobile including application design, source  &lt;br /&gt;
* &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
==Overview==&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
==Requirements==&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96245</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96245"/>
		<updated>2015-04-01T01:58:15Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Background */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Purpose===&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
===Scope===&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*communication.js&lt;br /&gt;
*controller.js&lt;br /&gt;
*model.js&lt;br /&gt;
*view.js&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*mHospital.js (model)&lt;br /&gt;
*hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html (views)&lt;br /&gt;
*hospitalController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*mVehicles.js (model)&lt;br /&gt;
*vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html (views)&lt;br /&gt;
*vehiclesController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
===Background===&lt;br /&gt;
====What’s Sahana Eden?==== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====What does Sahana Eden do?==== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''	&amp;lt;br&amp;gt;	&lt;br /&gt;
Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;						&lt;br /&gt;
'''Project Tracking'''&amp;lt;br&amp;gt;&lt;br /&gt;
Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Human Resources'''&amp;lt;br&amp;gt;	&lt;br /&gt;
There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Inventory'''&amp;lt;br&amp;gt;&lt;br /&gt;
Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Assets'''&amp;lt;br&amp;gt;&lt;br /&gt;
Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
'''Assessments'''&amp;lt;br&amp;gt;											&lt;br /&gt;
Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Scenarios &amp;amp; Events'''&amp;lt;br&amp;gt;&lt;br /&gt;
To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Map'''&amp;lt;br&amp;gt;									&lt;br /&gt;
Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Shelter Management'''&amp;lt;br&amp;gt;	&lt;br /&gt;
When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Messaging'''&amp;lt;br&amp;gt;&lt;br /&gt;
Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
====Sahana Eden Architecture====&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Documentation====&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;, explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; about the framework of Edenmobile including application design, source  &lt;br /&gt;
* &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Design===&lt;br /&gt;
=====Overview=====&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
=====Requirements=====&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
===Architecture===&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96243</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96243"/>
		<updated>2015-04-01T01:55:37Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Background */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Purpose===&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
===Scope===&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*communication.js&lt;br /&gt;
*controller.js&lt;br /&gt;
*model.js&lt;br /&gt;
*view.js&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*mHospital.js (model)&lt;br /&gt;
*hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html (views)&lt;br /&gt;
*hospitalController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*mVehicles.js (model)&lt;br /&gt;
*vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html (views)&lt;br /&gt;
*vehiclesController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
===Background===&lt;br /&gt;
====What’s Sahana Eden?==== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====What does Sahana Eden do?==== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
'''Organization Registry'''		&lt;br /&gt;
Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;						&lt;br /&gt;
'''Project Tracking'''&lt;br /&gt;
Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
=====Human Resources=====		&lt;br /&gt;
There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
=====Inventory=====		&lt;br /&gt;
Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
=====Assets=====&lt;br /&gt;
Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
=====Assessments=====											&lt;br /&gt;
Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
=====Scenarios &amp;amp; Events=====&lt;br /&gt;
To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
=====Map=====									&lt;br /&gt;
Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
=====Shelter Management=====		&lt;br /&gt;
When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
=====Messaging=====&lt;br /&gt;
Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
=====Sahana Eden Architecture=====&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Documentation====&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;, explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; about the framework of Edenmobile including application design, source  &lt;br /&gt;
* &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Design===&lt;br /&gt;
=====Overview=====&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
=====Requirements=====&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
===Architecture===&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96241</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96241"/>
		<updated>2015-04-01T01:54:51Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Background */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;big&amp;gt;S1503. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Purpose===&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
===Scope===&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*communication.js&lt;br /&gt;
*controller.js&lt;br /&gt;
*model.js&lt;br /&gt;
*view.js&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*mHospital.js (model)&lt;br /&gt;
*hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html (views)&lt;br /&gt;
*hospitalController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*mVehicles.js (model)&lt;br /&gt;
*vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html (views)&lt;br /&gt;
*vehiclesController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
===Background===&lt;br /&gt;
====What’s Sahana Eden?==== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====What does Sahana Eden do?==== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
*Organization Registry		&lt;br /&gt;
Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;						&lt;br /&gt;
*Project Tracking&lt;br /&gt;
Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
=====Human Resources=====		&lt;br /&gt;
There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
=====Inventory=====		&lt;br /&gt;
Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
=====Assets=====&lt;br /&gt;
Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
=====Assessments=====											&lt;br /&gt;
Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
=====Scenarios &amp;amp; Events=====&lt;br /&gt;
To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
=====Map=====									&lt;br /&gt;
Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
=====Shelter Management=====		&lt;br /&gt;
When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
=====Messaging=====&lt;br /&gt;
Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
====Sahana Eden Architecture====&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Documentation===&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;, explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; about the framework of Edenmobile including application design, source  &lt;br /&gt;
* &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
====Overview====&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
====Requirements===&lt;br /&gt;
The major requirements are that:&lt;br /&gt;
*Secure login;&lt;br /&gt;
*Multiple languages;&lt;br /&gt;
*users are able to work offline, and update forms and content when online;&lt;br /&gt;
*The initial forms that will be implemented are Hospitals, and Shelters;&lt;br /&gt;
&lt;br /&gt;
===Architecture===&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* The UML use case diagram is shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:S1503_Usecase.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96226</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96226"/>
		<updated>2015-04-01T01:35:07Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Background */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;big&amp;gt;E1526. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
This project is aimed at adding new functions to the EdenMobile client app to serve users better.These functions will allow mobile users to realize functions like&lt;br /&gt;
adding new shelters and hospitals, observing the list of hospitals and shelters both offline and online ,passing users' location to the nearest medical facilities and realizing a multilingual environment. &lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*communication.js&lt;br /&gt;
*controller.js&lt;br /&gt;
*model.js&lt;br /&gt;
*view.js&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*mHospital.js (model)&lt;br /&gt;
*hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html (views)&lt;br /&gt;
*hospitalController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Vehicles:&lt;br /&gt;
*mVehicles.js (model)&lt;br /&gt;
*vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html (views)&lt;br /&gt;
*vehiclesController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
===Organization Registry===			&lt;br /&gt;
Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;						&lt;br /&gt;
====Project Tracking====&lt;br /&gt;
Sahana Eden provides a valuable tool which could tell people what are going on about the project to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
====Human Resources====		&lt;br /&gt;
There are contact lists in Sahana Eden  which can be access by users to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
====Inventory====		&lt;br /&gt;
Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
====Assets====&lt;br /&gt;
Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
====Assessments====											&lt;br /&gt;
Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
====Scenarios &amp;amp; Events====&lt;br /&gt;
To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
====Map	====									&lt;br /&gt;
Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
====Shelter Management====		&lt;br /&gt;
When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
====Messaging====&lt;br /&gt;
Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;, explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt; about the framework of Edenmobile including application design, source  &lt;br /&gt;
* &amp;lt;strong&amp;gt;&amp;lt;i&amp;gt;[http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework Source code]&amp;lt;/i&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
===Overview===&lt;br /&gt;
In this design, we add several modules to the EdenMobile client app to allow mobile users to add new shelters and hospitals. Also, users can see the list of hospitals and shelters both offline and online and we can pass users' location to the nearest medical facilities. At last, a multilingual environment is also supported.&lt;br /&gt;
===Requirements===&lt;br /&gt;
&lt;br /&gt;
===Architecture===&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Security Log in'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills login form, which includes username, password and Captcha code.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to Sahana Server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User fills forms of shelter/warehouse/disaster etc.&lt;br /&gt;
*** Submit form to local database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Download new forms from server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #5: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Synchronize local data with server&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #6: Multi-Language Support '''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** Choose a language from settings page&lt;br /&gt;
&lt;br /&gt;
[[File:TO_BE_ADDED.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96203</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96203"/>
		<updated>2015-04-01T00:54:37Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Sahana Eden Architecture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;big&amp;gt;E1526. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
To add several modules to the EdenMobile client app based on the web2py framework to allow mobile users to add new shelters and hospitals,  to see the list of hospitals and shelters both offline and online and pass their location to the nearest medical facilities. &lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*communication.js&lt;br /&gt;
*controller.js&lt;br /&gt;
*model.js&lt;br /&gt;
*view.js&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*mHospital.js (model)&lt;br /&gt;
*hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html (views)&lt;br /&gt;
*hospitalController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin&lt;br /&gt;
Vehicles:&lt;br /&gt;
*mVehicles.js (model)&lt;br /&gt;
*vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html (views)&lt;br /&gt;
*vehiclesController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
===Organization Registry===			&lt;br /&gt;
Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;						&lt;br /&gt;
====Project Tracking====&lt;br /&gt;
By telling you Who’s Doing What, Where, and When, Sahana Eden provides a valuable tool to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
====Human Resources====		&lt;br /&gt;
Sahana Eden can also be used to provide a contact list to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
====Inventory====		&lt;br /&gt;
Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
====Assets====&lt;br /&gt;
Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
====Assessments====											&lt;br /&gt;
Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
====Scenarios &amp;amp; Events====&lt;br /&gt;
To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
====Map	====									&lt;br /&gt;
Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
====Shelter Management====		&lt;br /&gt;
When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
====Messaging====&lt;br /&gt;
Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
The basic Sahana Eden architecture is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: 1px dotted rgb(0, 0, 0); border-collapse: collapse;&amp;quot; cellpadding=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Server&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Apache&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Other web servers can also be used, such as Cherokee.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Application&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Sahana Eden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Web Application Framework&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Web2Py&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Programming Language&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Python &amp;amp;amp; Java Script&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Database&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;MySQL, PostgreSQL, or SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;p&amp;gt;MySQL, PostgreSQL, and SQLite are supported.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Other databases should be usable without major additional work since Web2Py supplies many connectors.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Operating System&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Linux (Debian recommended)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border: 1px dotted rgb(0, 0, 0);&amp;quot;&amp;gt;Windows and Mac OS X are possible, but only recommended for single-user environments.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
* An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction about the framework of Edenmobile including application design, source ] &lt;br /&gt;
Source code&lt;br /&gt;
http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills .&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** A.&lt;br /&gt;
*** B.&lt;br /&gt;
*** C.&lt;br /&gt;
*** D.&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** A.&lt;br /&gt;
*** B.&lt;br /&gt;
*** C.&lt;br /&gt;
*** D.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** A.&lt;br /&gt;
*** B.&lt;br /&gt;
*** C.&lt;br /&gt;
*** D.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:TO_BE_ADDED.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96202</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96202"/>
		<updated>2015-04-01T00:51:23Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* What’s Sahana Eden? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;big&amp;gt;E1526. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
To add several modules to the EdenMobile client app based on the web2py framework to allow mobile users to add new shelters and hospitals,  to see the list of hospitals and shelters both offline and online and pass their location to the nearest medical facilities. &lt;br /&gt;
==Scope==&lt;br /&gt;
We will realize the signup, secure login and logout function, which would add new module into the following files&lt;br /&gt;
*communication.js&lt;br /&gt;
*controller.js&lt;br /&gt;
*model.js&lt;br /&gt;
*view.js&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&amp;lt;br&amp;gt;&lt;br /&gt;
Hospitals:&lt;br /&gt;
*mHospital.js (model)&lt;br /&gt;
*hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html (views)&lt;br /&gt;
*hospitalController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin&lt;br /&gt;
Vehicles:&lt;br /&gt;
*mVehicles.js (model)&lt;br /&gt;
*vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html (views)&lt;br /&gt;
*vehiclesController.js (controller)&lt;br /&gt;
*config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What does Sahana Eden do?=== 							&lt;br /&gt;
Sahana Eden provides various of functions which are sorted in several different modules.&amp;lt;br&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
===Organization Registry===			&lt;br /&gt;
Sahana Eden’s Organization Registry can track what organizations do and organizations also could record their Offices, Warehouse and Field Sites including their locations so they can be mapped as well as links to other modules such as Human Resources, Assets and Inventory.&amp;lt;br&amp;gt;						&lt;br /&gt;
====Project Tracking====&lt;br /&gt;
By telling you Who’s Doing What, Where, and When, Sahana Eden provides a valuable tool to help organizations responding to disasters know where the greatest needs are and coordinate with others who are engaged in similar work.&amp;lt;br&amp;gt;&lt;br /&gt;
====Human Resources====		&lt;br /&gt;
Sahana Eden can also be used to provide a contact list to ensure that the right people can be contacted at the right time.&amp;lt;br&amp;gt;&lt;br /&gt;
====Inventory====		&lt;br /&gt;
Sahana Eden can be used to manage inventories of items and match requests for items with warehouses and other facilities which have them available. Sahana Eden can support multiple Catalogs of Items as well as providing alternative items to ensure more effective use of supplies. &amp;lt;br&amp;gt;&lt;br /&gt;
====Assets====&lt;br /&gt;
Sahana Eden is able to manage assets which are needed to respond to disasters, track where they are, who they have been assigned to, and what condition they are in. This ensures that assets are used effectively and efficiently.	&amp;lt;br&amp;gt;&lt;br /&gt;
====Assessments====											&lt;br /&gt;
Sahana Eden can be used to collect and analyze information from assessments to help organizations more effectively plan their disaster management activities. &amp;lt;br&amp;gt;&lt;br /&gt;
====Scenarios &amp;amp; Events====&lt;br /&gt;
To help organizations better plan for disasters, Sahana Eden can be used to plan for different scenarios, including recording what human resources, assets, facilities and tasks will be needed to effectively respond.&amp;lt;br&amp;gt;&lt;br /&gt;
====Map	====									&lt;br /&gt;
Sahana Eden has fully integrated mapping functionality which allows any location-based data to be visualized on a map. Maps provide situational awareness which is essential when either planning to prepare for or respond to a disaster.&amp;lt;br&amp;gt;&lt;br /&gt;
====Shelter Management====		&lt;br /&gt;
When disasters are widespread and result in population displacement, understanding and tracking the landscape of shelters - and the people in them - is a critical activity. The Shelter Registry provides functionality to list and track information on shelters and on the people arriving and departing. &amp;lt;br&amp;gt;&lt;br /&gt;
====Messaging====&lt;br /&gt;
Sahana Eden provides support for messages to be sent to one or Distribution Groups by Email, SMS, Twitter and Google Talk. Interactive messages can also be set up to allow people to send short message queries to Sahana Eden and receive automatic responses.&amp;lt;br&amp;gt;&lt;br /&gt;
===Sahana Eden Architecture===&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
former developer discussion about Sahana Oden &lt;br /&gt;
* An [https://groups.google.com/forum/?utm_medium=email&amp;amp;utm_source=footer#!forum/sahana-eden google discussion], explaining former problems developers met and corresponding solutions&lt;br /&gt;
*An [http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework basic introduction about the framework of Edenmobile including application design, source ] &lt;br /&gt;
Source code&lt;br /&gt;
http://eden.sahanafoundation.org/wiki/BluePrint/Mobile/EdenMobileFramework&lt;br /&gt;
&lt;br /&gt;
=Design=&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Submit forms to server'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** User logs in to Sahana Server.&lt;br /&gt;
*** User fills .&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Submit forms to local storage'''&lt;br /&gt;
** '''Actor:''' Mobile App User&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** A.&lt;br /&gt;
*** B.&lt;br /&gt;
*** C.&lt;br /&gt;
*** D.&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Download new forms from server'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** A.&lt;br /&gt;
*** B.&lt;br /&gt;
*** C.&lt;br /&gt;
*** D.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #4: Synchronize local data with server '''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** A.&lt;br /&gt;
*** B.&lt;br /&gt;
*** C.&lt;br /&gt;
*** D.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:TO_BE_ADDED.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=Troubleshoots=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96186</id>
		<title>CSC/ECE 517 Spring 2015 S1503 LWJZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1503_LWJZ&amp;diff=96186"/>
		<updated>2015-04-01T00:40:39Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Background */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;big&amp;gt;E1526. JavaRosa Mobile Client&amp;lt;/big&amp;gt;&lt;br /&gt;
=Introduction=&lt;br /&gt;
==Purpose==&lt;br /&gt;
To add several modules to the EdenMobile client app based on the web2py framework to allow mobile users to add new shelters and hospitals,  to see the list of hospitals and shelters both offline and online and pass their location to the nearest medical facilities. &lt;br /&gt;
==Scope==&lt;br /&gt;
 We will realize the signup, secure login and logout function, which would add new module into the following files:&lt;br /&gt;
           communication.js&lt;br /&gt;
           controller.js&lt;br /&gt;
           model.js&lt;br /&gt;
           view.js&lt;br /&gt;
We will make it available in multiple languages environment which will implement the languages fold.&lt;br /&gt;
We will add some new items including:“ hospital”, “vehicles” which will be added into the folder named “plugins”. The following file will be added into their corrsponding folders:&lt;br /&gt;
hospitals:&lt;br /&gt;
              mHospital.js (model)&lt;br /&gt;
              hospital.js, editHospital.js, hospital.html, hospital.css, editHospital.html (views)&lt;br /&gt;
              hospitalController.js (controller)&lt;br /&gt;
              config.js(Giving details on the configuration of the plugin&lt;br /&gt;
vehicles:&lt;br /&gt;
              mVehicles.js (model)&lt;br /&gt;
              vehicles.js, editVehicles.js, vehicles.html, vehicles.css, editVehicles.html (views)&lt;br /&gt;
              vehiclesController.js (controller)&lt;br /&gt;
              config.js(Giving details on the configuration of the plugin)&lt;br /&gt;
Also, we find some bugs and eliminate them. These could be any possible file in this project.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
===What’s Sahana Eden?=== &lt;br /&gt;
Sahana Eden is an Open Source Humanitarian Platform which can be used to provide solutions for Disaster Management, Development, and Environmental Management sectors. It is the latest evolution of Sahana Software which was initially developed by members of the information technology (IT) community in Sri Lanka to provide solutions for the relief effort following the 2004 Indian Ocean Tsunami. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
=Design=&lt;br /&gt;
=Use Cases=&lt;br /&gt;
=Troubleshoots=&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95450</id>
		<title>CSC/ECE 517 Spring 2015/oss E1502 wwj</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95450"/>
		<updated>2015-03-22T18:15:21Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* What needs to be done: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1502: Questionnaire Controller Refactoring&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In this project, we have done some refactoring on the questionnaires_controller. We moved some methods to where we thought suited them, and changed the format of language into ruby style, deleted debugging statement. Details are displayed in the following sections.&lt;br /&gt;
&lt;br /&gt;
=Introduction to Expertiza=&lt;br /&gt;
The Expertiza project is system for using peer review to create reusable learning objects. Students do different assignments; then peer review selects the best work in each category, and assembles it to create a single unit.&amp;lt;ref&amp;gt;[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
==What it does:==	 &lt;br /&gt;
Used on the admin side of Expertiza for creating/ editing questionnaires (rubrics, surveys and quizzes). It helps in add/removing questions, options, etc for a questionnaire.&lt;br /&gt;
&amp;lt;li&amp;gt;Very big controller that handles a lot more than the name suggests. Functionalities need to be moved to appropriate controllers.&lt;br /&gt;
&amp;lt;li&amp;gt;Quiz methods are should be treated the same as any other type of questionnaire; differences between quiz questionnaires and other questionnaires should be implemented in the model class, quiz_questionnaire&lt;br /&gt;
&amp;lt;li&amp;gt;Turn the questionnaire into a “form object.”  The ..._questions methods: save_new_questions, delete_questions, save_questions should be in a separate class.&lt;br /&gt;
==Other classes involved:==&lt;br /&gt;
&amp;lt;li&amp;gt;questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;quiz_questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;questions_controller.rb&lt;br /&gt;
&lt;br /&gt;
==What needs to be done:==&lt;br /&gt;
&amp;lt;li&amp;gt;Move quiz related functions to &amp;lt;i&amp;gt;quiz_questionnaire.rb&amp;lt;/i&amp;gt;.&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;copy, update_quiz, valid_quiz&amp;lt;/i&amp;gt; methods, clone_questionnaire_details is too long.&lt;br /&gt;
&amp;lt;li&amp;gt;Debug output (print statements) should be removed.&lt;br /&gt;
&amp;lt;li&amp;gt;Understand the functions in the controller and comment them. Ensure that the code is understandable to the next programmer who works on it.&lt;br /&gt;
&lt;br /&gt;
=What We Have Done=&lt;br /&gt;
==Method Refactoring==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| copy&lt;br /&gt;
| Extracted the content of this method as copy_questionnaires method and put it in questionnaire.rb &lt;br /&gt;
| The content of this method is about operations on the database (coping a questionnaire), it is better to be put in the model&lt;br /&gt;
|-&lt;br /&gt;
| valid_quiz&lt;br /&gt;
| Moved this method to quiz_questionnaire.rb&lt;br /&gt;
| This method is about validation of the quiz, it shouldn't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| export&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method exports the questionnaires as csv file, it should't appear in the controller &lt;br /&gt;
|-&lt;br /&gt;
| import&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method imports the questionnaires from csv file, it should't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| clone_questionnaire_details&lt;br /&gt;
| Deleted this method due to the duplication&lt;br /&gt;
| Substituted by copy_questionnaires method in questionnaire.rb &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Format Refactoring==&lt;br /&gt;
===Case 1: Loop Condition===&lt;br /&gt;
Change all the looping conditions into one format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  for question in @questionnaire.questions&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  @questionnaire.assignments.each&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Case 2: If Condition===&lt;br /&gt;
Change all the if conditions into ruby format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create == true&lt;br /&gt;
 .&lt;br /&gt;
 . &lt;br /&gt;
 unless this_q.nil?&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if this_q&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Case 3: Name===&lt;br /&gt;
Change all the name from &amp;quot;JAVA name&amp;quot; to &amp;quot;Ruby name&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  questionnum=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  question_num=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==Refactoring Example==&lt;br /&gt;
&amp;lt;p id=&amp;quot;example&amp;quot;&amp;gt;In &amp;lt;i&amp;gt;models/questionnaires.rb&amp;lt;/i&amp;gt;, we add &amp;lt;i&amp;gt;copy_questionnaires&amp;lt;/i&amp;gt; method, as shown below:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.copy_questionnaires(id,user)&lt;br /&gt;
    @orig_questionnaire = Questionnaire.find(id)&lt;br /&gt;
    questions = Question.where(questionnaire_id: id)&lt;br /&gt;
    @questionnaire = @orig_questionnaire.clone&lt;br /&gt;
    @questionnaire.instructor_id = user.instructor_id  ## Why was TA-specific code removed here?  See Project E713.&lt;br /&gt;
    @questionnaire.name = 'Copy of ' + @orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
    if user.role.name != &amp;quot;Teaching Assistant&amp;quot;&lt;br /&gt;
      @questionnaire.instructor_id = user.id&lt;br /&gt;
    else # for TA we need to get his instructor id and by default add it to his course for which he is the TA&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(user.id)&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire.name = 'Copy of '+@orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      @questionnaire.created_at = Time.now&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
&lt;br /&gt;
      questions.each{ | question |&lt;br /&gt;
&lt;br /&gt;
        new_question = question.clone&lt;br /&gt;
        new_question.questionnaire_id = @questionnaire.id&lt;br /&gt;
        new_question.save&lt;br /&gt;
&lt;br /&gt;
        advice = QuestionAdvice.find_by_question_id(question.id)&lt;br /&gt;
        if advice&lt;br /&gt;
          new_advice = advice.clone&lt;br /&gt;
          new_advice.question_id = newquestion.id&lt;br /&gt;
          new_advice.save&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        if (@questionnaire.section == &amp;quot;Custom&amp;quot;)&lt;br /&gt;
          old_question_type = QuestionType.find_by_question_id(question.id)&lt;br /&gt;
          if old_question_type&lt;br /&gt;
            new_question_type = old_question_type.clone&lt;br /&gt;
            new_question_type.question_id = newquestion.id&lt;br /&gt;
            new_question_type.save&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      pFolder = TreeFolder.find_by_name(@questionnaire.display_type)&lt;br /&gt;
      parent = FolderNode.find_by_node_object_id(pFolder.id)&lt;br /&gt;
      unless QuestionnaireNode.where(parent_id: parent.id, node_object_id: @questionnaire.id)&lt;br /&gt;
        QuestionnaireNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; @questionnaire.id)&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95448</id>
		<title>CSC/ECE 517 Spring 2015/oss E1502 wwj</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95448"/>
		<updated>2015-03-22T18:14:12Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Refactoring Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1502: Questionnaire Controller Refactoring&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In this project, we have done some refactoring on the questionnaires_controller. We moved some methods to where we thought suited them, and changed the format of language into ruby style, deleted debugging statement. Details are displayed in the following sections.&lt;br /&gt;
&lt;br /&gt;
=Introduction to Expertiza=&lt;br /&gt;
The Expertiza project is system for using peer review to create reusable learning objects. Students do different assignments; then peer review selects the best work in each category, and assembles it to create a single unit.&amp;lt;ref&amp;gt;[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
==What it does:==	 &lt;br /&gt;
Used on the admin side of Expertiza for creating/ editing questionnaires (rubrics, surveys and quizzes). It helps in add/removing questions, options, etc for a questionnaire.&lt;br /&gt;
&amp;lt;li&amp;gt;Very big controller that handles a lot more than the name suggests. Functionalities need to be moved to appropriate controllers.&lt;br /&gt;
&amp;lt;li&amp;gt;Quiz methods are should be treated the same as any other type of questionnaire; differences between quiz questionnaires and other questionnaires should be implemented in the model class, quiz_questionnaire&lt;br /&gt;
&amp;lt;li&amp;gt;Turn the questionnaire into a “form object.”  The ..._questions methods: save_new_questions, delete_questions, save_questions should be in a separate class.&lt;br /&gt;
==Other classes involved:==&lt;br /&gt;
&amp;lt;li&amp;gt;questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;quiz_questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;questions_controller.rb&lt;br /&gt;
&lt;br /&gt;
==What needs to be done:==&lt;br /&gt;
&amp;lt;li&amp;gt;Move quiz related functions to quiz_questionnaire.rb.&lt;br /&gt;
&amp;lt;li&amp;gt;copy, update_quiz, valid_quiz methods, clone_questionnaire_details is too long.&lt;br /&gt;
&amp;lt;li&amp;gt;Debug output (print statements) should be removed.&lt;br /&gt;
&amp;lt;li&amp;gt;Understand the functions in the controller and comment them. Ensure that the code is understandable to the next programmer who works on it.&lt;br /&gt;
&lt;br /&gt;
=What We Have Done=&lt;br /&gt;
==Method Refactoring==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| copy&lt;br /&gt;
| Extracted the content of this method as copy_questionnaires method and put it in questionnaire.rb &lt;br /&gt;
| The content of this method is about operations on the database (coping a questionnaire), it is better to be put in the model&lt;br /&gt;
|-&lt;br /&gt;
| valid_quiz&lt;br /&gt;
| Moved this method to quiz_questionnaire.rb&lt;br /&gt;
| This method is about validation of the quiz, it shouldn't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| export&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method exports the questionnaires as csv file, it should't appear in the controller &lt;br /&gt;
|-&lt;br /&gt;
| import&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method imports the questionnaires from csv file, it should't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| clone_questionnaire_details&lt;br /&gt;
| Deleted this method due to the duplication&lt;br /&gt;
| Substituted by copy_questionnaires method in questionnaire.rb &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Format Refactoring==&lt;br /&gt;
===Case 1: Loop Condition===&lt;br /&gt;
Change all the looping conditions into one format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  for question in @questionnaire.questions&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  @questionnaire.assignments.each&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Case 2: If Condition===&lt;br /&gt;
Change all the if conditions into ruby format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create == true&lt;br /&gt;
 .&lt;br /&gt;
 . &lt;br /&gt;
 unless this_q.nil?&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if this_q&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Case 3: Name===&lt;br /&gt;
Change all the name from &amp;quot;JAVA name&amp;quot; to &amp;quot;Ruby name&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  questionnum=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  question_num=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==Refactoring Example==&lt;br /&gt;
&amp;lt;p id=&amp;quot;example&amp;quot;&amp;gt;In &amp;lt;i&amp;gt;models/questionnaires.rb&amp;lt;/i&amp;gt;, we add &amp;lt;i&amp;gt;copy_questionnaires&amp;lt;/i&amp;gt; method, as shown below:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.copy_questionnaires(id,user)&lt;br /&gt;
    @orig_questionnaire = Questionnaire.find(id)&lt;br /&gt;
    questions = Question.where(questionnaire_id: id)&lt;br /&gt;
    @questionnaire = @orig_questionnaire.clone&lt;br /&gt;
    @questionnaire.instructor_id = user.instructor_id  ## Why was TA-specific code removed here?  See Project E713.&lt;br /&gt;
    @questionnaire.name = 'Copy of ' + @orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
    if user.role.name != &amp;quot;Teaching Assistant&amp;quot;&lt;br /&gt;
      @questionnaire.instructor_id = user.id&lt;br /&gt;
    else # for TA we need to get his instructor id and by default add it to his course for which he is the TA&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(user.id)&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire.name = 'Copy of '+@orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      @questionnaire.created_at = Time.now&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
&lt;br /&gt;
      questions.each{ | question |&lt;br /&gt;
&lt;br /&gt;
        new_question = question.clone&lt;br /&gt;
        new_question.questionnaire_id = @questionnaire.id&lt;br /&gt;
        new_question.save&lt;br /&gt;
&lt;br /&gt;
        advice = QuestionAdvice.find_by_question_id(question.id)&lt;br /&gt;
        if advice&lt;br /&gt;
          new_advice = advice.clone&lt;br /&gt;
          new_advice.question_id = newquestion.id&lt;br /&gt;
          new_advice.save&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        if (@questionnaire.section == &amp;quot;Custom&amp;quot;)&lt;br /&gt;
          old_question_type = QuestionType.find_by_question_id(question.id)&lt;br /&gt;
          if old_question_type&lt;br /&gt;
            new_question_type = old_question_type.clone&lt;br /&gt;
            new_question_type.question_id = newquestion.id&lt;br /&gt;
            new_question_type.save&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      pFolder = TreeFolder.find_by_name(@questionnaire.display_type)&lt;br /&gt;
      parent = FolderNode.find_by_node_object_id(pFolder.id)&lt;br /&gt;
      unless QuestionnaireNode.where(parent_id: parent.id, node_object_id: @questionnaire.id)&lt;br /&gt;
        QuestionnaireNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; @questionnaire.id)&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95444</id>
		<title>CSC/ECE 517 Spring 2015/oss E1502 wwj</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95444"/>
		<updated>2015-03-22T18:04:37Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1502: Questionnaire Controller Refactoring&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In this project, we have done some refactoring on the questionnaires_controller. We moved some methods to where we thought suited them, and changed the format of language into ruby style, deleted debugging statement. Details are displayed in the following sections.&lt;br /&gt;
&lt;br /&gt;
=Introduction to Expertiza=&lt;br /&gt;
The Expertiza project is system for using peer review to create reusable learning objects. Students do different assignments; then peer review selects the best work in each category, and assembles it to create a single unit.&amp;lt;ref&amp;gt;[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
==What it does:==	 &lt;br /&gt;
Used on the admin side of Expertiza for creating/ editing questionnaires (rubrics, surveys and quizzes). It helps in add/removing questions, options, etc for a questionnaire.&lt;br /&gt;
&amp;lt;li&amp;gt;Very big controller that handles a lot more than the name suggests. Functionalities need to be moved to appropriate controllers.&lt;br /&gt;
&amp;lt;li&amp;gt;Quiz methods are should be treated the same as any other type of questionnaire; differences between quiz questionnaires and other questionnaires should be implemented in the model class, quiz_questionnaire&lt;br /&gt;
&amp;lt;li&amp;gt;Turn the questionnaire into a “form object.”  The ..._questions methods: save_new_questions, delete_questions, save_questions should be in a separate class.&lt;br /&gt;
==Other classes involved:==&lt;br /&gt;
&amp;lt;li&amp;gt;questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;quiz_questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;questions_controller.rb&lt;br /&gt;
&lt;br /&gt;
==What needs to be done:==&lt;br /&gt;
&amp;lt;li&amp;gt;Move quiz related functions to quiz_questionnaire.rb.&lt;br /&gt;
&amp;lt;li&amp;gt;copy, update_quiz, valid_quiz methods, clone_questionnaire_details is too long.&lt;br /&gt;
&amp;lt;li&amp;gt;Debug output (print statements) should be removed.&lt;br /&gt;
&amp;lt;li&amp;gt;Understand the functions in the controller and comment them. Ensure that the code is understandable to the next programmer who works on it.&lt;br /&gt;
&lt;br /&gt;
=What We Have Done=&lt;br /&gt;
==Method Refactoring==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| copy&lt;br /&gt;
| Extracted the content of this method as copy_questionnaires method and put it in questionnaire.rb &lt;br /&gt;
| The content of this method is about operations on the database (coping a questionnaire), it is better to be put in the model&lt;br /&gt;
|-&lt;br /&gt;
| valid_quiz&lt;br /&gt;
| Moved this method to quiz_questionnaire.rb&lt;br /&gt;
| This method is about validation of the quiz, it shouldn't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| export&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method exports the questionnaires as csv file, it should't appear in the controller &lt;br /&gt;
|-&lt;br /&gt;
| import&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method imports the questionnaires from csv file, it should't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| clone_questionnaire_details&lt;br /&gt;
| Deleted this method due to the duplication&lt;br /&gt;
| Substituted by copy_questionnaires method in questionnaire.rb &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Format Refactoring==&lt;br /&gt;
===Case 1: Loop Condition===&lt;br /&gt;
Change all the looping conditions into one format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  for question in @questionnaire.questions&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  @questionnaire.assignments.each&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Case 2: If Condition===&lt;br /&gt;
Change all the if conditions into ruby format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create == true&lt;br /&gt;
 .&lt;br /&gt;
 . &lt;br /&gt;
 unless this_q.nil?&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if this_q&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Case 3: Name===&lt;br /&gt;
Change all the name from &amp;quot;JAVA name&amp;quot; to &amp;quot;Ruby name&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  questionnum=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  question_num=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==Refactoring Example==&lt;br /&gt;
&amp;lt;p id=&amp;quot;example&amp;quot;&amp;gt;In models/questionnaires.rb, we add copy_questionnaires method, as shown below:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.copy_questionnaires(id,user)&lt;br /&gt;
    @orig_questionnaire = Questionnaire.find(id)&lt;br /&gt;
    questions = Question.where(questionnaire_id: id)&lt;br /&gt;
    @questionnaire = @orig_questionnaire.clone&lt;br /&gt;
    @questionnaire.instructor_id = user.instructor_id  ## Why was TA-specific code removed here?  See Project E713.&lt;br /&gt;
    @questionnaire.name = 'Copy of ' + @orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
    if user.role.name != &amp;quot;Teaching Assistant&amp;quot;&lt;br /&gt;
      @questionnaire.instructor_id = user.id&lt;br /&gt;
    else # for TA we need to get his instructor id and by default add it to his course for which he is the TA&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(user.id)&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire.name = 'Copy of '+@orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      @questionnaire.created_at = Time.now&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
&lt;br /&gt;
      questions.each{ | question |&lt;br /&gt;
&lt;br /&gt;
        new_question = question.clone&lt;br /&gt;
        new_question.questionnaire_id = @questionnaire.id&lt;br /&gt;
        new_question.save&lt;br /&gt;
&lt;br /&gt;
        advice = QuestionAdvice.find_by_question_id(question.id)&lt;br /&gt;
        if advice&lt;br /&gt;
          new_advice = advice.clone&lt;br /&gt;
          new_advice.question_id = newquestion.id&lt;br /&gt;
          new_advice.save&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        if (@questionnaire.section == &amp;quot;Custom&amp;quot;)&lt;br /&gt;
          old_question_type = QuestionType.find_by_question_id(question.id)&lt;br /&gt;
          if old_question_type&lt;br /&gt;
            new_question_type = old_question_type.clone&lt;br /&gt;
            new_question_type.question_id = newquestion.id&lt;br /&gt;
            new_question_type.save&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      pFolder = TreeFolder.find_by_name(@questionnaire.display_type)&lt;br /&gt;
      parent = FolderNode.find_by_node_object_id(pFolder.id)&lt;br /&gt;
      unless QuestionnaireNode.where(parent_id: parent.id, node_object_id: @questionnaire.id)&lt;br /&gt;
        QuestionnaireNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; @questionnaire.id)&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95433</id>
		<title>CSC/ECE 517 Spring 2015/oss E1502 wwj</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95433"/>
		<updated>2015-03-22T17:50:57Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1502: Questionnaire Controller Refactoring&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In this project, we have done some refactoring on the questionnaires_controller. We moved some methods to where we thought suited them, and changed the format of language into ruby style, deleted debugging statement. Details are displayed in the following sections.&lt;br /&gt;
&lt;br /&gt;
=Introduction to Expertiza=&lt;br /&gt;
The Expertiza project is system for using peer review to create reusable learning objects. Students do different assignments; then peer review selects the best work in each category, and assembles it to create a single unit.&amp;lt;ref&amp;gt;[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
==What it does:==	 &lt;br /&gt;
Used on the admin side of Expertiza for creating/ editing questionnaires (rubrics, surveys and quizzes). It helps in add/removing questions, options, etc for a questionnaire.&lt;br /&gt;
&amp;lt;li&amp;gt;Very big controller that handles a lot more than the name suggests. Functionalities need to be moved to appropriate controllers.&lt;br /&gt;
&amp;lt;li&amp;gt;Quiz methods are should be treated the same as any other type of questionnaire; differences between quiz questionnaires and other questionnaires should be implemented in the model class, quiz_questionnaire&lt;br /&gt;
&amp;lt;li&amp;gt;Turn the questionnaire into a “form object.”  The ..._questions methods: save_new_questions, delete_questions, save_questions should be in a separate class.&lt;br /&gt;
==Other classes involved:==&lt;br /&gt;
&amp;lt;li&amp;gt;questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;quiz_questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;questions_controller.rb&lt;br /&gt;
&lt;br /&gt;
==What needs to be done:==&lt;br /&gt;
&amp;lt;li&amp;gt;Move quiz related functions to quiz_questionnaire.rb.&lt;br /&gt;
&amp;lt;li&amp;gt;copy, update_quiz, valid_quiz methods, clone_questionnaire_details is too long.&lt;br /&gt;
&amp;lt;li&amp;gt;Debug output (print statements) should be removed.&lt;br /&gt;
&amp;lt;li&amp;gt;Understand the functions in the controller and comment them. Ensure that the code is understandable to the next programmer who works on it.&lt;br /&gt;
&lt;br /&gt;
=What We Have Done=&lt;br /&gt;
==Method Refactoring==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| copy&lt;br /&gt;
| Extracted the content of this method as copy_questionnaires method and put it in questionnaire.rb &lt;br /&gt;
| The content of this method is about operations on the database (coping a questionnaire), it is better to be put in the model&lt;br /&gt;
|-&lt;br /&gt;
| valid_quiz&lt;br /&gt;
| Moved this method to quiz_questionnaire.rb&lt;br /&gt;
| This method is about validation of the quiz, it shouldn't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| export&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method exports the questionnaires as csv file, it should't appear in the controller &lt;br /&gt;
|-&lt;br /&gt;
| import&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method imports the questionnaires from csv file, it should't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| clone_questionnaire_details&lt;br /&gt;
| Deleted this method due to the duplication&lt;br /&gt;
| Substituted by copy_questionnaires method in questionnaire.rb &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Format Refactoring==&lt;br /&gt;
===Case 1: Loop Condition===&lt;br /&gt;
Change all the looping conditions into one format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  for question in @questionnaire.questions&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  @questionnaire.assignments.each&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Case 2: If Condition===&lt;br /&gt;
Change all the if conditions into ruby format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create == true&lt;br /&gt;
 .&lt;br /&gt;
 . &lt;br /&gt;
 unless this_q.nil?&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if this_q&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Case 3: Name===&lt;br /&gt;
Change all the name from &amp;quot;JAVA name&amp;quot; to &amp;quot;Ruby name&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  questionnum=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  question_num=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==Refactoring Example==&lt;br /&gt;
&amp;lt;p id=&amp;quot;example&amp;quot;&amp;gt;In models/questionnaires.rb, we add copy_questionnaires method, as shown below:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.copy_questionnaires(id,user)&lt;br /&gt;
    @orig_questionnaire = Questionnaire.find(id)&lt;br /&gt;
    questions = Question.where(questionnaire_id: id)&lt;br /&gt;
    @questionnaire = @orig_questionnaire.clone&lt;br /&gt;
    @questionnaire.instructor_id = user.instructor_id  ## Why was TA-specific code removed here?  See Project E713.&lt;br /&gt;
    @questionnaire.name = 'Copy of ' + @orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
    if user.role.name != &amp;quot;Teaching Assistant&amp;quot;&lt;br /&gt;
      @questionnaire.instructor_id = user.id&lt;br /&gt;
    else # for TA we need to get his instructor id and by default add it to his course for which he is the TA&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(user.id)&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire.name = 'Copy of '+@orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      @questionnaire.created_at = Time.now&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
&lt;br /&gt;
      questions.each{ | question |&lt;br /&gt;
&lt;br /&gt;
        new_question = question.clone&lt;br /&gt;
        new_question.questionnaire_id = @questionnaire.id&lt;br /&gt;
        new_question.save&lt;br /&gt;
&lt;br /&gt;
        advice = QuestionAdvice.find_by_question_id(question.id)&lt;br /&gt;
        if advice&lt;br /&gt;
          new_advice = advice.clone&lt;br /&gt;
          new_advice.question_id = newquestion.id&lt;br /&gt;
          new_advice.save&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        if (@questionnaire.section == &amp;quot;Custom&amp;quot;)&lt;br /&gt;
          old_question_type = QuestionType.find_by_question_id(question.id)&lt;br /&gt;
          if old_question_type&lt;br /&gt;
            new_question_type = old_question_type.clone&lt;br /&gt;
            new_question_type.question_id = newquestion.id&lt;br /&gt;
            new_question_type.save&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      pFolder = TreeFolder.find_by_name(@questionnaire.display_type)&lt;br /&gt;
      parent = FolderNode.find_by_node_object_id(pFolder.id)&lt;br /&gt;
      unless QuestionnaireNode.where(parent_id: parent.id, node_object_id: @questionnaire.id)&lt;br /&gt;
        QuestionnaireNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; @questionnaire.id)&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95430</id>
		<title>CSC/ECE 517 Spring 2015/oss E1502 wwj</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95430"/>
		<updated>2015-03-22T17:49:29Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1502: Questionnaire Controller Refactoring&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In this project, we have done some refactoring on the questionnaires_controller. We moved some methods to where we thought suited them, and changed the format of language into ruby style, deleted debugging statement. Details are displayed in the following sections.&lt;br /&gt;
&lt;br /&gt;
==Introduction to Expertiza==&lt;br /&gt;
The Expertiza project is system for using peer review to create reusable learning objects. Students do different assignments; then peer review selects the best work in each category, and assembles it to create a single unit.&amp;lt;ref&amp;gt;[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Project Description==&lt;br /&gt;
===What it does:===	 &lt;br /&gt;
Used on the admin side of Expertiza for creating/ editing questionnaires (rubrics, surveys and quizzes). It helps in add/removing questions, options, etc for a questionnaire.&lt;br /&gt;
&amp;lt;li&amp;gt;Very big controller that handles a lot more than the name suggests. Functionalities need to be moved to appropriate controllers.&lt;br /&gt;
&amp;lt;li&amp;gt;Quiz methods are should be treated the same as any other type of questionnaire; differences between quiz questionnaires and other questionnaires should be implemented in the model class, quiz_questionnaire&lt;br /&gt;
&amp;lt;li&amp;gt;Turn the questionnaire into a “form object.”  The ..._questions methods: save_new_questions, delete_questions, save_questions should be in a separate class.&lt;br /&gt;
===Other classes involved:===&lt;br /&gt;
&amp;lt;li&amp;gt;questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;quiz_questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;questions_controller.rb&lt;br /&gt;
&lt;br /&gt;
===What needs to be done:===&lt;br /&gt;
&amp;lt;li&amp;gt;Move quiz related functions to quiz_questionnaire.rb.&lt;br /&gt;
&amp;lt;li&amp;gt;copy, update_quiz, valid_quiz methods, clone_questionnaire_details is too long.&lt;br /&gt;
&amp;lt;li&amp;gt;Debug output (print statements) should be removed.&lt;br /&gt;
&amp;lt;li&amp;gt;Understand the functions in the controller and comment them. Ensure that the code is understandable to the next programmer who works on it.&lt;br /&gt;
&lt;br /&gt;
==What We Have Done==&lt;br /&gt;
===Method Refactoring===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| copy&lt;br /&gt;
| Extracted the content of this method as copy_questionnaires method and put it in questionnaire.rb &lt;br /&gt;
| The content of this method is about operations on the database (coping a questionnaire), it is better to be put in the model&lt;br /&gt;
|-&lt;br /&gt;
| valid_quiz&lt;br /&gt;
| Moved this method to quiz_questionnaire.rb&lt;br /&gt;
| This method is about validation of the quiz, it shouldn't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| export&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method exports the questionnaires as csv file, it should't appear in the controller &lt;br /&gt;
|-&lt;br /&gt;
| import&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method imports the questionnaires from csv file, it should't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| clone_questionnaire_details&lt;br /&gt;
| Deleted this method due to the duplication&lt;br /&gt;
| Substituted by copy_questionnaires method in questionnaire.rb &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Format Refactoring===&lt;br /&gt;
====Case 1: Loop Condition====&lt;br /&gt;
Change all the looping conditions into one format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  for question in @questionnaire.questions&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  @questionnaire.assignments.each&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Case 2: If Condition====&lt;br /&gt;
Change all the if conditions into ruby format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create == true&lt;br /&gt;
 .&lt;br /&gt;
 . &lt;br /&gt;
 unless this_q.nil?&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if this_q&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Case 3: Name====&lt;br /&gt;
Change all the name from &amp;quot;JAVA name&amp;quot; to &amp;quot;Ruby name&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  questionnum=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  question_num=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Refactoring Example===&lt;br /&gt;
&amp;lt;p id=&amp;quot;example&amp;quot;&amp;gt;In models/questionnaires.rb, we add copy_questionnaires method, as shown below:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.copy_questionnaires(id,user)&lt;br /&gt;
    @orig_questionnaire = Questionnaire.find(id)&lt;br /&gt;
    questions = Question.where(questionnaire_id: id)&lt;br /&gt;
    @questionnaire = @orig_questionnaire.clone&lt;br /&gt;
    @questionnaire.instructor_id = user.instructor_id  ## Why was TA-specific code removed here?  See Project E713.&lt;br /&gt;
    @questionnaire.name = 'Copy of ' + @orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
    if user.role.name != &amp;quot;Teaching Assistant&amp;quot;&lt;br /&gt;
      @questionnaire.instructor_id = user.id&lt;br /&gt;
    else # for TA we need to get his instructor id and by default add it to his course for which he is the TA&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(user.id)&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire.name = 'Copy of '+@orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      @questionnaire.created_at = Time.now&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
&lt;br /&gt;
      questions.each{ | question |&lt;br /&gt;
&lt;br /&gt;
        new_question = question.clone&lt;br /&gt;
        new_question.questionnaire_id = @questionnaire.id&lt;br /&gt;
        new_question.save&lt;br /&gt;
&lt;br /&gt;
        advice = QuestionAdvice.find_by_question_id(question.id)&lt;br /&gt;
        if advice&lt;br /&gt;
          new_advice = advice.clone&lt;br /&gt;
          new_advice.question_id = newquestion.id&lt;br /&gt;
          new_advice.save&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        if (@questionnaire.section == &amp;quot;Custom&amp;quot;)&lt;br /&gt;
          old_question_type = QuestionType.find_by_question_id(question.id)&lt;br /&gt;
          if old_question_type&lt;br /&gt;
            new_question_type = old_question_type.clone&lt;br /&gt;
            new_question_type.question_id = newquestion.id&lt;br /&gt;
            new_question_type.save&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      pFolder = TreeFolder.find_by_name(@questionnaire.display_type)&lt;br /&gt;
      parent = FolderNode.find_by_node_object_id(pFolder.id)&lt;br /&gt;
      unless QuestionnaireNode.where(parent_id: parent.id, node_object_id: @questionnaire.id)&lt;br /&gt;
        QuestionnaireNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; @questionnaire.id)&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95428</id>
		<title>CSC/ECE 517 Spring 2015/oss E1502 wwj</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95428"/>
		<updated>2015-03-22T17:48:39Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1502: Questionnaire Controller Refactoring&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
In this project, we have done some refactoring on the questionnaires_controller. We moved some methods to where we thought suited them, and changed the format of language into ruby style, deleted debugging statement. Details are displayed in the following sections.&lt;br /&gt;
&lt;br /&gt;
==Introduction to Expertiza==&lt;br /&gt;
The Expertiza project is system for using peer review to create reusable learning objects. Students do different assignments; then peer review selects the best work in each category, and assembles it to create a single unit.&amp;lt;ref&amp;gt;[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Project Description==&lt;br /&gt;
===What it does:===	 &lt;br /&gt;
Used on the admin side of Expertiza for creating/ editing questionnaires (rubrics, surveys and quizzes). It helps in add/removing questions, options, etc for a questionnaire.&lt;br /&gt;
&amp;lt;li&amp;gt;Very big controller that handles a lot more than the name suggests. Functionalities need to be moved to appropriate controllers.&lt;br /&gt;
&amp;lt;li&amp;gt;Quiz methods are should be treated the same as any other type of questionnaire; differences between quiz questionnaires and other questionnaires should be implemented in the model class, quiz_questionnaire&lt;br /&gt;
&amp;lt;li&amp;gt;Turn the questionnaire into a “form object.”  The ..._questions methods: save_new_questions, delete_questions, save_questions should be in a separate class.&lt;br /&gt;
===Other classes involved:===&lt;br /&gt;
&amp;lt;li&amp;gt;questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;quiz_questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;questions_controller.rb&lt;br /&gt;
&lt;br /&gt;
===What needs to be done:===&lt;br /&gt;
&amp;lt;li&amp;gt;Move quiz related functions to quiz_questionnaire.rb.&lt;br /&gt;
&amp;lt;li&amp;gt;copy, update_quiz, valid_quiz methods, clone_questionnaire_details is too long.&lt;br /&gt;
&amp;lt;li&amp;gt;Debug output (print statements) should be removed.&lt;br /&gt;
&amp;lt;li&amp;gt;Understand the functions in the controller and comment them. Ensure that the code is understandable to the next programmer who works on it.&lt;br /&gt;
&lt;br /&gt;
==What We Have Done==&lt;br /&gt;
===Method Refactoring===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| copy&lt;br /&gt;
| Extracted the content of this method as copy_questionnaires method and put it in questionnaire.rb &lt;br /&gt;
| The content of this method is about operations on the database (coping a questionnaire), it is better to be put in the model&lt;br /&gt;
|-&lt;br /&gt;
| valid_quiz&lt;br /&gt;
| Moved this method to quiz_questionnaire.rb&lt;br /&gt;
| This method is about validation of the quiz, it shouldn't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| export&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method exports the questionnaires as csv file, it should't appear in the controller &lt;br /&gt;
|-&lt;br /&gt;
| import&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method imports the questionnaires from csv file, it should't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| clone_questionnaire_details&lt;br /&gt;
| Deleted this method due to the duplication&lt;br /&gt;
| Substituted by copy_questionnaires method in questionnaire.rb &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Format Refactoring===&lt;br /&gt;
====Case 1: Loop Condition====&lt;br /&gt;
Change all the looping conditions into one format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  for question in @questionnaire.questions&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  @questionnaire.assignments.each&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Case 2: If Condition====&lt;br /&gt;
Change all the if conditions into ruby format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create == true&lt;br /&gt;
 .&lt;br /&gt;
 . &lt;br /&gt;
 unless this_q.nil?&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if this_q&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Case 3: Name====&lt;br /&gt;
Change all the name from &amp;quot;JAVA name&amp;quot; to &amp;quot;Ruby name&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  questionnum=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  question_num=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Refactoring Example===&lt;br /&gt;
&amp;lt;p id=&amp;quot;example&amp;quot;&amp;gt;In models/questionnaires.rb, we add copy_questionnaires method, as shown below:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.copy_questionnaires(id,user)&lt;br /&gt;
    @orig_questionnaire = Questionnaire.find(id)&lt;br /&gt;
    questions = Question.where(questionnaire_id: id)&lt;br /&gt;
    @questionnaire = @orig_questionnaire.clone&lt;br /&gt;
    @questionnaire.instructor_id = user.instructor_id  ## Why was TA-specific code removed here?  See Project E713.&lt;br /&gt;
    @questionnaire.name = 'Copy of ' + @orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
    if user.role.name != &amp;quot;Teaching Assistant&amp;quot;&lt;br /&gt;
      @questionnaire.instructor_id = user.id&lt;br /&gt;
    else # for TA we need to get his instructor id and by default add it to his course for which he is the TA&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(user.id)&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire.name = 'Copy of '+@orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      @questionnaire.created_at = Time.now&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
&lt;br /&gt;
      questions.each{ | question |&lt;br /&gt;
&lt;br /&gt;
        new_question = question.clone&lt;br /&gt;
        new_question.questionnaire_id = @questionnaire.id&lt;br /&gt;
        new_question.save&lt;br /&gt;
&lt;br /&gt;
        advice = QuestionAdvice.find_by_question_id(question.id)&lt;br /&gt;
        if advice&lt;br /&gt;
          new_advice = advice.clone&lt;br /&gt;
          new_advice.question_id = newquestion.id&lt;br /&gt;
          new_advice.save&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        if (@questionnaire.section == &amp;quot;Custom&amp;quot;)&lt;br /&gt;
          old_question_type = QuestionType.find_by_question_id(question.id)&lt;br /&gt;
          if old_question_type&lt;br /&gt;
            new_question_type = old_question_type.clone&lt;br /&gt;
            new_question_type.question_id = newquestion.id&lt;br /&gt;
            new_question_type.save&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      pFolder = TreeFolder.find_by_name(@questionnaire.display_type)&lt;br /&gt;
      parent = FolderNode.find_by_node_object_id(pFolder.id)&lt;br /&gt;
      unless QuestionnaireNode.where(parent_id: parent.id, node_object_id: @questionnaire.id)&lt;br /&gt;
        QuestionnaireNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; @questionnaire.id)&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95426</id>
		<title>CSC/ECE 517 Spring 2015/oss E1502 wwj</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1502_wwj&amp;diff=95426"/>
		<updated>2015-03-22T17:46:36Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: Created page with &amp;quot;==E1502: Questionnaire Controller Refactoring== In this project, we have done some refactoring on the questionnaires_controller. We moved some methods to where we thought suited ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E1502: Questionnaire Controller Refactoring==&lt;br /&gt;
In this project, we have done some refactoring on the questionnaires_controller. We moved some methods to where we thought suited them, and changed the format of language into ruby style, deleted debugging statement. Details are displayed in the following sections.&lt;br /&gt;
&lt;br /&gt;
==Introduction to Expertiza==&lt;br /&gt;
The Expertiza project is system for using peer review to create reusable learning objects. Students do different assignments; then peer review selects the best work in each category, and assembles it to create a single unit.&amp;lt;ref&amp;gt;[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Project Description==&lt;br /&gt;
===What it does:===	 &lt;br /&gt;
Used on the admin side of Expertiza for creating/ editing questionnaires (rubrics, surveys and quizzes). It helps in add/removing questions, options, etc for a questionnaire.&lt;br /&gt;
&amp;lt;li&amp;gt;Very big controller that handles a lot more than the name suggests. Functionalities need to be moved to appropriate controllers.&lt;br /&gt;
&amp;lt;li&amp;gt;Quiz methods are should be treated the same as any other type of questionnaire; differences between quiz questionnaires and other questionnaires should be implemented in the model class, quiz_questionnaire&lt;br /&gt;
&amp;lt;li&amp;gt;Turn the questionnaire into a “form object.”  The ..._questions methods: save_new_questions, delete_questions, save_questions should be in a separate class.&lt;br /&gt;
===Other classes involved:===&lt;br /&gt;
&amp;lt;li&amp;gt;questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;quiz_questionnaire.rb&lt;br /&gt;
&amp;lt;li&amp;gt;questions_controller.rb&lt;br /&gt;
&lt;br /&gt;
===What needs to be done:===&lt;br /&gt;
&amp;lt;li&amp;gt;Move quiz related functions to quiz_questionnaire.rb.&lt;br /&gt;
&amp;lt;li&amp;gt;copy, update_quiz, valid_quiz methods, clone_questionnaire_details is too long.&lt;br /&gt;
&amp;lt;li&amp;gt;Debug output (print statements) should be removed.&lt;br /&gt;
&amp;lt;li&amp;gt;Understand the functions in the controller and comment them. Ensure that the code is understandable to the next programmer who works on it.&lt;br /&gt;
&lt;br /&gt;
==What We Have Done==&lt;br /&gt;
===Method Refactoring===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| copy&lt;br /&gt;
| Extracted the content of this method as copy_questionnaires method and put it in questionnaire.rb &lt;br /&gt;
| The content of this method is about operations on the database (coping a questionnaire), it is better to be put in the model&lt;br /&gt;
|-&lt;br /&gt;
| valid_quiz&lt;br /&gt;
| Moved this method to quiz_questionnaire.rb&lt;br /&gt;
| This method is about validation of the quiz, it shouldn't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| export&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method exports the questionnaires as csv file, it should't appear in the controller &lt;br /&gt;
|-&lt;br /&gt;
| import&lt;br /&gt;
| Moved this method to questionnaire.rb&lt;br /&gt;
| This method imports the questionnaires from csv file, it should't appear in the controller&lt;br /&gt;
|-&lt;br /&gt;
| clone_questionnaire_details&lt;br /&gt;
| Deleted this method due to the duplication&lt;br /&gt;
| Substituted by copy_questionnaires method in questionnaire.rb &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Format Refactoring===&lt;br /&gt;
====Case 1: Loop Condition====&lt;br /&gt;
Change all the looping conditions into one format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  for question in @questionnaire.questions&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Remove a given questionnaire&lt;br /&gt;
  def delete&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  @questionnaire.assignments.each&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Case 2: If Condition====&lt;br /&gt;
Change all the if conditions into ruby format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create == true&lt;br /&gt;
 .&lt;br /&gt;
 . &lt;br /&gt;
 unless this_q.nil?&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if @successful_create&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 if this_q&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Case 3: Name====&lt;br /&gt;
Change all the name from &amp;quot;JAVA name&amp;quot; to &amp;quot;Ruby name&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  questionnum=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;After&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #save an updated quiz questionnaire to the database&lt;br /&gt;
  def update_quiz&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  question_num=1&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Refactoring Example===&lt;br /&gt;
&amp;lt;p id=&amp;quot;example&amp;quot;&amp;gt;In models/questionnaires.rb, we add copy_questionnaires method, as shown below:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.copy_questionnaires(id,user)&lt;br /&gt;
    @orig_questionnaire = Questionnaire.find(id)&lt;br /&gt;
    questions = Question.where(questionnaire_id: id)&lt;br /&gt;
    @questionnaire = @orig_questionnaire.clone&lt;br /&gt;
    @questionnaire.instructor_id = user.instructor_id  ## Why was TA-specific code removed here?  See Project E713.&lt;br /&gt;
    @questionnaire.name = 'Copy of ' + @orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
    if user.role.name != &amp;quot;Teaching Assistant&amp;quot;&lt;br /&gt;
      @questionnaire.instructor_id = user.id&lt;br /&gt;
    else # for TA we need to get his instructor id and by default add it to his course for which he is the TA&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(user.id)&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire.name = 'Copy of '+@orig_questionnaire.name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      @questionnaire.created_at = Time.now&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
&lt;br /&gt;
      questions.each{ | question |&lt;br /&gt;
&lt;br /&gt;
        new_question = question.clone&lt;br /&gt;
        new_question.questionnaire_id = @questionnaire.id&lt;br /&gt;
        new_question.save&lt;br /&gt;
&lt;br /&gt;
        advice = QuestionAdvice.find_by_question_id(question.id)&lt;br /&gt;
        if advice&lt;br /&gt;
          new_advice = advice.clone&lt;br /&gt;
          new_advice.question_id = newquestion.id&lt;br /&gt;
          new_advice.save&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        if (@questionnaire.section == &amp;quot;Custom&amp;quot;)&lt;br /&gt;
          old_question_type = QuestionType.find_by_question_id(question.id)&lt;br /&gt;
          if old_question_type&lt;br /&gt;
            new_question_type = old_question_type.clone&lt;br /&gt;
            new_question_type.question_id = newquestion.id&lt;br /&gt;
            new_question_type.save&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      pFolder = TreeFolder.find_by_name(@questionnaire.display_type)&lt;br /&gt;
      parent = FolderNode.find_by_node_object_id(pFolder.id)&lt;br /&gt;
      unless QuestionnaireNode.where(parent_id: parent.id, node_object_id: @questionnaire.id)&lt;br /&gt;
        QuestionnaireNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; @questionnaire.id)&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015&amp;diff=95425</id>
		<title>CSC/ECE 517 Spring 2015</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015&amp;diff=95425"/>
		<updated>2015-03-22T17:43:45Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Writing Assignment 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Writing Assignment 1==&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 17 WL]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 5 ZX]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 6 TZ]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 4 RW]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 7 SA]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 9 RA]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 14 RI]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 1 DZ]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 20 HA]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 3 RF]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 12 LS]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 13 MA]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1a 2 WA]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1b 21 QW]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1b 23 MS]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1b 10 GL]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1b 27 VC]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1b 22 SF]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1b 15 SH]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/ch1b 18 AS]]&lt;br /&gt;
&lt;br /&gt;
==Writing Assignment 2==&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/oss E1502 wwj]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2014/oss E1508 MRS]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/oss E1504 IMV]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/oss E1505 xzl]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/oss E1509 lds]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/oss E1510 FLP]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/oss E1506 SYZ]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/oss S1504 AAC]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/oss E1507 DGO]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/oss M1502 GVJ]]&lt;br /&gt;
*[[CSC/ECE 517 Spring 2015/oss M1503 EDT]]&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93834</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93834"/>
		<updated>2015-02-16T04:08:01Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Template streaming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Examples'''=&lt;br /&gt;
==Template Streaming==&lt;br /&gt;
Some basic knowledge about how web pages are rendered can be found [http://friendlybit.com/css/rendering-a-web-page-step-by-step/ here] and also [http://www.pathinteractive.com/blog/2014/07/rendering-a-webpage-with-google-webmaster-tools/ here]. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt;Template Streaming, George Ogata https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method ''yield'' and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like ''new'' or ''edit'', it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Aproach===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;Is it live? http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;Server-sent events https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Conclusion'''=&lt;br /&gt;
The supporting for live streaming has deep impact on Rails. It not only makes Rails more competitive with Node.js, but also opens a gate for Rails to embrace lots of new areas and applications that it does not fits well before. The main advantage of Rails can be summarized as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;Installing puma on windows, Robert Kranz https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93833</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93833"/>
		<updated>2015-02-16T04:07:34Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Live Streaming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Examples'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Some basic knowledge about how web pages are rendered can be found [http://friendlybit.com/css/rendering-a-web-page-step-by-step/ here] and also [http://www.pathinteractive.com/blog/2014/07/rendering-a-webpage-with-google-webmaster-tools/ here]. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt;Template Streaming, George Ogata https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method ''yield'' and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like ''new'' or ''edit'', it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Aproach===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;Is it live? http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;Server-sent events https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Conclusion'''=&lt;br /&gt;
The supporting for live streaming has deep impact on Rails. It not only makes Rails more competitive with Node.js, but also opens a gate for Rails to embrace lots of new areas and applications that it does not fits well before. The main advantage of Rails can be summarized as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;Installing puma on windows, Robert Kranz https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93824</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93824"/>
		<updated>2015-02-16T03:38:06Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Examples'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Some basic knowledge about how web pages are rendered can be found [http://friendlybit.com/css/rendering-a-web-page-step-by-step/ here] and [http://www.pathinteractive.com/blog/2014/07/rendering-a-webpage-with-google-webmaster-tools/ here]. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt;Template Streaming, George Ogata https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method ''yield'' and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like ''new'' or ''edit'', it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;Is it live? http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;Server-sent events https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Conclusion'''=&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;Installing puma on windows, Robert Kranz https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93823</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93823"/>
		<updated>2015-02-16T03:37:40Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Examples'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Some basic knowledge about how web pages are rendered can be found [http://friendlybit.com/css/rendering-a-web-page-step-by-step/ here] and [http://www.pathinteractive.com/blog/2014/07/rendering-a-webpage-with-google-webmaster-tools/ here]. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt;Template Streaming, George Ogata https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method ''yield'' and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like ''new'' or ''edit'', it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;Is it live? http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;Server-sent events https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Benefit of live streaming'''=&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;Installing puma on windows, Robert Kranz https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93818</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93818"/>
		<updated>2015-02-16T03:22:06Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Troubleshooting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt;Template Streaming, George Ogata https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;Is it live? http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;Server-sent events https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;Installing puma on windows, Robert Kranz https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93817</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93817"/>
		<updated>2015-02-16T03:20:49Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Server-Sent Event */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt;Template Streaming, George Ogata https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;Is it live? http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;Server-sent events https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93816</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93816"/>
		<updated>2015-02-16T03:19:55Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Live Streaming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt;Template Streaming, George Ogata https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;Is it live? http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93815</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93815"/>
		<updated>2015-02-16T03:18:19Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Tweaking views */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt;Template Streaming, George Ogata https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93814</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93814"/>
		<updated>2015-02-16T03:18:07Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* When to use streaming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt;Template Streaming, George Ogata https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;ActionController::Streaming http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93813</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93813"/>
		<updated>2015-02-16T03:17:08Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Benefit of live streaming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt;Template Streaming, George Ogata https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93812</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93812"/>
		<updated>2015-02-16T03:16:01Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Template streaming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt;Template Streaming, George Ogata https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai, August 3rd, 2012 http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93811</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93811"/>
		<updated>2015-02-16T03:13:42Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Benefit of live streaming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt; https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai, August 3rd, 2012 http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93810</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93810"/>
		<updated>2015-02-16T03:13:26Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Benefit of live streaming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt; https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;Why Rails 4 Live Streaming is a big deal, Hongli Lai, August 3rd, 2012 http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/ Why Rails 4 Live Streaming is a big deal By Hongli Lai on August 3rd, 2012&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93809</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93809"/>
		<updated>2015-02-16T03:11:27Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Benefit of live streaming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt; https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/ Why Rails 4 Live Streaming is a big deal By Hongli Lai on August 3rd, 2012&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93806</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93806"/>
		<updated>2015-02-16T03:05:11Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Server-Sent Event */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt; https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in [https://en.wikipedia.org/wiki/JSON JSON] format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93805</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93805"/>
		<updated>2015-02-16T03:04:11Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Server-Sent Event */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt; https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
[https://en.wikipedia.org/wiki/Server-sent_events Server-sent event (SSE)] is a technology where browser can automatically receive update data from a server via [https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol HTTP] connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of [https://en.wikipedia.org/wiki/HTML5 HTML5] by the [https://en.wikipedia.org/wiki/World_Wide_Web_Consortium W3C]. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in JSON format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93804</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93804"/>
		<updated>2015-02-16T03:01:35Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Troubleshooting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming''] module has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt; https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
Server-sent event (SSE) is a technology where browser can automatically receive update data from a server via HTTP connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of HTML5 by the W3C. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in JSON format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original [https://en.wikipedia.org/wiki/WEBrick WEBrick] server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93802</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93802"/>
		<updated>2015-02-16T02:55:25Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Tweaking views */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming'' module] has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt; https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won't need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
Server-sent event (SSE) is a technology where browser can automatically receive update data from a server via HTTP connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of HTML5 by the W3C. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in JSON format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original WEBrick server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93801</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93801"/>
		<updated>2015-02-16T02:54:28Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Live Streaming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is further optimized in Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming'' module] has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt; https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won’t need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module [http://api.rubyonrails.org/classes/ActionController/Live.html ''::Live''] was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ''::Live'' requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ''ActionController::Live''. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ''ActionController::Live''. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
Server-sent event (SSE) is a technology where browser can automatically receive update data from a server via HTTP connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of HTML5 by the W3C. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in JSON format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original WEBrick server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93799</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 12 LS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_12_LS&amp;diff=93799"/>
		<updated>2015-02-16T02:51:45Z</updated>

		<summary type="html">&lt;p&gt;Hwang40: /* Tweaking views */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Live Streaming&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Introduction'''=&lt;br /&gt;
The purpose of live streaming is to send data over the Internet in real-time. This requires a data source, a data encoder, a media publisher and a proper network.&lt;br /&gt;
&lt;br /&gt;
In Rails, the concept of streaming first appeared in [http://weblog.rubyonrails.org/releases/ version 3.1], and is better further optimized along with Rails 4. Now Rails 4 supports live streaming, which uses handling I/O object and can send data from server to client in real-time. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
='''Details'''=&lt;br /&gt;
==Template streaming==&lt;br /&gt;
Since Rail 3.1, [http://api.rubyonrails.org/classes/ActionController/Streaming.html ''::Streaming'' module] has been added to ActionController. For example, the loading progress in a traditional Rails client-side may look like this&amp;lt;ref&amp;gt; https://github.com/oggy/template_streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:slow-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 1 progress without streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
This is because that layouts are rendered before the content, thus causing control flow to be altered to render the page in the order that the client needs (layout first).But for some resources which are static, if they could be loaded while waiting for the server response, a lot of time can be saved. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The module ''::Streaming'' inverts the regular Rails process of rendering the layout and template. Using ''::Streaming'', Rails will render template first and then layout. It will first run method yield and load up the template, and then renders the assets and layouts. In this way, the progress with streaming looks like this:&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt; &lt;br /&gt;
[[File:fast-profile.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;width: auto; margin-left: auto; margin-right: auto;&amp;quot;&amp;gt;Figure 2 progress with streaming&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===When to use streaming===&lt;br /&gt;
For actions like new or edit, it may not be that necessary to use streaming. But for expensive actions like database query and generation of large amount of data, streaming can be extremely important and effective. Take the following action as an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since most of the queries here are executing in the controller, it might take a while before them to finish, thus causing the front end (user) to wait for long. We can solve this problem and enhance user experience, the above code can be rewrite as follows,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def storyboard&lt;br /&gt;
  # Allow lazy execution of the queries&lt;br /&gt;
  @stories = Story.all&lt;br /&gt;
  @developers = Page.all&lt;br /&gt;
  @comments = Comment.all&lt;br /&gt;
  render :stream =&amp;gt; true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Note: '':Streaming'' only works with templates. It doesn’t work with :json or :xml)&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tweaking views===&lt;br /&gt;
When using streaming, instance variables that are set in the template and are used in the layout won’t need some tweak to work well. This is done by using content_for, provide and yield.&lt;br /&gt;
Here’s a simple example where the layout expects the template to tell which title to use&amp;lt;ref&amp;gt;http://apidock.com/rails/ActionController/Streaming&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= yield :title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of yield, we can also use content_for to specify the title: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if content_for is called several times, the final result would have all calls concatenated.&lt;br /&gt;
For instance, if we have the following template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The final result would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that, if you have yield '':title'' in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For instance, the template above using provide would be: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= provide :title, &amp;quot;Main&amp;quot; %&amp;gt;&lt;br /&gt;
Hello&lt;br /&gt;
&amp;lt;%= content_for :title, &amp;quot; page&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Giving:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Main&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Live Streaming==&lt;br /&gt;
The module ''::Live'' was then added to ActionController at Rail 4. The difference between Streaming and Live is that Streaming is implicitly included whenever you create a new controller class, while ::Live requires explicit include.&lt;br /&gt;
&lt;br /&gt;
===Traditional Response===&lt;br /&gt;
In this type of communication between server and client, data will be buffered until all render works are finished, and everything will be sent to the client at the same time. And the stream object behaves just like an IO object. Here’s the sample code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a response message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When we run the code above, the web page will '''keep loading and remain blank''' for 8 seconds, and shows all 8 lines of “This is a response message!” altogether, as with the following image shows:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:nostreaming.gif]]&lt;br /&gt;
&lt;br /&gt;
===Live Streaming===&lt;br /&gt;
In order to enable live streaming, we need to include a module named ActionController::Live. When this module is mixed into the controller, all actions within that controller will be able to stream data to the client in real time, like the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MessageController &amp;lt; ApplicationController&lt;br /&gt;
 #here we enabled live streaming&lt;br /&gt;
 include ActionController::Live&lt;br /&gt;
 def message&lt;br /&gt;
   response.headers[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/event-stream&amp;quot;&lt;br /&gt;
   8.times {&lt;br /&gt;
     response.stream.write &amp;quot;This is a live streaming message!\n&amp;quot;&lt;br /&gt;
     sleep 1&lt;br /&gt;
   }&lt;br /&gt;
 ensure&lt;br /&gt;
   response.stream.close&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above code looks exactly the same as the traditional response, except the newly included module ActionController::Live. Now '''data can be streamed to the client immediately whenever write method is called'''. When we run the code above, the web page will print one line “This is a response message!” for every seconds and repeats 8 times.&amp;lt;ref&amp;gt;http://tenderlovemaking.com/2012/07/30/is-it-live.html&amp;lt;/ref&amp;gt; Like the image shows below:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:streaming.gif]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server-Sent Event==&lt;br /&gt;
Server-sent event (SSE) is a technology where browser can automatically receive update data from a server via HTTP connection. Whenever server sends data, the SSE method in the browser will trigger an event.The SSE EventSource API is standardized as part of HTML5 by the W3C. It can be used together with the Live API to achieve full-duplex communication.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Server-sent_events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A simple SSE looks like the following :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'json' &lt;br /&gt;
module ServerSide&lt;br /&gt;
  class SSE&lt;br /&gt;
    def initialize io&lt;br /&gt;
      @io = io&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def write object, options = {}&lt;br /&gt;
      options.each do |k,v|&lt;br /&gt;
        @io.write &amp;quot;#{k}: #{v}n&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      @io.write &amp;quot;data: #{object}nn&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    def close&lt;br /&gt;
      @io.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This module assigns the I/O stream object to a hash and converts it into a key-value pair so that it is easy to read, store, and send it back in JSON format.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Now we can wrap stream object inside the SSE class. By doing this, we need to include SSE module inside the controller, so that the opening and closing of connections will be managed by SSE module. And we also add the ensure clause to make sure that the connection will always be closed after execution.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sse' &lt;br /&gt;
class MessagingController &amp;lt; ApplicationController&lt;br /&gt;
  include ActionController::Live&lt;br /&gt;
 &lt;br /&gt;
  def stream&lt;br /&gt;
    response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    sse = SSE.new(response.stream)&lt;br /&gt;
    begin&lt;br /&gt;
      5.times {&lt;br /&gt;
        sse.write(“Streaming using SSE!”)&lt;br /&gt;
        sleep 1&lt;br /&gt;
      }&lt;br /&gt;
    ensure&lt;br /&gt;
      sse.close&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The code above will print the sentence “Streaming using SSE!” once per second, until the loop ends.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here’s another sample showing how to use SSE to stream data&amp;lt;ref&amp;gt;https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    # This class provides the ability to write an SSE (Server Sent Event)&lt;br /&gt;
    # to an IO stream. The class is initialized with a stream and can be used&lt;br /&gt;
    # to either write a JSON string or an object which can be converted to JSON.&lt;br /&gt;
    #&lt;br /&gt;
    # Writing an object will convert it into standard SSE format with whatever&lt;br /&gt;
    # options you have configured. You may choose to set the following options:&lt;br /&gt;
    #&lt;br /&gt;
    #   1) Event. If specified, an event with this name will be dispatched on&lt;br /&gt;
    #   the browser.&lt;br /&gt;
    #   2) Retry. The reconnection time in milliseconds used when attempting&lt;br /&gt;
    #   to send the event.&lt;br /&gt;
    #   3) Id. If the connection dies while sending an SSE to the browser, then&lt;br /&gt;
    #   the server will receive a +Last-Event-ID+ header with value equal to +id+.&lt;br /&gt;
    #&lt;br /&gt;
    # After setting an option in the constructor of the SSE object, all future&lt;br /&gt;
    # SSEs sent across the stream will use those options unless overridden.&lt;br /&gt;
    #&lt;br /&gt;
    # Example Usage:&lt;br /&gt;
    #&lt;br /&gt;
    #   class MyController &amp;lt; ActionController::Base&lt;br /&gt;
    #     include ActionController::Live&lt;br /&gt;
    #&lt;br /&gt;
    #     def index&lt;br /&gt;
    #       response.headers['Content-Type'] = 'text/event-stream'&lt;br /&gt;
    #       sse = SSE.new(response.stream, retry: 300, event: &amp;quot;event-name&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'})&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;)&lt;br /&gt;
    #       sse.write({ name: 'John'}, id: 10, event: &amp;quot;other-event&amp;quot;, retry: 500)&lt;br /&gt;
    #     ensure&lt;br /&gt;
    #       sse.close&lt;br /&gt;
    #     end&lt;br /&gt;
    #   end&lt;br /&gt;
    #&lt;br /&gt;
    # Note: SSEs are not currently supported by IE. However, they are supported&lt;br /&gt;
    # by Chrome, Firefox, Opera, and Safari.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: By default Rails provides a one-way communication process by writing the stream to the client when data is available. However, if we can add SSEs, we can enable events and responses, thus making it two-way.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefit of live streaming==&lt;br /&gt;
1.Send partial responses to the client immediately.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
2.Using Server-sent events, the ability to create chat clients, push notifications, and real-time feeds are available within Rails itself&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
3.Continuously inform the user about the progress.&lt;br /&gt;
See example below&amp;lt;ref&amp;gt;http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def big_work&lt;br /&gt;
  work = WorkModel.new&lt;br /&gt;
  while !work.done?&lt;br /&gt;
    work.do_some_calculations&lt;br /&gt;
    response.stream.write &amp;quot;Progress: #{work.progress}%\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  response.stream.close&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''Troubleshooting'''=&lt;br /&gt;
When running streaming programs, we need to install [http://puma.io/ PUMA] to substitute the original WEBrick server, because puma can handle concurrency better. In order to do this, we need to add the following line to Gemfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'puma'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
After installed puma, if we start rails server, the console will print the following output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files (x86)\JetBrains\RubyMine 7.0.2\bin\runnerw.exe&amp;quot; C:\RailsInstaller\Ruby2.0.0\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/Cloud/Coding/RubymineProjects/LiveStreamingExample/bin/rails server -b 127.0.0.1 -p 3000 -e development&lt;br /&gt;
=&amp;gt; Booting Puma&lt;br /&gt;
=&amp;gt; Rails 4.1.8 application starting in development on http://127.0.0.1:3000&lt;br /&gt;
=&amp;gt; Run `rails server -h` for more startup options&lt;br /&gt;
=&amp;gt; Ctrl-C to shutdown server&lt;br /&gt;
Puma 2.11.0 starting...&lt;br /&gt;
* Min threads: 0, max threads: 16&lt;br /&gt;
* Environment: development&lt;br /&gt;
* Listening on tcp://127.0.0.1:3000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that PUMA is set as our default server and successfully booted.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
We encountered failure on Windows when trying to install PUMA, the console printed the following error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Building native extensions.  This could take a while...&lt;br /&gt;
ERROR:  Error installing rails:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
&lt;br /&gt;
/Users/WillieTran/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb&lt;br /&gt;
*** extconf.rb failed ***&lt;br /&gt;
&lt;br /&gt;
Could not create Makefile due to some reason, probably lack of necessary&lt;br /&gt;
libraries and/or headers.  Check the mkmf.log file for more details.  You may&lt;br /&gt;
need configuration options.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To solve this problem, we need to install [https://www.openssl.org/ openssl] for windows. And then run the following command&amp;lt;ref&amp;gt;https://github.com/hicknhack-software/rails-disco/wiki/Installing-puma-on-windows&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem install puma -- --with-opt-dir=c:\openssl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
='''References'''=&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hwang40</name></author>
	</entry>
</feed>