Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature images #2

Merged
merged 10 commits into from
Oct 27, 2020
Next Next commit
New feature Added: imageMessage suport
  • Loading branch information
mscarceller committed Oct 23, 2020
commit a3c135dd8e4dc718677601abce4b83d9d9a1d8e4
305 changes: 190 additions & 115 deletions EFTGCA-MessagesLib/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const WebSocket = require('isomorphic-ws');
const axios = require('axios')
let EventEmitter = require('events').EventEmitter;
var uuid = require('uuid');
let EventEmitter = require('events').EventEmitter

const WEBSOCKET_STATE = {
CONNECTING: 0,
Expand All @@ -19,21 +20,26 @@ const EVENT_ONCLOSE = "closedConnection";
const EVENT_NEW_USER = "newUser";
const EVENT_RECONNECT = "reconnect";
const EVENT_TEXT_MESSAGE = "textMessage";
const EVENT_IMAGE_MESSAGE = "imageMessage";

// Methods read/write from/into the socket
const METHOD_NEW_USER = "newUser";
const METHOD_TEXT_MESSAGE = "textMessage";
const METHOD_IMAGE_MESSAGE = "imageMessage";
const METHOD_JOIN_ROOM = "joinRoom";
const METHOD_RECONNECT = "reconnect";

class ChatMessagesManager extends EventEmitter {

constructor(url) {
constructor(wsurl,apiurl,verbose=false) {

super();
this.url = url;
this.wsurl = wsurl;
this.apiurl = apiurl;
this.verbose = verbose;
this.webSocket = null;
this.messageId = 1;

this.sessionId = uuid.v4();
this.userId = "";
this.roomName = "";
Expand All @@ -42,14 +48,17 @@ class ChatMessagesManager extends EventEmitter {
this.messages = new Map();
this.serviceMessages = new Map();
this.pendingMessages = new Map();

this.connectWebSocket().then(() => {
console.log("WebSocket initializated succesfully");
})

this.imageAPIOptions = {
host: this.apiurl,
path: "/images",
method: "POST",
headers: {"Content-Type": "application/json"}
};

this.reconnectUser = function(){
let self = this;
console.log("Reconnecting user...");
if(this.verbose) console.log("Reconnecting user...");
let id = this.getNewId()
let reconnectMessage = {
jsonrpc: JSONRPC_VERSION,
Expand All @@ -76,126 +85,181 @@ class ChatMessagesManager extends EventEmitter {
}
return null;
}
}

getMessages(){
return this.messages;
}

getServiceMessages(){
return this.serviceMessages;
}

getPendingMessages(){
return this.pendingMessages;
}

connectWebSocket() {
let self = this;
console.log("Connecting to " + this.url);
return new Promise((resolve, reject) => {

this.webSocket = new WebSocket(this.url);

this.webSocket.onopen = () => {
this.webSocket.addEventListener("message", (message) => {
this.decodeMessage(JSON.parse(message.data));
});
self.emit(EVENT_CONNECTED, null);
resolve(this);
};

this.webSocket.onerror = function(err) {
self.emit(EVENT_ERROR, err);
};

this.webSocket.onclose = function(event) {
self.emit(EVENT_ONCLOSE, event);
setTimeout(function() {
self.reconnectUser();
}, 5000)
};
});
}
this.connectWebSocket = function() {
let self = this;
if(this.verbose) console.log("Connecting to " + this.wsurl);
return new Promise((resolve, reject) => {

this.webSocket = new WebSocket(this.wsurl);

this.webSocket.onopen = () => {
this.webSocket.addEventListener("message", (message) => {
this.decodeMessage(JSON.parse(message.data));
});
self.emit(EVENT_CONNECTED, null);
resolve(this);
};

this.webSocket.onerror = function(err) {
self.emit(EVENT_ERROR, err);
};

this.webSocket.onclose = function(event) {
self.emit(EVENT_ONCLOSE, event);
setTimeout(function() {
self.reconnectUser();
}, 5000)
};
});
}

closeWebSocket(){
this.webSocket.close();
}
this.closeWebSocket = function(){
this.webSocket.close();
}

decodeMessage(message){
this.decodeMessage = function(message){

if(this.isResponseMessage(message)){
this.emit(EVENT_RESPONSE, message);
if(this.isResponseMessage(message)){
this.emit(EVENT_RESPONSE, message);
}

if(this.isReconnectMessage(message)){
this.reconnectUser();
this.emit(EVENT_RECONNECT, message);
}

if(this.isErrorMessage(message)){
this.emit(EVENT_ERROR, message.error);
}

if(this.isNewUserNotification(message)){
if(!this.serviceMessages.has(message.params.uuid)){
this.serviceMessages.set(message.params.uuid,message)
}
this.emit(EVENT_NEW_USER, message.params);
}

if(this.isTextMessage(message)){
if(this.messages.has(message.params.uuid)){
this.messages.get(message.params.uuid).params.ack = true;
this.pendingMessages.delete(message.params.uuid);
}
else{
this.messages.set(message.params.uuid,message);
}
this.emit(EVENT_TEXT_MESSAGE, message.params);
}

if(this.isImageMessage(message)){
axios.get(this.apiurl+'/images/' + message.params.uuid)
.then(response => {
if(this.messages.has(response.data.params.uuid)){
this.messages.get(response.data.params.uuid).params.ack = true;
this.pendingMessages.delete(response.data.params.uuid);
}
else{
this.messages.set(message.params.uuid,response.data);
}
this.emit(EVENT_IMAGE_MESSAGE, message.params);
}).catch(e => {
console.log(e);
})
}
}

if(this.isReconnectMessage(message)){
this.reconnectUser();
this.emit(EVENT_RECONNECT, message);
this.isResponseMessage = function(message){
return message.hasOwnProperty('result')
}

if(this.isErrorMessage(message)){
this.emit(EVENT_ERROR, message.error);
this.isErrorMessage = function(message){
return message.hasOwnProperty('error');
}

if(this.isNewUserNotification(message)){
if(!this.serviceMessages.has(message.params.uuid)){
this.serviceMessages.set(message.params.uuid,message)
this.isNewUserNotification = function(message){
if (message.hasOwnProperty('method') && !message.hasOwnProperty('id')){
return (message.method === METHOD_NEW_USER);
}
this.emit(EVENT_NEW_USER, message.params);
return false;
}

if(this.isTextMessage(message)){
if(this.messages.has(message.params.uuid)){
this.messages.get(message.params.uuid).params.ack = true;
this.pendingMessages.delete(message.params.uuid);

this.isTextMessage = function(message){
if (message.hasOwnProperty('method') && message.hasOwnProperty('id')){
return (message.method === METHOD_TEXT_MESSAGE);
}
else{
this.messages.set(message.params.uuid,message);
return false;
}

this.isImageMessage = function(message){
if (message.hasOwnProperty('method') && message.hasOwnProperty('id')){
return (message.method === METHOD_IMAGE_MESSAGE);
}
this.emit(EVENT_TEXT_MESSAGE, message.params);
return false;
}

}

isResponseMessage(message){
return message.hasOwnProperty('result')
}

isErrorMessage(message){
return message.hasOwnProperty('error');
}

isNewUserNotification(message){
if (message.hasOwnProperty('method') && !message.hasOwnProperty('id')){
return (message.method === METHOD_NEW_USER);

this.isReconnectMessage = function(message){
if (message.hasOwnProperty('method') && message.hasOwnProperty('id')){
return (message.method === METHOD_RECONNECT);
}
return false;
}
return false;
}

isTextMessage(message){
if (message.hasOwnProperty('method') && message.hasOwnProperty('id')){
return (message.method === METHOD_TEXT_MESSAGE);

this.isOpeningWebSocket = function() {
return Boolean(this.webSocket && this.webSocket.readyState === WEBSOCKET_STATE.CONNECTING);
}

this.isOpenedWebSocket = function() {
return Boolean(this.webSocket && this.webSocket.readyState === WEBSOCKET_STATE.OPEN);
}

this.getNewId = function(){
return this.messageId++;
}
return false;
}

isReconnectMessage(message){
if (message.hasOwnProperty('method') && message.hasOwnProperty('id')){
return (message.method === METHOD_RECONNECT);
this.sendPendingMessages = function(){
for (const [key, value] of this.pendingMessages) {
if (value.method==METHOD_IMAGE_MESSAGE){
this.writeImageMessageToAPIRest(value)
}
else{
this.writeMessageIntoWebSocket(value);
}
}
}

this.writeImageMessageToAPIRest = function(message){
axios.post(this.apiurl+"/images", JSON.stringify(message), {headers: {'content-type': 'application/json'}})
.then((res) => {
if(this.verbose) console.log(res.data)
})
.catch((error) => {
console.error(error)
})
}
return false;

this.writeMessageIntoWebSocket = function(message){
if (this.isOpenedWebSocket()){
if(this.verbose) console.log(JSON.stringify(message));
this.webSocket.send(JSON.stringify(message));
}
}

this.connectWebSocket().then(() => {
if(this.verbose) console.log("WebSocket initializated succesfully");
})

}

isOpeningWebSocket() {
return Boolean(this.webSocket && this.webSocket.readyState === WEBSOCKET_STATE.CONNECTING);
getMessages(){
return this.messages;
}

isOpenedWebSocket() {
return Boolean(this.webSocket && this.webSocket.readyState === WEBSOCKET_STATE.OPEN);
getServiceMessages(){
return this.serviceMessages;
}

getNewId(){
return this.messageId++;
getPendingMessages(){
return this.pendingMessages;
}

joinRoom(userId, userName, roomName){
Expand All @@ -211,14 +275,14 @@ class ChatMessagesManager extends EventEmitter {
userId: userId,
roomName: roomName,
userName: userName,
lastMessageId: null
},
id: id
}
this.serviceMessages.set(id,joinRoomMessage);
this.writeMessageIntoWebSocket(joinRoomMessage);
}


sendTextMessage(messageText){
let messageUUID = uuid.v4();
let id = this.getNewId()
Expand All @@ -241,17 +305,28 @@ class ChatMessagesManager extends EventEmitter {
this.sendPendingMessages();
}

sendPendingMessages(){
for (const [key, value] of this.pendingMessages) {
this.writeMessageIntoWebSocket(value);
sendImageMessage(base64ImgString){
let messageUUID = uuid.v4();
let id = this.getNewId()
let imageMessage = {
jsonrpc: JSONRPC_VERSION,
method: METHOD_IMAGE_MESSAGE,
params: {
userId: this.userId,
roomName: this.roomName,
userName: this.userName,
base64ImgString: base64ImgString,
ack: false,
uuid: messageUUID,
date: new Date()
},
id: id
}
this.messages.set(messageUUID,imageMessage);
this.pendingMessages.set(messageUUID,imageMessage);
this.sendPendingMessages();
}

writeMessageIntoWebSocket(message){
if (this.isOpenedWebSocket()){
this.webSocket.send(JSON.stringify(message));
}
}
}

module.exports = ChatMessagesManager;
Loading