WSJS / WebSocket Integrity
This commit is contained in:
parent
0a0dcdf764
commit
08e8c59d59
|
@ -0,0 +1,23 @@
|
|||
function Client()
|
||||
{
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this.id = null;
|
||||
/**
|
||||
* @type {import("websocket").connection}
|
||||
*/
|
||||
this.socket = null;
|
||||
/**
|
||||
* @type {Date}
|
||||
*/
|
||||
this.created_at = null;
|
||||
|
||||
this.store = new Map();
|
||||
};
|
||||
|
||||
Client.prototype.send = function(obj){
|
||||
this.socket.sendUTF(JSON.stringify(obj));
|
||||
};
|
||||
|
||||
exports.Client = Client;
|
|
@ -0,0 +1,8 @@
|
|||
"use strict";
|
||||
|
||||
let http = require("http");
|
||||
let server = http.createServer();
|
||||
server.listen(8282,'0.0.0.0',() => {
|
||||
console.log("HTTP Service Running...");
|
||||
});
|
||||
exports.http = server;
|
|
@ -0,0 +1,47 @@
|
|||
let {addService} = require("../WebSocket.js");
|
||||
|
||||
addService(({
|
||||
global,
|
||||
client,
|
||||
message,
|
||||
end,
|
||||
next,
|
||||
response
|
||||
})=>{
|
||||
let {type,username,password} = message;
|
||||
if(type === 'auth/check')
|
||||
{
|
||||
let auth = client.store.has('user');
|
||||
return end({
|
||||
value: auth
|
||||
})
|
||||
};
|
||||
if(type === 'auth/login')
|
||||
{
|
||||
if(username == 'admin' && password == '123456Kc')
|
||||
{
|
||||
return end({
|
||||
status: 'success'
|
||||
})
|
||||
}else{
|
||||
return end({
|
||||
status: 'fail'
|
||||
})
|
||||
}
|
||||
};
|
||||
if(type === 'auth/logout')
|
||||
{
|
||||
let auth = client.store.has('user');
|
||||
if(auth)
|
||||
{
|
||||
client.store.delete('user');
|
||||
return end({
|
||||
status: 'success'
|
||||
})
|
||||
}else{
|
||||
return end({
|
||||
status: 'fail'
|
||||
})
|
||||
}
|
||||
};
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
let {addListener} = require("../WebSocket.js");
|
||||
|
||||
addListener('connect',(global, client)=>{
|
||||
client.send([{
|
||||
type: 'id',
|
||||
value: client.id
|
||||
},'id'])
|
||||
});
|
|
@ -0,0 +1,117 @@
|
|||
"use strict";
|
||||
|
||||
let websocket = require("websocket");
|
||||
let {http} = require("./HTTPServer");
|
||||
let {randomUUID} = require("crypto");
|
||||
const { Client } = require("./Client.js");
|
||||
|
||||
let wsServer = new websocket.server({
|
||||
httpServer: http,
|
||||
autoAcceptConnections: true
|
||||
});
|
||||
|
||||
let global = new Map();
|
||||
let clients = new Map();
|
||||
wsServer.addListener("connect",(socket) => {
|
||||
|
||||
let local = new Client();
|
||||
let id = randomUUID();
|
||||
socket.id = id;
|
||||
local.id = id;
|
||||
local.socket = socket;
|
||||
local.created_at = new Date();
|
||||
clients.set(id, local);
|
||||
|
||||
emit("connect", global, local);
|
||||
socket.addListener("close",()=>{
|
||||
emit("disconnect", global, local);
|
||||
clients.delete(id);
|
||||
});
|
||||
socket.addListener("message",({type,utf8Data}) => {
|
||||
if(type == "utf8")
|
||||
{
|
||||
let json;
|
||||
try{
|
||||
json = JSON.parse(utf8Data);
|
||||
emit('services', global, local, json);
|
||||
let [payload, id, action] = json;
|
||||
if(typeof id === "string")
|
||||
{
|
||||
action = id;
|
||||
}
|
||||
emitService(global, local, id, payload, action);
|
||||
}catch{
|
||||
emit("messageError", global, local, utf8Data);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @type {Map<string, Function[]>}
|
||||
*/
|
||||
let events = new Map();
|
||||
/**
|
||||
* @type {Map<string, Function[]>}
|
||||
*/
|
||||
let services = []
|
||||
/**
|
||||
*
|
||||
* @param {string} event
|
||||
* @param {(global:Map<string, any>, client:Client, data:any) => any} func
|
||||
*/
|
||||
exports.addListener = (event, func) => {
|
||||
if(!events.has(event))
|
||||
{
|
||||
events.set(event,[]);
|
||||
};
|
||||
events.get(event).push(func);
|
||||
};
|
||||
/**
|
||||
*
|
||||
* @param {string} event
|
||||
* @param {(data:{global:Map<string, any>, client:Client, message:any,response:Function,end:Function,next:Function}) => any} func
|
||||
*/
|
||||
exports.addService = (func) => {
|
||||
services.push(func);
|
||||
};
|
||||
function emit(event,...args)
|
||||
{
|
||||
if(events.has(event))
|
||||
{
|
||||
for (const callback of events.get(event)) {
|
||||
callback(...args);
|
||||
}
|
||||
};
|
||||
};
|
||||
/**
|
||||
*
|
||||
* @param {Map} global
|
||||
* @param {Client} local
|
||||
* @param {number} id
|
||||
* @param {{[key:string]:any}} payload
|
||||
* @param {"R"|"S"} action
|
||||
*/
|
||||
async function emitService(global, client, id, payload, action)
|
||||
{
|
||||
let willContinue = false;
|
||||
for (const callback of services) {
|
||||
await callback({
|
||||
message: payload,
|
||||
action,
|
||||
client,
|
||||
global,
|
||||
response:(obj)=>{
|
||||
client.send([obj, id, 'C']) // continue
|
||||
},
|
||||
end:(obj)=>{
|
||||
client.send([obj, id, 'E']) // stopped data stream (this channel)
|
||||
},
|
||||
next:function(){
|
||||
willContinue = true;
|
||||
}
|
||||
});
|
||||
if(willContinue === false) break;
|
||||
}
|
||||
};
|
||||
exports.websocket = wsServer;
|
|
@ -0,0 +1,5 @@
|
|||
require("./HTTPServer.js");
|
||||
require("./WebSocket.js");
|
||||
|
||||
require("./Services/YourID.js");
|
||||
require("./Services/Auth.js");
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "mwse",
|
||||
"version": "0.1.0",
|
||||
"description": "Mikro WebSocket Engine",
|
||||
"main": "Source/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://git.saqut.com/saqut/MWSE"
|
||||
},
|
||||
"keywords": [
|
||||
"WebSocket",
|
||||
"server",
|
||||
"microservice",
|
||||
"ws"
|
||||
],
|
||||
"author": "Abdussamed ULUTAŞ <abdussamedulutas@yandex.com.tr>",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"knex": "^2.3.0",
|
||||
"sqlite3": "^5.1.2",
|
||||
"websocket": "^1.0.34"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="./wsjs.js"></script>
|
||||
<script>
|
||||
let ws = new WSJS();
|
||||
ws.connect('ws://localhost:8282');
|
||||
ws.scope(()=>{
|
||||
console.log("Connected ws")
|
||||
ws.authWith("admin","123456Kc");
|
||||
});
|
||||
ws.signal('id',(data)=>{
|
||||
console.log("Your id is ", data.value)
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,133 @@
|
|||
function WSJS()
|
||||
{
|
||||
this.isActive = false;
|
||||
this.ws = null;
|
||||
this.endpoint = null;
|
||||
};
|
||||
WSJS.prototype.connect = function(url){
|
||||
this.ws = new WebSocket(url);
|
||||
this.addListeners();
|
||||
}
|
||||
WSJS.prototype.addListeners = function(url){
|
||||
this.ws.addEventListener("close", this.closedEvent.bind(this));
|
||||
this.ws.addEventListener("message", this.messageEvent.bind(this));
|
||||
this.ws.addEventListener("open", this.openMessage.bind(this));
|
||||
}
|
||||
WSJS.prototype.closedEvent = function(){
|
||||
this.isActive = false;
|
||||
this.ws = null;
|
||||
this.events.dispatchEvent(new Event("close"));
|
||||
}
|
||||
WSJS.prototype.openMessage = function(){
|
||||
this.isActive = true;
|
||||
this.events.dispatchEvent(new Event("open"));
|
||||
}
|
||||
WSJS.prototype.messageEvent = function({data}){
|
||||
let [payload, id, action] = JSON.parse(data);
|
||||
if(typeof id === 'number')
|
||||
{
|
||||
if(this.requests.has(id))
|
||||
{
|
||||
this.requests.get(id)(payload, action);
|
||||
switch(action)
|
||||
{
|
||||
case 'E':{
|
||||
this.requests.delete(id);
|
||||
break;
|
||||
}
|
||||
case 'S':
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else console.warn("Missing event sended from server");
|
||||
}else{
|
||||
if(this.signals.has(id))
|
||||
{
|
||||
for (const callback of this.signals.get(id)) {
|
||||
callback(payload);
|
||||
}
|
||||
}else console.warn("Missing event sended from server");
|
||||
}
|
||||
}
|
||||
WSJS.prototype.events = new EventTarget();
|
||||
WSJS.prototype.scope = function(func){
|
||||
if(this.isActive)
|
||||
{
|
||||
func();
|
||||
}else this.events.addEventListener("open", func);
|
||||
}
|
||||
|
||||
WSJS.prototype.sendOnly = function(obj){
|
||||
if(this.isActive)
|
||||
{
|
||||
this.sendRaw([obj,'R']);
|
||||
}else throw new Error(`socket could be a active`);
|
||||
}
|
||||
WSJS.prototype.requests = new Map();
|
||||
WSJS.prototype.requestCount = 0;
|
||||
WSJS.prototype.request = async function(obj){
|
||||
if(this.isActive)
|
||||
{
|
||||
return await new Promise(ok => {
|
||||
let id = ++this.requestCount;
|
||||
this.sendRaw([obj,id,'R']);
|
||||
this.requests.set(id,data => {
|
||||
ok(data);
|
||||
});
|
||||
})
|
||||
}else throw new Error(`socket could be a active`);
|
||||
}
|
||||
WSJS.prototype.stream = async function(obj,callback){
|
||||
if(this.isActive)
|
||||
{
|
||||
let id = ++this.requestCount;
|
||||
this.sendRaw([obj, id, 'S']);
|
||||
this.requests.set(id,data => {
|
||||
callback(data);
|
||||
});
|
||||
}else throw new Error(`socket could be a active`);
|
||||
}
|
||||
WSJS.prototype.signals = new Map();
|
||||
WSJS.prototype.signal = async function(name, callback){
|
||||
if(!this.signals.has(name))
|
||||
{
|
||||
this.signals.set(name, [callback]);
|
||||
}else{
|
||||
this.signals.get(name).push(callback);
|
||||
}
|
||||
}
|
||||
WSJS.prototype.slot = async function(name, obj){
|
||||
if(this.isActive)
|
||||
{
|
||||
if(typeof name == "string")
|
||||
{
|
||||
this.sendOnly([obj,name]);
|
||||
}else{
|
||||
throw new Error(`name could be a string, gived ${typeof name}`);
|
||||
}
|
||||
}else throw new Error(`socket could be a active`);
|
||||
}
|
||||
WSJS.prototype.sendRaw = function(obj){
|
||||
if(this.isActive)
|
||||
{
|
||||
this.ws.send(JSON.stringify(obj))
|
||||
};
|
||||
}
|
||||
WSJS.prototype.checkAuth = async function(username, password){
|
||||
let {value:isAuth} = await this.request({
|
||||
type: 'auth/check'
|
||||
});
|
||||
return isAuth;
|
||||
};
|
||||
WSJS.prototype.authWith = async function(username, password){
|
||||
if(!await this.checkAuth())
|
||||
{
|
||||
let requets = await this.request({
|
||||
type: 'auth/login',
|
||||
username,
|
||||
password
|
||||
});
|
||||
debugger;
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue