Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
117 views
in Technique[技术] by (71.8m points)

javascript - Managing web-socket client connections on a node service for real-time notifications

I have a side project I have been working on for a while now that involves a React Native mobile app, some node services and a cloud platform (MetaApi) that hosts MetaTrader trading accounts on to permit API based accessed to the trading account data over REST. Recently I have started looking at setting up a real-time data notification service using the web-socket capabilities of the SDK which is a fairly new concept to me.

The challenge that I am facing currently is that for each hosted trading account on the cloud platform, a client socket connection must be established on the notification node service that is kept alive 24/7, and must have event listener actions applied to it in order to receive live data for that account and use this data to trigger actions for example a push notification. Having worked with web-sockets before (socket.io) the challenge here is that for real-time data to be listened to 24/7 for the use-case of a notification service, the client connections are required to be established and persisted on the node notification server, rather than a users device for example where the connection is only required to be established and maintained during the the user session.

I'm unsure on this approach for a couple of reasons:

  1. It seems like initialising and referencing potentially hundreds of client socket connections in memory is going to be terrible for resource consumption and scaling
  2. Failover, if the service running with these client connections on suffers a downtime, all of these connections are lost and must be reinitialised

Is there an approach that I can adopt in this scenario that would make handling this better? At the moment I am considering abandoning this approach to a notification service with the cloud platforms SDK for web-sockets, and instead falling back to perhaps to a polling approach to trigger notifications based on changes in responses utilising the REST API, though not ideal.

I've added some code below that I've been playing with as a reference to how this is being implemented currently on the notification server startup

// Fetch deployed trading accounts from the cloud platform
const fetchAccountsWithSDK = async (limit = 100, offset = 0) =>
  api.metatraderAccountApi.getAccounts({
    limit,
    offset,
    state: ["DEPLOYED"],
  });

// call fetchAccountsWithSDK to build up an array of all deployed accounts?
const getDeployedAccounts = async () => {
  const limit = 100;
  const accounts = [];
  const fetch = async (offset = 0) => {
    const fetched = await fetchAccountsWithSDK(limit, offset);
    accounts.push(...fetched);
    // If the fetched count = the limit, call again to fetch further accounts
    if (fetched.length === limit) return fetch(accounts.length);
    // Returns array of all accounts
    return accounts;
  };
  // Return fetched accounts, starting at offset 0
  return fetch(0);
};

const initAllAccounts = async () => {
  // Use the SDK to get all currently deployed trading accounts on the cloud platform
  const deployedAccounts = await getDeployedAccounts();
    // Create an array of connection references for deployed trading accounts
  const accountConnections = await Promise.all(
    deployedAccounts.map(async (item) => {
      // Initiate a connection with the trading account
      const connectedAccount = await item.connect();
      // Synchronise data from the trading account
      await connectedAccount.waitSynchronized();
      // Initialise event listener actions for trading account connection
      const AccountListeners = new Listeners({ accountId: item._data._id });
      // Apply event listener actions to the trading account connection
      connectedAccount.addSynchronizationListener(AccountListeners);
      // Return an object containing the accountId and a reference to the connection
      return { accountId: item._data._id, connection: connectedAccount };
    })
  );
  // Not sure what do with accountConnections array
  // but a reference needs to be kept somewhere, i.e. if the connection is to be closed due to user closing account(connection.close())
};

// initialise web-socket client connections for all trading accounts and apply socket event listener actions
initAllAccounts();

Here's some sample code of the listeners that are applied to each connection for my use-case:

class Listeners extends SynchronizationListener {
  constructor({ accountId = "" }) {
    super();
    // Assign reference of account id event is for, use in following actions
    this.id = accountId;
  }
  async onDisconnected() {
   // handle account disconnected from trading terminal action here
  }
  async onConnected() {
   // handle account connection action here
  }
  async onAccountInformationUpdated(accountInformation) {
   // handle account information updated here i.e. triggering push notification that trading balance has changed etc
  }
}
question from:https://stackoverflow.com/questions/65862313/managing-web-socket-client-connections-on-a-node-service-for-real-time-notificat

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...