Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Maintain an available instance list. #19

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 143 additions & 36 deletions peerserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// SPDX-License-Identifier: Apache-2.0

// Prepare for web server
var fs = require("fs");
var path = require("path");
var fs = require('fs');
var path = require('path');
var url = require('url');
var config = require('./config');
var account = require('./vendormodule');
Expand All @@ -17,19 +17,80 @@ var httpsOptions = {

var app = require('express')();
var server = app.listen(config.port.plain);
var servers = require("https").createServer(httpsOptions, app).listen(config.port.secured);
var servers = require('https').createServer(httpsOptions, app).listen(config.port.secured);
var io = require('socket.io').listen(server);
var ios = require('socket.io').listen(servers);

var sessionMap = {}; // Key is uid, and value is session object.
var instanceList = new Array();
var clientId = 1000;

function addInstance(uid){
var i = 0;
while(i < instanceList.length && instanceList[i] != uid){
++i;
}
if(i == instanceList.length){
instanceList.push({uid:uid, available:1});
}
}

function deleteInstance(uid){
for(var i = 0; i < instanceList.length; ++i){
if(instanceList && instanceList[i].uid == uid){
instanceList.splice(i, 1);
return;
}
}
}

function changeToIdle(uid){
for(var i = 0; i < instanceList.length; ++i){
if(instanceList && instanceList[i].uid == uid){
instanceList[i].available = 1;
return;
}
}
}

function changeToOccupy(uid, state){
for(var i = 0; i < instanceList.length; ++i){
if(instanceList && instanceList[i].uid == uid){
instanceList[i].available = 0;
return;
}
}
}

function isExist(uid){
if(!instanceList){
return -1;
}
for(var i = 0; i < instanceList.length; ++i){
if(instanceList[i].uid == uid){
if(instanceList[i].available == 1){
return 1;
}else{
return 2;
}
}
}
return 0;
}

function logNumber(){
var sessionMapkeys = Object.keys(sessionMap);
var clientNum = sessionMapkeys.length - instanceList.length;
console.log('Client number: ' + clientNum + ' ; Instance number: ' + instanceList.length);
}

// Check user's token from partner
function validateUser(token, successCallback, failureCallback){
// TODO: Should check token first, replace this block when engagement with different partners.
if(token){
account.authentication(token,function(uid){
account.authentication(token, function(uid){
successCallback(uid);
},function(){
}, function(){
console.log('Account system return false.');
failureCallback(0);
});
Expand All @@ -39,11 +100,11 @@ function validateUser(token, successCallback, failureCallback){
}

function disconnectClient(uid){
if(sessionMap[uid]!==undefined){
var session=sessionMap[uid];
if(sessionMap[uid] !== undefined){
var session = sessionMap[uid];
session.emit('server-disconnect');
session.disconnect();
console.log('Force disconnected '+uid);
console.log('Force disconnected ' + uid);
}
}

Expand All @@ -56,7 +117,7 @@ function createUuid(){

function emitChatEvent(targetUid, eventName, message, successCallback, failureCallback){
if(sessionMap[targetUid]){
sessionMap[targetUid].emit(eventName,message);
sessionMap[targetUid].emit(eventName, message);
if(successCallback)
successCallback();
}
Expand All @@ -66,66 +127,112 @@ function emitChatEvent(targetUid, eventName, message, successCallback, failureCa
}

function authorization(socket, next){
var query=url.parse(socket.request.url,true).query;
var token=query.token;
var clientVersion=query.clientVersion;
var clientType=query.clientType;
var query = url.parse(socket.request.url, true).query;
var clientVersion = query.clientVersion;
var clientType = query.clientType;
var isClient = query.isClient;
if(isClient){
token = (clientId++) + '';
}else{
token = query.token;
}
switch(clientVersion){
case '4.2':
case '4.2.1':
case '4.3':
// socket.user stores session related information.
if(token){
validateUser(token, function(uid){ // Validate user's token successfully.
socket.user={id:uid};
console.log(uid+' authentication passed.');
},function(error){
// Invalid login.
socket.user = {id:uid, isClient:isClient, instanceId:null};
if(!isClient){
console.log('Instance ' + uid + ' authentication passed.');
addInstance(uid);
}else{
console.log('Client ' + uid + ' authentication passed.');
}
}, function(error){
// Invalid login.
console.log('Authentication failed.');
next();
});
}else{
socket.user=new Object();
socket.user.id=createUuid()+'@anonymous';
console.log('Anonymous user: '+socket.user.id);
socket.user = new Object();
socket.user.id = createUuid() + '@anonymous';
console.log('Anonymous user: ' + socket.user.id);
}
next();
break;
default:
next(new Error('2103'));
console.log('Unsupported client. Client version: '+query.clientVersion);
console.log('Unsupported client. Client version: ' + query.clientVersion);
break;
}
}

function onConnection(socket){
// Disconnect previous session if this user already signed in.
var uid=socket.user.id;
var uid = socket.user.id;
var isClient = socket.user.isClient;
disconnectClient(uid);
sessionMap[uid]=socket;
socket.emit('server-authenticated',{uid:uid}); // Send current user's id to client.
console.log('A new client has connected. Online user number: '+Object.keys(sessionMap).length);
sessionMap[uid] = socket;
socket.emit('server-authenticated', {uid:uid}); // Send current user's id to client.
logNumber();
if(isClient){
socket.on('disconnect-instance', function (data) {
console.log('Client ' + uid + ' disconnect with instance ' + data.to);
changeToIdle(data.to);
});
}

socket.on('disconnect',function(){
socket.on('disconnect', function(){
if(socket.user){
var uid=socket.user.id;
var uid = socket.user.id;
var isClient = socket.user.isClient;
// Delete session
if(socket===sessionMap[socket.user.id]){
if(socket === sessionMap[socket.user.id]){
delete sessionMap[socket.user.id];
}
console.log(uid+' has disconnected. Online user number: '+Object.keys(sessionMap).length);
if(isClient){
console.log('Client ' + uid + ' disconnect with server.');
if(socket.user.instanceId != null){
changeToIdle(socket.user.instanceId);
}
}else{
console.log('Instance ' + uid + ' disconnect with server.');
deleteInstance(uid);
}
logNumber();
}
});

socket.on('build-p2p-connect', function(data, callback){
var m = isExist(data.to);
callback(false, m);
if(m == -1){
console.log('Error: instanceList does not exist.');
}else if(m == 0){
console.log('Instance ' + data.to + ' does not exist.');
}else if(m == 1){
console.log('Instance ' + data.to + ' is available.');
changeToOccupy(data.to);
}else if(m == 2){
console.log('Instance ' + data.to + ' is occupied.');
}
});

// Forward events
var forwardEvents=['owt-message'];
for (var i=0;i<forwardEvents.length;i++){
socket.on(forwardEvents[i],(function(i){
var forwardEvents = ['owt-message'];
for(var i = 0; i < forwardEvents.length; i++){
socket.on(forwardEvents[i], (function(i){
return function(data, ackCallback){
data.from=socket.user.id;
var to=data.to;
console.log('Received ' + forwardEvents[i] + ' : ' + JSON.stringify(data));
data.from = socket.user.id;
var to = data.to;
if(socket.user.isClient){
socket.user.instanceId = to;
}
delete data.to;
emitChatEvent(to,forwardEvents[i],data,function(){
emitChatEvent(to, forwardEvents[i], data, function(){
if(ackCallback)
ackCallback();
},function(errorCode){
Expand All @@ -139,7 +246,7 @@ function onConnection(socket){

function listen(io) {
io.use(authorization);
io.on('connection',onConnection);
io.on('connection', onConnection);
}

listen(io);
Expand Down