DIMSE starts with a configured DICOM peer.
Traditional DICOM archives communicate using DIMSE operations over DICOM associations. EASI JS adds Node.js transports for Verification, Store, and a bounded Query/Retrieve profile. The core parser and output targets still do the application-facing work.
These examples require a reachable archive, such as an Orthanc instance you control. They are separate from the offline tutorials. Before running them:
- Confirm the peer’s DICOM listener address and port. This is its DICOM port, rather than its HTTP or DICOMweb port.
- Set
calledAeTitleto the peer’s AE title, andcallingAeTitleto your application’s AE title. - Configure the peer to allow your application’s AE and host where its policy requires that.
- Use a test archive with synthetic data, and replace sample queries and identifiers with values at that peer.
Import transports from @xinonix/easi-js/dimse/node. A browser interface needs a Node backend for these connections. Browser-compatible DICOM processing remains available through the core package.
Start with C-ECHO.
Verification checks whether a DICOM association and echo operation can complete with your configured peer. Replace the example address, port, and AE titles before running it.
import {
DimseClientBuilder,
NodeDimseQueryRetrieveSourceTransport
} from '@xinonix/easi-js/dimse/node';
const association = {
host: '127.0.0.1',
port: 4242,
calledAeTitle: 'ORTHANC',
callingAeTitle: 'EASI_JS',
associationTimeoutMs: 30000
};
const client = new DimseClientBuilder()
.withAssociation(association)
.withTransport(new NodeDimseQueryRetrieveSourceTransport())
.build();
const verification = await client.echo({ operationTimeoutMs: 10000 });
console.log(verification.ok, verification.status); // Success: true, 0A successful response has ok: true and status 0. If this fails, check the listener, routing, firewall, and AE policy before moving to Query/Retrieve. A successful echo does not establish that the peer supports every other operation.
Query once, then choose the result shape.
C-FIND returns matching identifiers. The pipeline below asks for study-level metadata and maps each returned study into a FHIR summary. Its default subject mode uses a contained Patient; use configured references when integrating with your own patient identity system.
import EASI from '@xinonix/easi-js';
import {
NodeDimseQueryRetrieveSourceTransport
} from '@xinonix/easi-js/dimse/node';
const association = {
host: '127.0.0.1',
port: 4242,
calledAeTitle: 'ORTHANC',
callingAeTitle: 'EASI_JS',
associationTimeoutMs: 30000
};
const pipeline = EASI.pipelineBuilder()
.fromDimseAssociation(association, new NodeDimseQueryRetrieveSourceTransport())
.ofDicomData()
.toFHIRImagingStudy('study-summary')
.build();
const studies = await pipeline.process({
sourceOptions: {
operation: 'c-find',
queryRetrieveModel: 'study-root',
queryRetrieveLevel: 'STUDY',
keys: { PatientID: 'RESEARCH-*' },
returnKeys: [
'StudyInstanceUID', 'PatientID', 'PatientName', 'StudyDate',
'ModalitiesInStudy', 'NumberOfStudyRelatedSeries',
'NumberOfStudyRelatedInstances'
],
operationTimeoutMs: 30000
}
});
console.log(studies.toArray().map(study => study.toJSON()));
console.log(pipeline.reader.lastMetadata.dimse.finalResponse);keys constrain the query. returnKeys request fields your output needs. A peer may omit unavailable optional attributes or reject unsupported keys. Use toInstances() if you want identifier datasets rather than FHIR summaries.
A successful query with no matches returns an empty result collection. The transport’s finalResponse preserves status and counters separately from the mapped output.
Choose how instances return to your application.
| Operation | Where incoming Store objects arrive | What to configure |
|---|---|---|
| C-GET | On the same association | Supported storage SOP classes and transfer syntaxes |
| C-MOVE | On a separate Store listener | A destination AE route at the archive, plus a reachable local listener |
This GET recipe targets a single identified instance. Replace all three UIDs with an existing study, series, and instance at your peer. performFind: false skips the preliminary FIND because the identifiers are already known.
import EASI from '@xinonix/easi-js';
import {
NodeDimseQueryRetrieveSourceTransport
} from '@xinonix/easi-js/dimse/node';
const association = {
host: '127.0.0.1',
port: 4242,
calledAeTitle: 'ORTHANC',
callingAeTitle: 'EASI_JS',
associationTimeoutMs: 30000
};
const pipeline = EASI.pipelineBuilder()
.fromDimseAssociation(association, new NodeDimseQueryRetrieveSourceTransport())
.ofDicomData()
.toInstances()
.build();
try {
const instances = await pipeline.process({
sourceOptions: {
operation: 'c-get',
performFind: false,
queryRetrieveModel: 'study-root',
queryRetrieveLevel: 'IMAGE',
keys: {
StudyInstanceUID: '2.25.123',
SeriesInstanceUID: '2.25.123.1',
SOPInstanceUID: '2.25.123.1.1'
},
operationTimeoutMs: 60000
}
});
console.log(instances.count, pipeline.reader.lastMetadata.dimse.finalResponse);
} catch (error) {
console.error(error.message, error.dimse);
process.exitCode = 1;
}To use MOVE, the archive must already map moveDestinationAeTitle to your listener’s reachable address and fixed moveStorePort. The local moveStoreHost is a bind address; configuring it does not register a route at the archive. The complete retrieval guide shows that configuration.
For outgoing C-STORE, provide a complete Part 10 object with file metadata. The small raw dataset from our writing tutorial is not that input. The transport preserves bytes and does not transcode them to a peer-selected transfer syntax.
Inspect completion and bound the work.
Warning statuses can retain partial results. Failure and cancellation reject with peer information in error.dimse. Inspect the final status, completed/failed/warning counters, and failed instance UIDs before treating a retrieval as complete.
associationTimeoutMs is a socket idle timeout. operationTimeoutMs is an optional absolute operation deadline. Use a deadline for peers that could keep sending pending responses; a local abort closes the association rather than sending a graceful C-CANCEL exchange.
The Node transports buffer complete datasets and retrieved output before the pipeline consumes them. Memory includes retained datasets, Part 10 wrappers, and multipart copies. Query a smaller series or instance and lower the transport limits to match your deployment.
| Limit | v1 default |
|---|---|
maxIncomingPduLength | 16 MiB |
maxCommandBytes | 1 MiB |
maxDataSetBytes | 512 MiB per dataset |
maxTotalDataSetBytes | 512 MiB retained datasets per operation |
These dataset limits are not total process-memory limits. Transport acceptance also does not establish pixel-decoder support.
The independent Orthanc validation matrix covers Echo, Store send/receive, and Study Root FIND/GET/MOVE with synthetic inputs. Query/Retrieve SCP services, worklist, normalized services, and asynchronous multiplexing are outside that matrix. Review the v1 profile against your peer and deployment requirements.
Read the complete DIMSE v1 profile
Explore Store send/receive, MOVE routing, transport options, and the independent-peer validation matrix.