Wednesday 2 March 2016

Real-time E-Mail Box for Web Projects?



Introduction

After an intensive research online & offline am now going to illustrate how we can construct a real-time Mail box.
This is due to the fact I would like to create a plug-in that web masters and developers can use to integrate to their sites allowing a user view incoming mails without having to refresh their page.
This will uses a streaming technique to push data to the user interface.
This is best achieved through web socket programming.
Without saying much, the prerequisites are:


1.      J-query Lib
2.      Data tables
3.      Php scripting language
4.      Light streamer Server
5.      Php Imap Library
6.      Eclipse
7.      Web server (Am using Apache 2.2)

Briefly explaining the need of each of the above, j-query lib is a requirement if you need to use the data table plug-in , which allows you to create grid UI for your web pages , Php will be a server end that will reside in the server allowing us to fetch our emails from our mail box may they be Imap or pop 3. Eclipse IDE will help us assemble a custom adapter that we are going to build in Java language. An adapter will perform an interface between data fetched from the mailbox using the Php Library and link it to our web socket that we can finally consume it on our page. Lastly the light streamer server that will perform a useful functionality in creating a socket communication with our web page.

Creating the data Adapter.
Open the eclipse IDE,just assuming this has already been installed in your PC.

 

 Create a new Java Project,

 

 Then create a package in it,for my package I call it  mundia.mail.adapter as shown :

 

Right Click on the package an create a Java class, an call it FetchClass :

 
 Import the libraries as shown below:




The yellow marked might not be in use for now.
The rest of the code is as shown,

public class FetchMail implements SmartDataProvider
                                                {
                       
                                                private ItemEventListener listener;
                                                private volatile myThread gt;
                                                private Connection conn;
                                                                                               
                                               public void init(Map params, File configDir) throws DataProviderException   {
                                                                                                                       

                                                                                                                        }
                                                                                               
                                             public boolean isSnapshotAvailable(String itemName) throws SubscriptionException {
                                                                                                                          return false;
                                                                                                                        }
                                              public void setListener(ItemEventListener listener)  {
                                                                                                                          this.listener = listener;
                                                                                                                        }
                                                                                               
                                            public void subscribe(String itemName, Object itemHandle, boolean needsIterator)
                                                   throws           SubscriptionException, FailureException {
                                                                      if (itemName.equals("mydataitem"))  {
                                                                                                                            this.gt = new myThread(itemHandle);
                                                                                                                            this.gt.start();
                                                                                                                          }
                                                                                                                        }
                                                                                               
                                            public void subscribe(String itemName, boolean needsIterator)  
                                                    throws SubscriptionException, FailureException  {
                                                                     if (itemName.equals("mydataitem")) {
                                                                                                                            this.gt = new myThread(null);
                                                                                                                            this.gt.start();
                                                                                                                          }
                                                                                                                        }
                                                                                               
                                           public void unsubscribe(String itemName)  
                                                               throws SubscriptionException, FailureException{
                                                                         if ((itemName.equals("mydataitem")) && (this.gt != null)) {
                                                                                                    this.gt.go = false;
                                                                                                  }
                                                                                                }
                                                                                               
                                                                                               
                                                                                               
                                          class myThread extends Thread  {


                                                private final Object itemHandle;
                                                public volatile boolean go = true;
                                                                                                 
                                              public myThread(Object itemHandle) {
                                                                    this.itemHandle = itemHandle;
                                                                                }
                                                                                                 
                                             public void run()  {

                                                             URL url = null;
                                                                                                   
                                                                             while (this.go)  {
                                                                                        try{
                                                                                                     try {                                                                                                                                    
                                                                                                                        url = new URL("http://localhost//stream_data.php");
                                                                                                                          
                                                                                                        } catch (MalformedURLException e1) {                                                                                                                                   
                                                                                                                                                                                    e1.printStackTrace();
                                                                                                                                                                                  }
                                                                                                                          
                                                                                                                                                    BufferedReader in = null;
                                                                                                                                                                        try {
                                                                                                                                                                                     in = new BufferedReader(new InputStreamReader(url.openStream()));
                                                                                                                                                                        } catch (IOException e1) {                                            
                                                                                                                                                                                     e1.printStackTrace();
                                                                                                                                                                        }
                                                                                                                                                                       
                                                                                                                                                    String inputLine;
                                                                                                                                                    StringBuilder sb = new StringBuilder();
                                                                                                                                                    try {
                                                                                                                                                                                while ((inputLine = in.readLine()) != null){
                                                                                                                                                                                                                       
                                                                                                                                                                                 Map<String, String> data = new HashMap();
                                                                                                                                                                                 data.put("streaming_data",inputLine);
                                                                                                                                                                                 FetchMail.this.listener.smartUpdate(this.itemHandle, data, false);
                                                                                                                                                                                                                       
                                                                                                                                                                                                    System.out.println(inputLine);
                                                                                                                                                                                                    sb.append(inputLine);
                                                                                                                                                                                                }
                                                                                                                                                                        } catch (IOException e) {
                                                                                                                                                                                                // TODO Auto-generated catch block
                                                                                                                                                                                                e.printStackTrace();
                                                                                                                                                                        }
                                                                                                                                                   
                                                                                                                                                    try {
                                                                                                                                                                                     in.close();
                                                                                                                                                                        } catch (IOException e) {
                                                                                                                                                                                     // TODO Auto-generated catch block
                                                                                                                                                                                       e.printStackTrace();
                                                                                                                                                                        }                                                                                                                        
                                                                                               
                                                                                                      }
                                                                                                      catch (Exception ex)
                                                                                                      {
                                                                                                        Map<String, String> data = new HashMap();
                                                                                                        data.put("streaming_data", "Error detected"+ex);
                                                                                                        data.put("timestamp", "00:00:00.000");
                                                                                                        FetchMail.this.listener.smartUpdate(this.itemHandle, data, false);                                                                                         
                                                                                                        System.out.println(ex);
                                                                                                      }
                                                                                                      try
                                                                                                      {
                                                                                                        Thread.sleep(0);
                                                                                                      }
                                                                                                      catch (InterruptedException localInterruptedException) {}
                                                                                                    }
                                                                                                  }
                                                                                                }
}

Brief explanation of the above code,
Most of the code above is native light-streamer methods of handling subscription, I have added a new class called myThread, this is invoked and supplies data to the map object of the light-streamer. The data is fetched on the line with: url = new URL("http://localhost//stream_data.php");.
On eclipse file menu go to export and export the project as a compiled jar file in your desktop.

Php Server side.
The php server side is simple a file that will create a connection to your mail server and supply data, as shown below.

 


Just above your Php file set the include of your Imap library as : 
<?php
require_once("PhpImap/__autoload.php");
Save this file in your web server (Apache) as stream_data.php
Try running it on your browser you should have some output as shown:





The above is a preview of data that will be polled from my mail box.
Being a little more precise the data from your php file should be in form of json format as shown:





Let’s now set our Light-streamer up,
Download the light streamer library from its official site, it is a zipped folder that you can download on your server.
After the download, look inside it for a folder titled adapter; set your light streamer adapter that we created in our first section here. It should look as below:











Where the file adapters give a name to our adapter and its properties to the lightstreamer server.The folder Lib contains out compiled java source code (.jar) file.


Navigate on the root of the light-streamer folder where you find the bin/windows folder run the file called Start_LS_as_Application.bat and start your light-streamer server.
It should start fine, listening to port 8080.
Check on the log to ensure that it has loaded your adapter.

Client side development
This will now develop the client end where the user can view new mails that are being streamed from his her mailbox.
Firstly ensure that you have your root folder in your web server with the j-query libraries and Data tables plugins,create an index file and include your JavaScript libraries as shown.

 

Note also the light streamer libraries included .
After including,
Include a connection to your lightstreamer server as shown below:


 
Note the function handleStreamingContent()  that will handle data being streamed back to the user.The complete function is shown below:

 

The statement   $('#myStreamingTable').dataTable()  will call the datatable which is now created with the code below:

 


Note the empty dataset that I will use to initialize the data table, and compare it with that functions that populate the table in the function  handleStreamingContent()   .
The table is created in a table object that you set on your body of the html documents as shown:

 
I will now try out our output on a browser, which will now show the complete assembly working as below:

 


A new message will be loaded as the first you don’t have to navigate, or refresh the page, checking on my task manager, no much overhead required. Hmmm some of my personal mail just loaded  J
You are free to contact me for implementing this awesome plug-in in your web projects.
My throbbing light-streamer server performance is as shown:


 


Once again you are free to contact me for implementing this awesome plug-in in your web projects.

Much thanks to Allan Jardine – Founder SpryMedia Ltd

No comments:

Post a Comment