=============================================================================================================================================> I OFFER FULL STACK BLOCKCHAIN DEVELOPMENT SERVICES: ERC20/721 TOKEN CREATION, TOKEN SALE SMART CONTRACT, WHITELISTING, LENDING PROTOCOL, MARKETING REFERRAL, DAO DEVELOPMENT AND MORE.
FRONT END INTEGRATION INCLUDED.
IF YOU NEED SMART CONTRACTS, CONTACT ME.
IF YOU NEED FRONT END INTEGRATION WITH SMART CONTRACTS, CONTACT ME.
SEE MY OFFERS, CLIENT TESTIMONIALS AND PREVIOUS WORK BY VISITING =>https://www.muratcanyuksel.xyz
OR SEND ME AN EMAIL VIA mail@muratcanyuksel.xyz
=============================================================================================================================================>
To learn more about programming, subscribe to my Youtube channel => https://www.youtube.com/channel/UCP1hJydcsPZCwbn8rPiohsg
For my last project, I had to use Websockets to create a website that displays real-time trading data. I didn't know anything about WebSockets, and it took a couple of dreading hours to get to start with it. That's the only problem, actually, to start with it; the rest is pretty clear. This short article hopes to help others save the time it took for me to understand the basics of it.
Most of the tutorials on the web mention a "require" syntax. You know it. When you want to use a certain tool, component, or image in your component in JS or React, you'd do something like const something = require ("./folder/something"). Now, as I said, most of the tutorials I've found on the web start with this very syntax, that pushes you to start working with WebSockets using the require syntax. This is unnecessary, and maybe even wrong in the present day. I'm not sure about whether it works in any way or not, but I'm certain that the way I use works perfectly as I write this article on 12/09/2021. So, without further ado, let's talk about how we can make use of this protocol.
This article supposes that you have a working knowledge of Vanilla JS and React.js, you know how to deal with json format, and asynchronous code.
I initiate my app with vite (with the following command: npm init vite@latest and choose react from the menu), but you can use your own structure, or create-react-app. It doesn't matter really.
For a more in-depth introduction on WebSocket, visit javascript.info
What we'll build?
We're going to build a very simple, one-page React.js application that takes continuous-data from bitstamp.net and displays it on the page. The data will be changing all the time.
It doesn't really matter which service you're using, as long as it's WebSockets, the rest is plain Javascript.
Building the app
Let's start with connecting to bitstamp's WebSocket protocol by writing the following code const ws = new WebSocket("wss://ws.bitstamp.net");
Now, using this ws constant, we can subscribe to any channel that's defined on bitstamp's website and get continuous-data from there. You can find any information regarding the channels, properties, and all from here
Now, let's subscribe to a channel. I'll subscribe to oder_book_v2 channel and specify that I want to see btc/usd exchange rates. This call is defined in bitstamp's guide. You can change the channel and the currencies as you wish. Here's is the call:
const apiCall = {
event: "bts:subscribe",
data: { channel: "order_book_btcusd" },
};
The next step is to send this call to the server on open =>
ws.onopen = (event) => {
ws.send(JSON.stringify(apiCall));
};
Now we want to do something with each data. So, whenever we receive a message from the server, we'll do something. Let's write an async code with try/catch
ws.onmessage = function (event) {
const json = JSON.parse(event.data);
console.log(`[message] Data received from server: ${json}`);
try {
if ((json.event = "data")) {
console.log(json.data);
}
} catch (err) {
// whatever you wish to do with the err
}
};
If we opened the console, we'd see a large amount of data coming from the server. That's it, actually. We got the data, it's coming in a stream, and we can do whatever we want to do with it. It's that easy.
I want to display the data in a particular manner though. Let me paste the code and I'll explain immediately after:
import React, { useState } from "react";
function App() {
//give an initial state so that the data won't be undefined at start
const [bids, setBids] = useState([0]);
const ws = new WebSocket("wss://ws.bitstamp.net");
const apiCall = {
event: "bts:subscribe",
data: { channel: "order_book_btcusd" },
};
ws.onopen = (event) => {
ws.send(JSON.stringify(apiCall));
};
ws.onmessage = function (event) {
const json = JSON.parse(event.data);
try {
if ((json.event = "data")) {
setBids(json.data.bids.slice(0, 5));
}
} catch (err) {
console.log(err);
}
};
//map the first 5 bids
const firstBids = bids.map((item) => {
return (
<div>
<p> {item}</p>
</div>
);
});
return <div>{firstBids}</div>;
}
export default App;
So, what's going on here? As you can see, it's a very basic React.js App component. I use useState hook so I import it also with react.
I define the state and give it an initial value.
I proceed as indicated before- except, I set the state to json.data.bids (bids being a property of the live order channel and indicated on bitstamp's page) and restrict the amount of data I'll receive to 5, for the sake of convenience.
I map the data I receive, saved in state (as you know, React asks for a key for each item. I won't be using it here. I usually use uniqid for that, you can check it out yourself.)
I return the mapped data and voilà! If you did the same, you should see exactly 5 rows of constantly changing data on the screen.
I hope this article helps someone.
=============================================================================================================================================> I'M OFFERING FULL STACK BLOCKCHAIN DEVELOPMENT SERVICES: ERC20/721 TOKEN CREATION, TOKEN SALE SMART CONTRACT, WHITELISTING, LENDING PROTOCOL, MARKETING REFERRAL, DAO DEVELOPMENT AND MORE.
FRONT END INTEGRATION INCLUDED.
IF YOU NEED SMART CONTRACTS, CONTACT ME.
IF YOU NEED FRONT END INTEGRATION WITH SMART CONTRACTS, CONTACT ME.
SEE MY OFFERS, CLIENT TESTIMONIALS AND PREVIOUS WORK BY VISITING =>https://www.muratcanyuksel.xyz
OR SEND ME AN EMAIL VIA mail@muratcanyuksel.xyz
=============================================================================================================================================>
All the best and keep coding!
To learn more about programming, subscribe to my Youtube channel => https://www.youtube.com/channel/UCP1hJydcsPZCwbn8rPiohsg
Top comments (19)
I guess your code will create multiple instances of Websocket, you should put this in useEffect hook to avoid that
That's right. I will even go further and create a hook ( useWebsocket that uses useEffect internally) where you can pass the callback functions onopen and onmessage and returns a send function for instance or whatever you need from the hook.
Hey man, I wrote a reply to Vu's comment. Feel free to join the discussion :)
Every time the client receives new message =>
setBids
called => component rerender => create new instance of Websocket => create new connection (1 request in devtools). This's not good, right :)))This is my idea. You can check more in network tab in devtools and see the differents.
Hello, I have 4 components that I repeat the same method and it seems like each one waits its turn to display the data. I was wondering how to fix that, I guess you're taling about that? In my original code, I have useEffect in this manner :
What should I do to overcome the problem you mentioned?
if ((json.event = "data")) {
Why "=", and not "==="?
Because he's not using a linter?
That's why he gets a lot of unfiltered events.
Good question, that was some snippet I found while trying to figure out how to get started, and itseemed to work. I didn't even think about it. Will it cause any problems? It didn't so far...
This condition will always be true because the assignment operator is used instead of the comparison operator.
Gonna edit it (y)
Clear, concise and useful! Thanks for sharing. As others have mentioned using the useEffect hook is likely the best spot for initializing WS, but it adds additional code so 🤷♀️. In any case really great work
Sorry but this article has many technical errors.
Seems you've been aware about them yet you didn't correct the article.
True. I haven't touched websockets after writing this article though, worked on some other stuff and all. I'm thinking of trying to correct it as much as I can once I get the time to dive into websockets further.
I agree
Why use websocket and not socket.io? Just asking to exchange some dialog between the two.
To be honest, I'm not even sure what's the other one. I had 3 days to learn websockets and redux, so I went with that way.
What's the difference between the two? Why should I check socket.io?
Websocket is the native api from your browser whereas socket.io does not implent the same api although it can use websocket under the hood if the browser support it, besides it has the server version that helps the backend keep the same interface with the client and add extra features as authentication , etc.
Once the WebSocket server is created, we had to accept the handshake on receiving the request . dua to make someone call you
thank you so much !
helpful for my assignment