Streaming Currency and Cryptocurrency Data Using WebSockets and Node.js with ReactJs client
Published: 2023-07-10 12:49:14

## Introduction:

The world of finance operates at lightning speed, and real-time data is crucial for making informed decisions. Traditionally, retrieving up-to-date currency and cryptocurrency information required frequent API calls, which could be inefficient and resource-intensive. However, with the advent of WebSockets and the power of Node.js, developers now have a more efficient solution. In this blog post, we will explore how to use WebSockets and Node.js to stream currency and cryptocurrency data in real-time, ensuring that you have the most accurate information at your fingertips.

## Prerequisites:

To follow along with this tutorial, it is recommended to have a basic understanding of Node.js and JavaScript. Familiarity with WebSockets will also be beneficial but not required.

## Setting Up the Project:

1. Ensure that you have Node.js and npm (Node Package Manager) installed on your machine.
2. Create a new directory for your project and navigate to it using the terminal or command prompt.

3. Initialize a new Node.js project by running the command: `npm init -y`.
4. Install the required dependencies:
   - Express.js: `npm install express`
   - WebSocket library: `npm install ws`
   - Axios (for making API requests): `npm install axios`

## Server-side Implementation:

1. Create a new file called `server.js` and require the necessary modules.

You should have a server file that looks like the code below, please not that implementation may vary but the underlining principle is the same.

```js
const http = require("http");



const port = normalizePort(process.env.PORT || "3000");
app.set("port", port);


const server = http.createServer(app);



server.listen(port);
server.on("error", onError);
server.on("listening", onListening);



function normalizePort(val) {
  const port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}



function onError(error) {
  if (error.syscall !== "listen") {
    throw error;
  }

  const bind = typeof port === "string" ? "Pipe " + port : "Port " + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case "EACCES":
      console.error(bind + " requires elevated privileges");
      process.exit(1);
      break;
    case "EADDRINUSE":
      console.error(bind + " is already in use");
      process.exit(1);
      break;
    default:
      throw error;
  }
}


function onListening() {
  const addr = server.address();
  const bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;
  debug("Listening on " + bind);
}
```

2. Set up an Express.js server \_app.js to handle the rest of server logic.
3. Initialize a WebSocket server using the 'ws' library and listen for incoming connections.

Basically, the whole implementation should look like the code below using ws modules

```js
const WebSocket = require('ws');

const ws = new WebSocket('wss://stream.binance.com:9443/ws/btcusdt@trade');

ws.on('open', () => {
  console.log('WebSocket connection established');
});

ws.on('message', (data) => {
  const trade = JSON.parse(data);
  console.log(`Trade executed at price ${trade.p} with quantity ${trade.q}`);
});

ws.on('close', () => {
  console.log('WebSocket connection closed');
});

```

4. Fetch currency and cryptocurrency data from an API at regular intervals. The basic code structure above ☝️ will be used to fetch cryptocurrency data at stream intervals.

```js
wsServer.on("request", function (request) {
  const connection = request.accept(null, request.origin);
  console.log(new Date() + " Connection accepted.");


  connection.on("message", function (message) {
    if (message.type === "utf8") {
      console.log(new Date() + "Message received: " + message.utf8Data);

      const trade = JSON.parse(data);
      console.log(`Trade executed at price ${trade.p} with quantity ${trade.q}`);
      connection.send(JSON.stringify(data))

      //implementation below is simply an additional code
      //you can fetch from mongodb streams as below
      Exchange.watch().on("change", (data) =>
      connection.send(JSON.stringify(data.fullDocument))
    );

    }

    else if (message.type === 'binary') {
      console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
    }
  });

  connection.on("close", function (reasonCode, description) {
    console.log(
      new Date() +
        " Peer " +
        connection.remoteAddress + " disconnected."
    );
  });
});
```

5. Send the updated data to connected WebSocket clients whenever it changes as shown in the code above ☝️.

## Client-side Implementation:

## React

1. Create the React app.

- React.js (if not already installed): npx create-react-app client

2. Modify the 'App.js' file to establish a WebSocket connection with the server.
3. Implement event handlers to process incoming data from the WebSocket and update the React state accordingly.
4. Design and render components to display the real-time currency and cryptocurrency data.

```js
const [ws, setWs] = React.use useState(new WebSocket("wss://...server"));
```

get streams of data from the server using the useEffect hook

```js
useEffect(() => {
    //setup websocket
    ws.onopen = (event) => {
      //check to confirm connection from both
      //you can inspect websockets using a chrome add-on
      //The message below should be displayed when you client app is connected
      ws.send("Message sent from React client");
    };

    // recieve stream data, our implementation uses a state function setData
    ws.onmessage = (stream) => {
      setTdata([...tData, JSON.parse(stream.data)]);
    };

    return () => {
      ws.onclose = () => {
        //reconnect to server ever 1000 * 10 ms
        console.log("socket close : will reconnect in " + 1000 * 10);
        setWatchState(false);
        setTimeout(
          () => setWs(new WebSocket("wss://...server")),
          1000 * 10
        );
      };
    };
  }, []);
```

Simply used the received data as you wish in your React.Js app.

## Conclusion:

In this blog post, we explored how to use WebSockets and Node.js to stream currency and cryptocurrency data in real-time. By leveraging the power of WebSockets, we can establish a persistent connection between the server and the client, eliminating the need for frequent API calls. This approach ensures that we have the most accurate and up-to-date data available at all times. Whether you are building a financial application, a trading platform, or simply want to display live data on your website, WebSockets and Node.js provide an efficient solution. Take the code provided, experiment, and create dynamic and interactive applications that keep your users informed in real-time. Happy coding!