webSocketExchange<T> method
Future<JsonRpcResponse<T> >
webSocketExchange<T>(
- Uri uri,
- JsonRpcRequest request, {
- JsonRpcRequestConfig? config,
Makes a JSON-RPC data request to the web socket server.
The request's timeout duration can be set using the config object's
JsonRpcRequestConfig.timeout property.
All other configurations are ignored.
Implementation
@protected
Future<JsonRpcResponse<T>> webSocketExchange<T>(
final Uri uri,
final JsonRpcRequest request, {
final JsonRpcRequestConfig? config,
}) async {
// The subscription's request/response cycle.
WebSocketExchange<T>? exchange;
try {
// Connect the web socket.
await socket.connect(uri);
// Get the existing request/response cycle (if it exists).
exchange = webSocketExchangeManager.get(request.hash());
// If an exchange created using the current connection exists, return the response (which may
// still be pending).
if (exchange != null) {
final DateTime? connectedAt = socket.connectedAt;
if (connectedAt == null) {
throw const WebSocketException('[WebSocketConnection.connectedAt] is null.');
}
if (exchange.createdAt.isBefore(connectedAt)) {
if (exchange.isCompleted) {
await webSocketSubscriptionManager.close(exchangeId: exchange.id);
} else {
throw const WebSocketException('The exchange request expired.');
}
} else {
return exchange.response;
}
}
// Check that existing requests have an id and new requests do not.
assert(
exchange == null ? request.id == null : request.id == exchange.id,
'A [WebSocketExchange] must be initialized with a new or existing exchange request.',
);
// Create a WebSocketExchange for the subscription's request/response cycle.
exchange = WebSocketExchange<T>(request);
// Store the exchange (request/response) to be used for future subscriptions or cancellation.
webSocketExchangeManager.set(exchange);
// Send the [exchange.request] to the JSON-RPC web socket server (the response will be
// recevied by `onSocketData`). The original request may have been modified by
// WebSocketExchange, so use [exchange.request].
//_debugWebSocketRequest(exchange.request);
final List<int> data = json.encode(exchange.request.toJson()).codeUnits;
socket.send(await encrypt(data));
// Return the pending subscription that completes when a success response is received from the
// web socket server (onSocketData) or the request times out.
final Duration timeLimit = config?.timeout ?? const Duration(seconds: 60);
return await exchange.response.timeout(timeLimit, onTimeout: onWebSocketExchangeTimeout());
} catch (error, stackTrace) {
webSocketExchangeManager.remove(exchange?.id);
exchange?.completeError(error, stackTrace);
return Future.error(error, stackTrace);
}
}