Home Reference Source Repository

src/server/socket-server.js

import { server as WebSocketServer } from 'websocket';
import bus from '../lib/bus';
import coreRequests from './core-requests';
// import http = from 'http';

export const clientResponse = ({type, name, data}, encoding = 'utf8') => {
	data = {
		data,
		status: 200
	};
	const response = {
		type,
		name,
		data
	};
	if (encoding === 'utf8') {
		return JSON.stringify(response);
	}
	return response;
};

export class ClientConnection {
	constructor(connection) {
		this.connection = connection;

		this.onMessage = this.onMessage.bind(this);
		this.onPeerAdded = this.onPeerAdded.bind(this);
		this.onMining = this.onMining.bind(this);
		this.onBlockAdded = this.onBlockAdded.bind(this);
		this.onHashrate = this.onHashrate.bind(this);
		this.onjobCancelled = this.onjobCancelled.bind(this);
		this.onConnecting = this.onConnecting.bind(this);
		this.onSyncing = this.onSyncing.bind(this);
		this.onReady = this.onReady.bind(this);

		this.connection.on('message', this.onMessage);

		bus.on('peer-added', this.onPeerAdded);
		bus.on('mining', this.onMining);
  	bus.on('block', this.onBlockAdded);
  	bus.on('hashrate', this.onHashrate);
  	bus.on('job-cancelled', this.onjobCancelled);
  	bus.on('connecting', this.onConnecting);
  	bus.on('syncing', this.onSyncing);
		bus.on('ready', this.onReady);

  	this.connection.on('close', (reasonCode, description) => {
			bus.removeListener('peer-added', this.onPeerAdded);
  		bus.removeListener('mining', this.onMining);
    	bus.removeListener('block', this.onBlockAdded);
    	bus.removeListener('hashrate', this.onHashrate);
    	bus.removeListener('job-cancelled', this.onjobCancelled);
    	bus.removeListener('connecting', this.onConnecting);
    	bus.removeListener('syncing', this.onSyncing);
  		bus.removeListener('ready', this.onReady);
  		console.log((new Date()) + ' Peer ' + this.connection.remoteAddress + ' disconnected.');
			return;
  	});
	}

	onMessage({type, utf8Data}) {
		if (type === 'utf8') {
    	const request = JSON.parse(utf8Data.toString());
			coreRequests(request).then(data => {
				const { name, type } = request;
				this.connection.send(JSON.stringify({name, data, type}));
			});
		}
	}

	send({name, data, type}) {
		this.connection.send(clientResponse({type, name, data}));
	}

	stateResponse({type = 'status', name, data}) {
  	if (data !== global.states[name]) {
  		global.states[name] = data;
  	}
  	return this.send({type, name, data});
	}

	onPeerAdded(peer) {
		this.send({type: 'network', name: 'peer-added'});
	}

	onMining(data) {
		this.stateResponse({name: 'mining', data});
	}

	onBlockAdded(data) {
  	console.log(data.transactions);
  	this.send({type: 'blockchain', name: 'block-added', data});
	}

	onHashrate(data) {
		this.send({type: 'miner', name: 'hashrate', data});
	}

	onjobCancelled(data) {
		this.send({type: 'miner', name: 'job-cancelled', data});
	}

	onConnecting(data) {
		this.stateResponse({name: 'connecting', data});
	}

	onSyncing(data) {
		this.stateResponse({name: 'syncing', data});
	}

	onReady(data) {
		this.stateResponse({name: 'ready', data});
	}
}

export default httpServer => {
	const socketServer = new WebSocketServer({
  	httpServer,
  	autoAcceptConnections: false
	});

	const originIsAllowed = origin => {
  	// put logic here to detect whether the specified origin is allowed.
  	return true;
	};

	socketServer.on('request', request => {
  	if (!originIsAllowed(request.origin)) {
  		// Make sure we only accept requests from an allowed origin
  		request.reject();
  		console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
  		return;
  	}

  	const connection = request.accept('echo-protocol', request.origin);
  	console.log((new Date()) + ' Connection accepted.');
		return new ClientConnection(connection);
	});

};