ohif-viewer/Packages/dimseservice/server/Connection.js
Aysel Afsar dfcb33153f LT-239: Handle the error if the last imported file is not dcm file
- Add message label in progress dialog
2016-04-25 19:01:59 -04:00

244 lines
8.0 KiB
JavaScript
Executable File

var net = Npm.require('net'),
Socket = net.Socket;
var DEFAULT_MAX_PACKAGE_SIZE = 32768;
Connection = function (options) {
EventEmitter.call(this);
this.options = Object.assign({
maxPackageSize: C.DEFAULT_MAX_PACKAGE_SIZE,
idle: false,
reconnect: true,
vr: {
split: true
}
}, options);
this.peers = {};
this.peerSockets = {};
this.defaultPeer = null;
this.defaultServer = null;
}
util.inherits(Connection, EventEmitter);
var StoreHandle = function () {
EventEmitter.call(this);
}
util.inherits(StoreHandle, EventEmitter);
Connection.prototype.addPeer = function (options) {
if (!options.aeTitle || !options.host || !options.port) {
return false;
}
this.peers[options.aeTitle] = {
host: options.host, port: options.port
};
if (options.default) {
if (options.server) {
this.defaultServer = options.aeTitle;
} else {
this.defaultPeer = options.aeTitle;
}
}
if (options.server) {
//start listening
var server = net.createServer();
server.listen(options.port, options.host, function () {
console.log("listening on %j", this.address());
});
server.on('error', function (err) {
console.log("server error %j", err);
});
var o = this;
server.on('connection', function (nativeSocket) {
//incoming connections
var socket = new CSocket(nativeSocket, o.options);
o.addSocket(options.aeTitle, socket);
//close server on close socket
socket.on('close', function () {
server.close();
});
});
}
};
Connection.prototype.selectPeer = function (aeTitle) {
if (!aeTitle || !this.peers[aeTitle]) {
throw "No such peer";
}
return this.peers[aeTitle];
};
Connection.prototype._sendFile = function (socket, sHandle, file, maxSend, metaLength, list) {
var fileNameText = typeof file.file == 'string' ? file.file : 'buffer';
console.log("Sending file " + fileNameText);
var useContext = socket.getContextByUID(file.context), self = this;
PDU.generatePDatas(useContext.id, file.file, maxSend, null, metaLength, function (err, handle) {
if (err) {
console.log('Error while sending file');
return;
}
var processNext = function () {
var next = list.shift();
if (next)
self._sendFile(socket, sHandle, next, maxSend, metaLength, list);
else
socket.release();
};
var store = socket.storeInstance(useContext.abstractSyntax, file.uid);
handle.on('pdv', function (pdv) {
socket.sendPData(pdv);
});
handle.on('error', function (err) {
sHandle.emit('file', err, fileNameText);
processNext();
});
store.on('response', function (msg) {
var statusText = msg.getStatus().toString(16);
console.log('STORE reponse with status', statusText);
var error = null;
if (msg.failure()) {
error = new Error(statusText);
}
sHandle.emit('file', error, fileNameText);
processNext();
});
});
};
Connection.prototype.storeInstances = function (fileList) {
var contexts = {}, read = 0, length = fileList.length, toSend = [], self = this, handle = new StoreHandle();
var lastProcessedMetaLength;
fileList.forEach(function (bufferOrFile) {
var fileNameText = typeof bufferOrFile == 'string' ? bufferOrFile : 'buffer';
DicomMessage.readMetaHeader(bufferOrFile, function (err, metaMessage, metaLength) {
read++;
if (err) {
handle.emit('file', err, fileNameText);
if (read == length && toSend.length > 0 && lastProcessedMetaLength) {
sendProcessedFiles(self, contexts, toSend, handle, lastProcessedMetaLength);
}
return;
}
console.log('Dicom file ' + (typeof bufferOrFile == 'string' ? bufferOrFile : 'buffer') + ' found');
lastProcessedMetaLength = metaLength;
var syntax = metaMessage.getValue(0x00020010),
sopClassUID = metaMessage.getValue(0x00020002),
instanceUID = metaMessage.getValue(0x00020003);
if (!contexts[sopClassUID]) {
contexts[sopClassUID] = [];
}
if (syntax && contexts[sopClassUID].indexOf(syntax) == -1) {
contexts[sopClassUID].push(syntax);
}
toSend.push({file: bufferOrFile, context: sopClassUID, uid: instanceUID});
if (read == length) {
sendProcessedFiles(self, contexts, toSend, handle, metaLength);
}
});
});
return handle;
};
// Starts to send dcm files
sendProcessedFiles = function (self, contexts, toSend, handle, metaLength) {
var useContexts = [];
for (var context in contexts) {
var useSyntaxes = contexts[context];
if (useSyntaxes.length > 0) {
useContexts.push({context: context, syntaxes: contexts[context]});
} else {
throw "No syntax specified for context " + context;
}
}
self.associate({
contexts: useContexts
}, function (ac) {
var maxSend = ac.getMaxSize(), next = toSend.shift();
self._sendFile(this, handle, next, maxSend, metaLength, toSend);
});
};
Connection.prototype.storeResponse = function (messageId, msg) {
var rq = this.messages[messageId];
if (rq.listener[2]) {
var status = rq.listener[2].call(this, msg);
if (status !== undefined && status !== null && rq.command.store) {
//store ok, ready to send c-store-rsp
var storeSr = rq.command.store,
replyMessage = storeSr.replyWith(status);
replyMessage.setAffectedSOPInstanceUID(this.lastCommand.getSOPInstanceUID());
replyMessage.setReplyMessageId(this.lastCommand.messageId);
this.sendMessage(replyMessage, null, null, storeSr);
} else {
throw "Missing store status";
}
}
};
Connection.prototype.allClosed = function () {
var allClosed = true;
for (var i in o.peerSockets) {
if (Object.keys(o.peerSockets[ae]).length > 0) {
allClosed = false;
break;
}
}
return allClosed;
};
Connection.prototype.addSocket = function (ae, socket) {
if (!this.peerSockets[ae]) {
this.peerSockets[ae] = {};
}
this.peerSockets[ae][socket.id] = socket;
var o = this;
socket.on("close", function () {
if (o.peerSockets[ae][this.id]) {
delete o.peerSockets[ae][this.id];
}
});
};
Connection.prototype.associate = function (options, callback) {
var hostAE = options.hostAE ? options.hostAE : this.defaultPeer,
sourceAE = options.sourceAE ? options.sourceAE : this.defaultServer;
if (!hostAE || !sourceAE) {
throw "Peers not provided or no defaults in settings";
}
var peerInfo = this.selectPeer(hostAE), nativeSocket = new Socket();
var socket = new CSocket(nativeSocket, this.options), o = this;
if (callback) {
socket.once('associated', callback);
}
socket.setCalledAe(hostAE);
socket.setCallingAE(sourceAE);
nativeSocket.connect({
host: peerInfo.host, port: peerInfo.port
}, function () {
//connected
o.addSocket(hostAE, socket);
if (options.contexts) {
socket.setPresentationContexts(options.contexts);
} else {
throw "Contexts must be specified";
}
socket.associate();
});
return socket;
};