Real Time

KambojaJS support real time interaction between server and client code using websocket/polling technique. It uses socket.io library as its core function.

The main problem of common MVC framework and common real time framework is the fact that they are separate process. Websocket and http request is separate process it needs further trick to share request data like cookie, authentication etc. Thus make simple task like sending real time message to specific login user complicated.

KambojaJS provide a simple API to broadcast message or send real time message to specific user. It is possible to send real time message from any controller. It means you can create a controller which handle http post request and combined with sending real time message to related users.

Example Code There is a simple example of using real time functionalities here built using Jquery on the client side so everyone will understand the code.

Enable Real Time Functionalities

KambojaJS doesn’t enable real time functionalities by default. You can enable real time functionalities by applying RealTimeFacility in the KambojaApplication

import { KambojaApplication } from "kamboja-express"
import { RealTimeFacility } from "kamboja-socket.io"
import * as BodyParser from "body-parser"

export const app = new KambojaApplication(__dirname)
    //this step will enable real time functionalities
    .apply(new RealTimeFacility())
    .use(BodyParser.urlencoded({ extended: false }))
    .use(BodyParser.json())
    .init();

By applying RealTimeFacility like above KambojaJS then ready to send/receive websocket event.

Note If you are curious about facility, check the documentation about facility

Send/Broadcast Message To Client Code

Sending real time message to client code simply by calling emit() or broadcast() method of ActionResult. There is a shorthand function to do that.

import { Controller, route, json } from "kamboja-express"

export class PostController extends Controller {
    @route.post()
    save(@bind.body() body:any){
        return json({ message:"Success!" })
            .emit("message", [<user ids>])
    }
}

Above code showing common KambojaJS controller which handle POST request to /post/save. Controller will return JSON { "message": "Success" } and it will send the result to appropriate users listed in [<user id>].

In the client side you use socket.io JavaScript client like below:

//client side
var socket = io({ query: { token: <login token> }});
socket.on("message", function(msg){
    //code block that will be executed when POST /post/save requested
})

Handle socket.io Events On Server Side

KambojaJS provide convenient way to handle socket event by using @route.on(). You can listen to all socket.io event for example connection, disconnect, including custom event sent by client code.

import { Controller, route, broadcast } from "kamboja-express"

export class UserController extends Controller {
    @route.on("connection")
    join(){
        return broadcast("presence/join", this.context.user.id)
    }

    @route.on("disconnect")
    leave(){
        return broadcast("presence/leave", this.context.user.id)
    }
}

Above code is simple presence system that will broadcast the user id when user connected and disconnected. To listen to custom event simply @route.on() the appropriate event on specific controller action

import { Controller, route, emit } from "kamboja-express"

export class UserController extends Controller {
    @route.on("send-message")
    send(msg: { to:string, message:string }){
        return emit("message", msg.to, msg.message)
    }
}

Above code will listen to send-message event and emit a message event to specific user defined on to property in action parameter. On client side you simply do this:

//client side
var socket = io({ query: { token: <login token> }});
socket.emit("send-message", { to: <user id>, message: "Hello world!" },  function(msg) {
    //this code will be executed when message received by server
})

Authentication Integration

In order to send event to specific user you need to integrate the authentication system manually. KambojaJS doesn’t have built-in authentication functionality yet, but soon in milestone 0.5 will be implemented.

You can use any existing authentication middleware for example passport (see example integration with passport).

KambojaJS real time functionality will look for the context.user.id and create a lookup table with appropriate socket id. So your task is fill the context.user.id with proper user id on each request.

If you are using passport, you need to return a user with id in the done callback on the strategy like this, and that’s it.

If you are using custom authentication using KambojaJS middleware you just need to set the context.user.id properly like this