socketry
Version:
A socket library to help with your websocket needs!
239 lines (200 loc) • 7.94 kB
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: index.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: index.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>const WebSocket = require('ws');
const { EventEmitter } = require('events');
// ------ Server ------
/**
* Create a new server
* @constructor
* @param {number} port - Choose the port for the server to listen to.
*/
class Server extends EventEmitter {
constructor(port) {
super();
if (typeof port !== 'number') throw Error('Expected type: number');
this.clients = [];
this.rooms = [];
this.port = port;
this.server = new WebSocket.Server({ port });
this.server.on('connection', ws => {
ws.id = `0${Math.round(Math.random() * 10000000000000000)}`;
ws.user = new User(ws);
this.clients.push(ws.user);
this.emit('connection', ws.user);
ws.on('message', msg => {
if (!JSON.parse(msg).socketry) {
let msgB = JSON.parse(msg);
delete msgB.sendRoomName;
ws.user.emit('message', JSON.stringify(msgB), this.rooms.filter(r => r.name == JSON.parse(msg).sendRoomName)[0]);
} else if (JSON.parse(msg).type === 'joinRoom') {
if (!this.rooms.length) ws.send(JSON.stringify({socketry: true, type: 'Error', details: {error: 'No rooms available'}}));
if (!this.rooms.filter(r => r.name == JSON.parse(msg).details.name)) ws.send(JSON.stringify({socketry: true, type: 'Error', details: {error: 'No rooms with that name'}}));
let name = JSON.parse(msg).details.name;
this.rooms.filter(r => r.name == name)[0].clients.push(ws);
ws.send(JSON.stringify({socketry: true, type: 'roomJoined', details: {room: {id: this.rooms.filter(r => r.name == name)[0].id, name: this.rooms.filter(r => r.name == name)[0].name}}}));
} else if (JSON.parse(msg).type === 'leaveRoom') {
let name = JSON.parse(msg).details.name;
this.rooms.filter(r => r.name == name)[0].clients = this.rooms.filter(r => r.name == name)[0].clients.filter(c => c.id !== ws.id);
ws.send(JSON.stringify({socketry: true, type: 'roomLeft', details: {name: JSON.parse(msg).details.name, clients: this.rooms.filter(r => r.name == name)[0].clients.length}}));
}
});
ws.on('close', () => {
ws.user.emit('end', this.clients.filter(c => c.server.readyState !== 1)[0]);
this.clients = this.clients.filter(c => c.server.readyState === 1);
this.rooms.forEach(r => {
r.clients = r.clients.filter(c => c.readyState === 1);
});
});
});
}
/**
* Create a new room
* @param {string} room - Name of the room you would like to connect to
*/
get Room() {
return room.bind(null, this);
}
}
/**
* The room class. New rooms can be created with the Server class
*/
class room extends EventEmitter {
constructor (server, name) {
super();
this.id = `1${Math.round(Math.random() * 10000000000000000)}`;
this.oname = name;
if(!server.rooms.filter(r => r.oname === name).length) {
this.name = name;
} else {
this.name = `${name}-${server.rooms.filter(r => r.oname === name).length}`;
}
this.clients = [];
this.server = {
port: server.port,
socket: server.server
};
server.rooms.push(this);
}
}
/**
* The user class which is passed down to the server connection event (ids start with a '0')
* @constructor
*/
class User extends EventEmitter {
constructor(ws) {
super();
this.server = ws;
}
/**
* Send data to a client
* @param {string} msg - The message content
*/
send(msg) {
this.server.send(msg);
}
}
// ------ Client ------
/**
* The Client class
* @constructor
* @param {string} url - Connect to a socketry server (ids start with a '0')
*/
class Client extends EventEmitter {
constructor(url) {
super();
if (typeof url !== 'string') throw Error('Expected type: number');
this.url = url;
this.client = new WebSocket(url);
this.rooms = [];
this.client.on('open', () => {
this.emit('open');
this.client.on('message', data => {
try {
if (JSON.parse(data).type == 'Error') {
throw Error(JSON.parse(data).details.error);
} else if (JSON.parse(data).type == 'roomJoined') {
this.rooms.push(JSON.parse(data).details.room);
this.emit('join', new clientRoom(JSON.parse(data).details.room, this));
} else if (JSON.parse(data).type == 'roomLeft') {
this.emit('leave', JSON.stringify({name: JSON.parse(data).name, clients: JSON.parse(data).clients}));
}
} catch (err) {}
});
});
}
/**
* End the client connection
*/
end() {
this.client.close();
}
/**
* Join a room
* @param {string} room - Name of the room you would like to join
*/
joinRoom(room) {
if (typeof room !== 'string') throw Error('Expected type: string');
this.client.send(JSON.stringify({socketry: true, type: 'joinRoom', details: {name: room}}));
// {socketry: true, type: 'joinRoom', details: {name: room}}
}
}
class clientRoom extends EventEmitter {
constructor (room, main) {
super();
this.room = room;
this.main = main;
this.main.client.on('message', data => {
try {
JSON.parse(data);
} catch (err) {
this.emit('message', data);
}
});
}
/**
* Send data to a room
* @param {object} msg - The message content
*/
send(msg) {
if (typeof msg !== 'object') throw Error('Expected type: object');
msg.sendRoomName = this.room.name;
this.main.client.send(JSON.stringify(msg));
}
/** Leave a room
*/
leave() {
this.main.rooms = this.main.rooms.filter(r => r.name !== this.room.name);
this.main.client.send(JSON.stringify({socketry: true, type: 'leaveRoom', details: this.room}));
}
}
module.exports = { Server, Client };</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Client.html">Client</a></li><li><a href="room.html">room</a></li><li><a href="Server.html">Server</a></li><li><a href="User.html">User</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue May 15 2018 20:28:19 GMT-0400 (Eastern Daylight Time)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>