Skip to content

Latest commit

 

History

History
181 lines (139 loc) · 4.21 KB

File metadata and controls

181 lines (139 loc) · 4.21 KB

WebSocket REST App

The project implements and show the two most popular options available today for client-server communication protocols: WebSocket against RESTful HTTP.

Motivation

The motivation behind this project was to learn and understand better the topic of client-server communication (the communication between a web browser and a web server) and to implement it with ReactJS web framework.

Screenshots

image

animated gif

Tech/framework used

Built with

Features

  • The JSON data that we receive from the REST API is displayed in a beautifully designed Table.
  • The messages that we receive from the WebSocket is displayed on the screen as Live Rates Ticker that are colorfully designed and include start/stop button.

Code Examples

REST API

// Using useEffect to retrieve data from an API
useEffect(() => {
	const source = axios.CancelToken.source();

	const fetchData = async () => {
		setIsError(false);
		setIsLoading(true);

		try {
			// Making our HTTP request to the specified url
			const response = await axios(url, {
				cancelToken: source.token
			});
			// Updating the state with the data we got from the response
			setData(response.data);
		} catch (error) {
			setIsError(true);
			if (axios.isCancel(error)) {
				console.log('request cancelled');
			} else {
				throw error;
			}
		}

		setIsLoading(false);
	};

	// Invoke the async function
	fetchData();

	// Unmount
	return () => {
		source.cancel();
	};
}, []);

WebSocket API

// Consistent WebSocket API connection
const webSocket = useRef(null);

// Socket onopen effect
useEffect(() => {
	// Connect to websocket
	connect();
	webSocket.current.onopen = (event) => {
		try {
			// Subscribing to a channel by sending JSON message to the server
			toogleChannel("subscribe");
		} catch (err) {
			console.log("Got invalid message from websocket on open", err, event.data);
		}
	}
}, []);

// Socket onmessage effect
useEffect(() => {
	webSocket.current.onmessage = (event) => {
		// Some response message
		const response = JSON.parse(event.data);
		switch (response.event) {
			case 'data':
				// Calculate the rate by summing the last bid with the last ask and divide it by 2
				rateCalculate(response.data.bids[0][0], response.data.asks[0][0])
					// Generate rate object that includes value and color
					.then( rate => generateRateObject(!rates.length ? undefined : rates[rates.length-1].value, rate))
					// Adding the new rate to previous rates array by using array spread operator.
					.then( rateObj => setRates(rates => [...rates, rateObj]));
				break;
			case 'bts:request_reconnect':
				// Forced reconnection
				connect();
				break;
			default:
				break;
		}
	}
}, [rates]);

// Socket onclose effect
useEffect(() => {
	webSocket.current.onclose = (event) => {
		// Wasn't cleaned
		if (!event.wasClean) {
			console.log({ error: `WebSocket error: ${event.code} ${event.reason}` });
			// Reconnect
			connect();
		}
	}
}, []);

// Socket onerror effect
useEffect(() => {
	webSocket.current.onerror = (event) => {
		console.log("received websocket error", event);
	}
}, []);

// Unmount
useEffect(() => () => {
	webSocket.current.close();
}, [webSocket])

// WebSocket connection
const connect = () => {
	webSocket.current = new WebSocket(serverEndPoint);
}

Installation

Running Locally

git, npm and node softwares should be installed before moving on

git clone https://github.com/dimakol/react-websocket-rest-app.git
cd react-websocket-rest-app
npm install
npm run start

Building for production

npm run build

API Reference

Deployed to Github pages

https://dimakol.github.io/react-websocket-rest-app/

Credits

License

(The MIT License)

Copyright © 2020 Dima Kolyas