Oracle apex chat demo
Tags: orclapex, apex5, node, socketio
Published: 2017-04-12 19:32:52

---
title: Oracle apex chat demo
published: true
description: 
cover_image: https://thepracticaldev.s3.amazonaws.com/i/l1ylzvx7raym9bc41b0a.jpg
tags: orclapex, apex5, nodejs, socket.io
---
A week before or two I published on [apex.oracle.com](https://goo.gl/eiE0TZ) simple apex chat demo. It is demo about how to integrate oracle apex and socket.io (node.js). 

## Basics, part I: Oracle apex
Oracle apex is a rapid web application development tool for the Oracle database. Using only a web browser and limited programming experience, you can develop and deploy professional applications that are both fast and secure.

## Basics, part II: Socket.io 
Socket.io is a JavaScript library (uses websockets, more info on [wiki](https://en.wikipedia.org/wiki/WebSocket)) for realtime web applications. It enables realtime, bi-directional communication between web clients and servers. It has two parts: a client-side library that runs in the browser, and a server-side library for Node.js. Both components have a nearly identical API. Like Node.js, it is event-driven. 

## Proof of concept
![alt text](https://thepracticaldev.s3.amazonaws.com/i/8vta2nx01xmx41sf334y.png)
Concept was to developed apex region plugin that uses socket.io javascript library for realtime interaction with node.js. Socket.io is composed of two parts, one is included on client side and the other is installed on server side. They communicate through websocket which uses 101 switching protocols to send and receive data. So when message is send to server side, server side propagate the same message to all active socket.io sessions. Also you can see from the concept, that messages are not stored in database. 

## Client side
On client side apex chat is designed as apex region plugin. Witch uses these js libraries:
  - [handlebars.js](http://handlebarsjs.com/) -> compiles html forms with data
  - [socket.io client side](https://github.com/socketio/socket.io-client) -> client side lib. for realtime communication between web clients and servers.
  - [jquery witch is included in apex](https://docs.oracle.com/database/121/HTMDB/app_comp001.htm#HTMDB29024) 

Beside controling the html form, it also listen for propagated events from websocket and triggers the same in order to send data. 

## Server side, node.js
Server side is developed in node.js with multiple packages. Underneath there is a list of used packages and short description with links. Comunication with client is through websocket.

1. [Express.js](https://expressjs.com/) & [http](https://nodejs.org/api/http.html) - used to create http server 
2. [socket.io](https://github.com/socketio/socket.io) - server side library for websockets
3. [winston](https://github.com/winstonjs/winston) - logger
4. [mkdirp](https://github.com/substack/node-mkdirp) - 'mkdir -p', creates log folder
5. [ip](https://github.com/indutny/node-ip) - IP address utilities

```javascript
...
    const express = require('express');
    const http = require('http');
    const socketio = require('socket.io');
    const winston = require('winston');
    const mkdirp = require('mkdirp');
    const ip = require("ip");
...
```
## Socket events
Socket.io is event-driven library, that means communication goes by **triggering** events and there **registration**. On server side triggering is done in **emit function**. If on socket object is not set **room** property chat then broadcast event to all open socket sessions. 

```javascript
...
var emit = function(emitCmd, data){
...
    if (socket.room !== undefined){
        socket.in(socket.room).broadcast.emit(emitCmd, data);
    } else {
        socket.broadcast.emit(emitCmd, data);
    }
 }
...
emit("new.message", {
    username: socket.username,
    message : data
});
...
```
and this is how event is registered on server side:

```javascript
...
socket.on("add.user", function (data) {
...
    socket.username = data.username;
    emit("user.joined", {
        username: socket.username
     });
});
...
```
So when on client side is triggered event **"add.user"** (in demo when user set there own username), on server side socket.io catch that event and triggers to all others socket.io session **"user.joined"** event.

on client side this is much simpler, triggering example:

```javascript
...
this.socket.emit("new.message", msg);
...
```

and there registration:

```javascript
...
this.socket.on("user.joined", function(data) {
      ...
}.bind(this));
...
```

List of events that are triggered on client side, note that this events are registered on server side:
1. **public** - send flag that this chat is public is available to everyone
2. **set.room** - send flag that this chat is private
3. **typing** - send flag that user has started to type in message area
4. **stop.typing** - send stop typing flag
5. **new.message** - send new message to server side for propagation to other sessions

List of events that are registered on client side, there are triggered on server side:
1. **user.joined** - received data from server that user has joined in your chatroom, create notification in chat region
2. **typing** - received data from server that user has started typing, create typing info in chat region
3. **stop.typing** - received data from server that user has stopped typing, remove  typing info in chat region
4. **new.message** - received new message from server, display message in chat region
5. **user.left** - received data from server that user has left your chatroom (socket.io session is terminated), create notification in chat region


## Monitoring network between client and server

Now for this, I used google developer tools for screenshot. In your **developer tools** under **network** tab, and **WS** you can see all traffic (under **Frame** tab you can see text message that are sended/received) that is currently comming and going. 
![alt text](https://thepracticaldev.s3.amazonaws.com/i/7arovjjr9oaijod6telu.png)

![alt text](https://thepracticaldev.s3.amazonaws.com/i/pp5c98d5nufvg5qie8zd.png)


## Deploying on [apex.oracle.com](https://goo.gl/eiE0TZ) / [OpenShift Online](https://www.openshift.com/)

Since websocket can do cross-domain (but you will need to have a handshake in order to get this going), I installed plugin on [apex.oracle.com](https://goo.gl/eiE0TZ) and node.js module (server side socket.io) is installed on [OpenShift Online](https://www.openshift.com/). OpenShift Online is Red Hat's public cloud application development and hosting platform that automates the provisioning, management and scaling of applications so that you can focus on writing the code for your business, startup, or big idea. OpenShift Online supports a variety of technologies through use of cartridges, including Java, PHP, Node.js, Python, Perl, MySQL, PostgreSQL, MongoDB, Jenkins, Cron, and more.


## The future of apex chat demo
Right now all code/project is available at [github](https://goo.gl/i8sXNq).
Note that it is still work in progress. The passed few weeks I received a huge, huge feedback which I am very thankful for. 

![alt text](https://media.giphy.com/media/JltOMwYmi0VrO/giphy.gif)

I also encourage you to submit ideas to [github issue page](https://github.com/isabolic/apex-chat-region/issues) and tag them with label **New feature**.