Getting empty object on websocket (Market data feed)

Hi,
I have integrate websocket with React Native. I got websocket response properly with node JS but when I try it with React Native, websocket connection is established but it return empty object i.e, {“isTrusted”:false,“data”:{}} not even binary encoded message.

Please provide solution or reason why I am getting empty object not the encoded message. Also provide how to decode the message after receiving non-empty object in React Native.

Thank you

My implementation code:

import React, {useEffect} from 'react';
import {StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import {Buffer} from 'buffer';

const Upstox = () => {

  useEffect(() => {
    connectWebSocket();
  }, []);

  const getUrl = () => {
    return new Promise(async (resolve, reject) => {
      const apiUrl = 'https://api-v2.upstox.com/feed/market-data-feed/authorize';
      const auth_token = 'AUTH_TOKEN';
      let headers = {
        'Content-type': 'application/json',
        Authorization: 'Bearer ' + auth_token,
      };

      try {
        // Make the API request
        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();
        const url = res.data.authorizedRedirectUri;
        resolve(url);
      } catch (error) {
        console.error('Error:', error);
        reject(error);
      }
    });
  };

  const connectWebSocket = async () => {
    const wsUrl = await getUrl();
    return new Promise((resolve, reject) => {
      const ws = new WebSocket(wsUrl);

      ws.addEventListener('open', () => {
        console.log('connected');
        resolve(ws);

        setTimeout(() => {
          const data = {
            guid: 'someguid',
            method: 'sub',
            data: {
              mode: 'full',
              instrumentKeys: ['NSE_EQ|INE155A01022'],
            },
          };
          ws.send(Buffer.from(JSON.stringify(data)));
        }, 1000);
      });

      ws.addEventListener('close', () => {
        console.log('disconnected');
      });

      ws.addEventListener('message', data => {
        // let res = JSON.stringify(decodeProfobuf(data));
        let res = JSON.stringify(data);
        console.log(res); // gives {"isTrusted":false, "data":{}} empty object
      });

      ws.addEventListener('error', error => {
        console.log('error:', error);
        reject(error);
      });
    });
  };
  return (
    <View style={styles.container}>
      <TouchableOpacity onPress={() => connectWebSocket()}>
        <Text style={{fontSize: 22, fontWeight: 'bold', color: 'black'}}>
          Upstox WebSocket
        </Text>
      </TouchableOpacity>
    </View>
  );
};

We are currently evaluating this matter and will soon provide a complete React JS code. Thank you for your understanding and patience.

HI @Pradeep_Jaiswar,
When will I get a solution for this problem ?

and few questions…

and a few questions…
I am developing a public stock market app in React Native, and for that, I required real-time data from Websocket. So…

  • Is it ok that multiple users are getting the market data with the same authentication token of a particular user ?
  • Is there any limitation on the number of socket connections at a time for a particular auth_token (a single user) ?
  • As I can get only 100 instrument key data from a websocket at a time, if I use the NodeJS server as middleware for Upstox websocket and React Native, this 100 instrument key limitation will affect the functionality of my app because multiple users are getting the data of different instrument keys. So how can I connect a web socket directly to a React Native or React app? Also, is there any limitation to socket connections ?
  • Can I get top market gainer and looser data from the Upstox API?

We’ve included a sample code in our ReactJS repository that we believe will be helpful to you.
Access the sample here

  • Using the same authentication token of a specific user to access market data is not advisable and not recommended.
  • A limit of three websocket connections per authentication will be implemented soon, so please take note of this.
  • Efforts are underway to raise the limit on websocket token numbers. Ensure you stay updated and incorporate this information into the documentation.
  • Data on the top market gainers and losers is currently unavailable through the API.

import React, { useEffect, useState } from “react”;
import { View, Text, StyleSheet, ScrollView } from “react-native”;
import AsyncStorage from “@react-native-async-storage/async-storage”;
import { Buffer } from “buffer”;
import protobuf from “protobufjs”;
import proto from “./marketDataFeed.js”; // Import the compiled JavaScript module

// Initialize Protobuf root
let protobufRoot = null;
const initProtobuf = async () => {
try {
protobufRoot = protobuf.Root.fromJSON(proto);
console.log(“Protobuf part initialization complete”);
} catch (error) {
console.error(“Error initializing Protobuf:”, error);
}
};

// Function to get WebSocket URL
const getUrl = async (token) => {
const apiUrl = “https://api-v2.upstox.com/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);
});
};

const decodeProtobuf = (buffer) => {
if (!protobufRoot) {
console.warn(“Protobuf root not initialized yet!”);
return null;
}
try {
// Log available types in Protobuf root for debugging
console.log(“Available types:”, protobufRoot.lookupAll());

  // Attempt to find the FeedResponse type
  const FeedResponse = protobufRoot.lookupType("com.upstox.marketdatafeeder.rpc.proto.FeedResponse");
  if (!FeedResponse) {
    throw new Error("FeedResponse type not found in Protobuf root");
  }
  return FeedResponse.decode(buffer);
} catch (error) {
  console.error("Error decoding Protobuf message:", error);
  return null;
}

};

// MarketDataFeed component
function MarketDataFeed() {
const [isConnected, setIsConnected] = useState(false);
const [feedData, setFeedData] = useState();

useEffect(() => {
const fetchTokenAndConnect = async () => {
try {
// Initialize Protobuf
await initProtobuf();

    // Retrieve token from AsyncStorage
    const tokenStr = await AsyncStorage.getItem('enctoken');
    if (tokenStr) {
      let token = JSON.parse(tokenStr);
      if (Array.isArray(token)) {
        token = token.join(''); // Convert array to string if needed
      }
      await connectWebSocket(token);
    } else {
      console.warn("No token found in AsyncStorage");
    }
  } catch (error) {
    console.error("Error retrieving token or connecting to WebSocket:", error);
  }
};

const connectWebSocket = async (token) => {
    try {
      if (!token) {
        throw new Error("Token is not available");
      }
      const wsUrl = await getUrl(token);
      if (!wsUrl) {
        throw new Error("WebSocket URL is not available");
      }
      const ws = new WebSocket(wsUrl);
  
      ws.onopen = () => {
        setIsConnected(true);
        console.log("Connected");
        const data = {
          guid: "someguid",
          method: "sub",
          data: {
            mode: "full",
            instrumentKeys: ["NSE_INDEX|Nifty 50"],
          },
        };
        console.log(Buffer.from(JSON.stringify(data)))
        
        ws.send(Buffer.from(JSON.stringify(data)));
      };
  
      ws.onclose = () => {
        setIsConnected(false);
        console.log("Disconnected");
      };
  
      ws.onmessage = async (event) => {
        console.log("Received WebSocket message:", event.data);
        if (event.data) {
          try {
            const arrayBuffer = await blobToArrayBuffer(event.data);
            let buffer = Buffer.from(arrayBuffer);
            let response = decodeProtobuf(buffer);
            console.log("Decoded response:", response);
            setFeedData((currentData) => [
              ...currentData,
              JSON.stringify(response),
            ]);
          } catch (error) {
            console.error("Error processing WebSocket message:", error);
          }
        } else {
          console.warn("Received null or empty data from WebSocket");
        }
      };
      
      
  
      ws.onerror = (error) => {
        setIsConnected(false);
        console.log("WebSocket error:", error);
      };
  
      return () => ws.close();
    } catch (error) {
      console.error("WebSocket connection error:", error);
    }
  };
  
fetchTokenAndConnect();

}, );

return (


Market Feed
<Text
style={[
styles.status,
{ color: isConnected ? “green” : “red” },
]}
>
Status: {isConnected ? “Connected” : “Not Connected”}


{isConnected && (

{feedData.map((data, index) => (

{data}

))}

)}

);
}

const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
},
headerSection: {
marginBottom: 16,
},
headerText: {
fontSize: 24,
fontWeight: “bold”,
},
status: {
fontSize: 16,
marginTop: 8,
},
feedSection: {
marginTop: 16,
},
feedItem: {
marginBottom: 8,
fontSize: 14,
borderWidth: 1,
borderColor: “#ccc”,
padding: 8,
borderRadius: 4,
},
});

export default MarketDataFeed;

this is my code i am succesfully sending data to websocket

44, 34, 100, 97, 116, 97, 34, 58, 123, 34, 109, 111, 100, 101, 34, 58, 34, 102, 117, 108, 108, 34, 44, 34, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 75, 101, 121, 115, 34, 58, 91, 34, 78, 83, 69, 95, 73, 78, 68, 69, 88, 124, 78, 105, 102, 116, 121, 32, 53, 48, 34, 93, 125, 125], “type”: “Buffer”}

but in reaturn i am getting an array please help me with this m, i am working in react native