Skip to content

Commit efad65c

Browse files
Viorel BaicuViorel Baicu
authored andcommitted
Initial commit
0 parents  commit efad65c

File tree

7 files changed

+334
-0
lines changed

7 files changed

+334
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
.DS_Store

README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# TFPSockets
2+
Simple, lightweight, event based websockets library for web and nodejs.
3+
4+
[**TFPSockets**](https://github.com/vbaicu/TFPSockets)
5+
6+
## Usage
7+
8+
9+
### Install
10+
11+
```bash
12+
npm install --save tfpSockets
13+
```
14+
15+
### Client
16+
17+
**Include code - Browser**
18+
19+
```html
20+
<script src="TFPSocketsClient-Browser.js"> <script>
21+
```
22+
23+
**Include code - Nodejs**
24+
25+
```javascript
26+
const TFPSocketsClient = require('TFPSockets').client
27+
```
28+
29+
**Open connection**
30+
31+
```javascript
32+
var conn = new TFPSocketsClient("ws://localhost:1600", ["chat"])
33+
conn.on('connected', event => {
34+
console.log('connected')
35+
36+
})
37+
```
38+
39+
**Add event listeners**
40+
```javascript
41+
conn.on('eventName', data => {
42+
console.log('Received event: ', data.eventName, 'with payload: ', data.payload)
43+
})
44+
```
45+
**Send Events**
46+
47+
Only supports sending serialisable objects and strings now.
48+
Binary data support is in progress.
49+
50+
```javascript
51+
conn.send('eventName',{x:0,y:0})
52+
```
53+
54+
Client for browser is build on top of WebSocket javascript object. TFPSocketsClient provides access to base socket object via `ws` property and can also be initialised with a pre initialised WebSocket instance using:
55+
```javascript
56+
var cleint = new TFPSocketsClient(null, null,initilisedWS)
57+
```
58+
59+
## Server
60+
Server library is build on top of [**WS**](https://github.com/websockets/ws) libary. library provides access to base WebSocket.Server object via `wss` proprerty for those who need more customisation.
61+
62+
**Include**
63+
64+
```javascript
65+
const TFPSocketsServer = require('TFPSockets').server
66+
```
67+
68+
**Create Server (using express)**
69+
70+
```javascript
71+
const express = require('express');
72+
const http = require('http');
73+
const url = require('url');
74+
75+
const app = express();
76+
77+
78+
const server = http.createServer(app);
79+
80+
const TFPServer = new TFPSockets.server(server,["chat"])
81+
82+
server.listen(1507, function listening() {
83+
console.log('Listening on %d', server.address().port);
84+
});
85+
```
86+
87+
**Listening for connections and event**
88+
```javascript
89+
TFPServer.on('connection',client => {
90+
client.on('testEvent', data => {
91+
console.log("test event payload: ", data.payload)
92+
client.send('testEventBack',{x:1,y:100})
93+
})
94+
})
95+
```
96+
97+
## Limitations & next steps
98+
* doesn't support binary data events - WIP
99+
* ssl certificates setup - WIP
100+

TFPSocketsClient-Browser.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
const isString = s => typeof (s) === 'string' || s instanceof String;
2+
3+
class TFPSocketsClient {
4+
5+
constructor(url, protocols,cutomws = null) {
6+
7+
this.EventStream = (function () {
8+
9+
var listeners = {};
10+
11+
const paddListener = (name, callback) => {
12+
if (!listeners[name]) {
13+
listeners[name] = [];
14+
}
15+
listeners[name] = [...listeners[name], callback];
16+
}
17+
18+
const premoveListener = (name, callback) => listeners[name] = listeners[name].filter(c => c != callback);
19+
20+
const pemit = (name, data) => (listeners[name] ? listeners[name] : []).forEach(c => c(data));
21+
22+
23+
return {
24+
addListener: (name, callback) => paddListener(name, callback),
25+
removeListener: (name, callback) => premoveListener(name, callback),
26+
emit: (name, data) => pemit(name, data)
27+
};
28+
}());
29+
30+
this.connectionUrl = url
31+
this.connectionProtocols = protocols
32+
this.isOpen = false
33+
this.handlers = {}
34+
this.ws = cutomws != null ? cutomws: new WebSocket(url, protocols)
35+
this.ws.onopen = event => {
36+
this.isOpen = true
37+
this.EventStream.emit('connected', event)
38+
}
39+
this.ws.onclose = event => {
40+
this.isOpen = false
41+
this.EventStream.emit('disconnected', event)
42+
}
43+
this.ws.binaryType = "arraybuffer"
44+
this.ws.onmessage = (data) => {
45+
if (isString(data.data)) {
46+
//handle incomming message
47+
try {
48+
let obj = JSON.parse(data.data);
49+
this.EventStream.emit(obj.eventName, obj)
50+
} catch (e) {
51+
console.log("Message doesn't repect protocol with exception: ", e)
52+
}
53+
} else {
54+
//binary data wip
55+
}
56+
}
57+
}
58+
59+
on(eventName, handler) {
60+
this.EventStream.addListener(eventName, handler)
61+
}
62+
63+
send(eventName, payload) {
64+
let obj = { eventName, payload }
65+
if (this.isOpen) {
66+
this.ws.send(JSON.stringify(obj))
67+
} else {
68+
console.log("Connection is not opened")
69+
}
70+
}
71+
72+
}
73+
74+
if (typeof module !== 'undefined' && module.exports) {
75+
module.exports = TFPSocketsClient
76+
} else {
77+
}

example.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const express = require('express');
2+
const http = require('http');
3+
const url = require('url');
4+
const TFPSockets = require('./index')
5+
6+
7+
const app = express();
8+
9+
10+
const server = http.createServer(app);
11+
12+
const TFPServer = new TFPSockets.server(server,["chat"])
13+
TFPServer.on('connection',client => {
14+
client.on('testEvent', data => {
15+
console.log("test event payload: ", data.payload)
16+
client.send('testEventBack',{x:1,y:100})
17+
})
18+
})
19+
20+
21+
const testClient = new TFPSockets.client("ws://localhost:1507",["chat"])
22+
testClient.on('open', event => {
23+
console.log("test client open")
24+
testClient.send('testEvent',{x:10,y:89})
25+
})
26+
27+
testClient.on('testEventBack', data => {
28+
console.log('testEventBack ', data.payload);
29+
})
30+
31+
32+
33+
server.listen(1507, function listening() {
34+
console.log('Listening on %d', server.address().port);
35+
});

index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const TFP = require('./lib/TFPSockets.js')
2+
3+
module.exports = TFP

lib/TFPSockets.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
const WebSocket = require('ws')
2+
3+
const isString = s => typeof (s) === 'string' || s instanceof String;
4+
5+
class TFPBaseEventStream {
6+
constructor() {
7+
this.EventStream = (function () {
8+
9+
var listeners = {};
10+
11+
const paddListener = (name, callback) => {
12+
if (!listeners[name]) {
13+
listeners[name] = [];
14+
}
15+
listeners[name] = [...listeners[name], callback];
16+
}
17+
18+
const premoveListener = (name, callback) => listeners[name] = listeners[name].filter(c => c != callback);
19+
20+
const pemit = (name, data) => (listeners[name] ? listeners[name] : []).forEach(c => c(data));
21+
22+
23+
return {
24+
addListener: (name, callback) => paddListener(name, callback),
25+
removeListener: (name, callback) => premoveListener(name, callback),
26+
emit: (name, data) => pemit(name, data)
27+
};
28+
}());
29+
}
30+
31+
on(eventName, handler) {
32+
if(typeof handler === 'function'){
33+
this.EventStream.addListener(eventName, handler)
34+
} else {
35+
console.log("Handler needs to be a function")
36+
}
37+
}
38+
}
39+
40+
41+
class TFPSocketsClient extends TFPBaseEventStream {
42+
43+
constructor(url, protocols, connection = null) {
44+
super()
45+
this.ws = connection != null ? connection : new WebSocket(url,protocols)
46+
this.isOpen = connection != null
47+
this.ws.on('open', event => {
48+
this.isOpen = true
49+
this.EventStream.emit('open',event)
50+
})
51+
this.ws.on('message', (data) => {
52+
if (isString(data)) {
53+
//handle incomming message
54+
try {
55+
let obj = JSON.parse(data);
56+
this.EventStream.emit(obj.eventName, obj)
57+
} catch (e) {
58+
console.log("Message doesn't repect protocol with exception: ", e)
59+
}
60+
} else {
61+
//binary data wip
62+
}
63+
})
64+
this.ws.on('close', () => this.EventStream.emit('close') )
65+
}
66+
67+
send(eventName, payload) {
68+
let obj = { eventName, payload }
69+
if (this.isOpen) {
70+
this.ws.send(JSON.stringify(obj))
71+
} else {
72+
console.log("Connection is not opened")
73+
}
74+
}
75+
76+
}
77+
78+
class TFPSocketsServer extends TFPBaseEventStream {
79+
constructor(server, protocols, customwss = null) {
80+
super()
81+
this.wss = customwss != null ? customwss : new WebSocket.Server({ server, handleProtocols: (ps, req) => { return protocols } });
82+
this.wss.on('connection', (ws, req) => {
83+
var client = new TFPSocketsClient(null, null,ws);
84+
this.EventStream.emit('connection', client);
85+
});
86+
}
87+
88+
}
89+
90+
module.exports = {
91+
client: TFPSocketsClient,
92+
server: TFPSocketsServer
93+
}

package.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "tfpsockets",
3+
"version": "0.1.0",
4+
"description": "Simple event based websockets wrapper",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"keywords": [
10+
"websocktes",
11+
"ws",
12+
"nodewebsockets",
13+
"javascrip",
14+
"js",
15+
"sockets",
16+
"tcp"
17+
],
18+
"author": "Viorel Baicu",
19+
"license": "MIT",
20+
"dependencies": {
21+
"express": "^4.16.0",
22+
"ws": "^3.2.0"
23+
}
24+
}

0 commit comments

Comments
 (0)