ICE allows a client to request connectivity data for multiple Gateway IDs in a single OnixS::ICE::BOE::Messaging::IPRequest, as long as those IDs belong to the same company. The BUS gateway returns one OnixS::ICE::BOE::Messaging::IPReport containing one entry per requested Gateway ID.
This page summarizes the exchange rules from the ICE Binary Order and Utility Service API Technical Specification and shows how they map to the OnixS handler API.
Protocol Rules
According to the specification:
- before connecting to BGW, the client must obtain IP, port, and ipSessionToken from BUS for each Gateway ID;
- the ipSessionToken is valid for the current exchange trading session only;
- one IPRequest may contain multiple Gateway IDs under the same company;
- BUS assigns each requested Gateway ID to a BGW using round-robin and returns all assignments in a single IPReport;
- BGW rejects logon attempts that use IP, port, or ipSessionToken not assigned for that specific Gateway ID;
- if reconnect to BGW fails after disconnect, the client should restart from Step 1 and request fresh connectivity data from BUS.
- Note
- The specification also states that BUS/BGW assignments are dynamic. Network and firewall rules should permit the full range of BUS and BGW addresses provided by ICE, not only a single previously assigned endpoint.
Handler API Mapping
For single-ID retrieval, OnixS::ICE::BOE::BusSession implements OnixS::ICE::BOE::IBgwCredentialsProvider and exposes:
Threading::SharedFuture<BgwCredentials> getBgwCredentialsAsync(const std::string& userId, bool forceRequest = false);
This helper requests credentials for one Gateway ID at a time and returns a single OnixS::ICE::BOE::BgwCredentials object.
If an application needs one BUS request for several Gateway IDs, it should build OnixS::ICE::BOE::Messaging::IPRequest directly and populate its users repeating group. Each returned entry in OnixS::ICE::BOE::Messaging::IPReport::UsersEntry contains the assigned userId, ipAddress, port, and ipSessionToken.
The BUS response should be processed in OnixS::ICE::BOE::SessionListener::onIPReport. For a multi-ID request, the callback should inspect every OnixS::ICE::BOE::Messaging::IPReport::UsersEntry and update the application's mapping from Gateway ID to the returned IP, port, and ipSessionToken.
Processing IPReport In SessionListener
class BusListener : public SessionListener
{
public:
void onIPReport(const IPReport msg, Session* ) override
{
const auto users = msg.
users();
for (auto&& user : users)
{
if (user.success() && *user.success() == BooleanEnum::True && user.ipAddress() && user.port() && user.ipSessionToken())
{
BgwCredentials bgwCredentials(
toStr(*user.ipAddress()), *user.port(),
toStr(*user.ipSessionToken()));
credentialsByGatewayId_[
toStr(user.userId())] = bgwCredentials;
}
}
}
const auto& credentialsByGatewayId() const noexcept
{
return credentialsByGatewayId_;
}
private:
std::unordered_map<std::string, BgwCredentials> credentialsByGatewayId_;
};
In production code, the handler should also log or otherwise process failed entries returned in IPReport::UsersEntry.
Building A Multi-ID IPRequest
request->clientId(clientId);
auto users = request->users(3);
users[0].userId("GW_1");
users[1].userId("GW_2");
users[2].userId("GW_3");
busSession.send(request);
The same repeating-group API is demonstrated in Repeating Groups.
Usage Notes
- Keep a separate mapping from Gateway ID to returned IP, port, and ipSessionToken.
- Use each returned credential set only with the matching BGW session logon.
- Treat BUS responses as per-session data; do not persist or reuse tokens across trading sessions.
- Reissuing IPRequest for already assigned Gateway IDs is allowed by ICE, but repeated requests are subject to the exchange backoff rules described in the specification.
- When a batch request partially fails, inspect each IPReport::UsersEntry instead of assuming the whole response succeeded uniformly.
See Also