upstox-js-sdk
Version:
The official Node Js client for communicating with the Upstox API
135 lines (120 loc) • 3.77 kB
JavaScript
import React, { useEffect, useState } from "react";
import proto from "./marketDataFeed.proto";
import { Buffer } from "buffer";
const protobuf = require("protobufjs");
// Initialize Protobuf root
let protobufRoot = null;
const initProtobuf = async () => {
protobufRoot = await protobuf.load(proto);
console.log("Protobuf part initialization complete");
};
// Function to get WebSocket URL
const getUrl = async (token) => {
const apiUrl = "https://api.upstox.com/v2/feed/market-data-feed/authorize";
let headers = {
"Content-type": "application/json",
Authorization: "Bearer " + token,
};
const response = await fetch(apiUrl, {
method: "GET",
headers: headers,
});
if (!response.ok) {
throw new Error("Network response was not ok");
}
const res = await response.json();
return res.data.authorizedRedirectUri;
};
// Helper functions for handling Blob and ArrayBuffer
const blobToArrayBuffer = async (blob) => {
if ("arrayBuffer" in blob) return await blob.arrayBuffer();
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject();
reader.readAsArrayBuffer(blob);
});
};
// Decode Protobuf messages
const decodeProfobuf = (buffer) => {
if (!protobufRoot) {
console.warn("Protobuf part not initialized yet!");
return null;
}
const FeedResponse = protobufRoot.lookupType(
"com.upstox.marketdatafeeder.rpc.proto.FeedResponse"
);
return FeedResponse.decode(buffer);
};
// MarketDataFeed component
function MarketDataFeed({ token }) {
const [isConnected, setIsConnected] = useState(false);
const [feedData, setFeedData] = useState([]);
// Establish WebSocket connection
useEffect(() => {
const connectWebSocket = async (token) => {
try {
const wsUrl = await getUrl(token);
const ws = new WebSocket(wsUrl);
ws.onopen = () => {
setIsConnected(true);
console.log("Connected");
const data = {
guid: "someguid",
method: "sub",
data: {
mode: "full",
instrumentKeys: ["NSE_EQ|INE669E01016"],
},
};
ws.send(Buffer.from(JSON.stringify(data)));
};
ws.onclose = () => {
setIsConnected(false);
console.log("Disconnected");
};
ws.onmessage = async (event) => {
const arrayBuffer = await blobToArrayBuffer(event.data);
let buffer = Buffer.from(arrayBuffer);
let response = decodeProfobuf(buffer);
setFeedData((currentData) => [
...currentData,
JSON.stringify(response),
]);
};
ws.onerror = (error) => {
setIsConnected(false);
console.log("WebSocket error:", error);
};
return () => ws.close();
} catch (error) {
console.error("WebSocket connection error:", error);
}
};
initProtobuf();
connectWebSocket(token);
}, [token]);
return (
<div className="feed-container">
<div className="header-section">
<h1>Market Feed</h1>
<h3 className={`status ${isConnected ? "connected" : "not-connected"}`}>
Status: <span>{isConnected ? "Connected" : "Not Connected"}</span>
</h3>
</div>
{isConnected && (
<div className="feed-section">
<div className="title">Feed</div>
<div>
{feedData.map((data, index) => (
<div key={index} className="feed-item">
{JSON.stringify(data)}
</div>
))}
</div>
</div>
)}
</div>
);
}
export default MarketDataFeed;