WADO Protocol implemented in node.js - node.js

I am creating a very simple DICOM ECHO server with nodejs however I am facing a problem where the clients always respond as can't connect, I am unsure what I am missing, has someone here experience in writing a DICOM ECHO server?
This is the code I have
var net = require('net');
net.createServer(function(socket){
socket.on('data', function(data){
datat = String.fromCharCode.apply(null, new Uint16Array(data));
console.log(datat);
socket.write(data);
socket.end()
});
socket.on('error', function(error){
console.log("Caught server socket error: ")
console.log(error.stack)
console.log(error)
});
}).listen(8041);
console.log('Server running at 127.0.0.1 on port 8041');
I have tried responding with the binary data and also with text data but neither one seems to work.

DICOM Echo is not as simple as a ping. You must implement a subset of the full stack of the DICOM network protocol. Instead of writing your own server with node.js, I would advise you to rely on an existing DICOM server. Orthanc is an example of a free DICOM server designed to act as a back-end service to Web applications. Orthanc has built-in support of DICOM C-Echo, which can be triggered by an AJAX request to its REST API (URI /modalities/{dicom}/echo).
Disclaimer: I am the author of Orthanc.

Related

Can't set headers after they are sent error happens with socket.io

I am writing a very simple nodejs socket.io app. Somehow this returns "can't set headers after they are sent" error. but I can't see the point where the header is set again. I've only called server.listen once and I believe socket.listen works independently so it shouldn't conflict.
I am aware that can't set headers error had been posted a multiple times. I've read them briefly and I also understand how does response.writeHead works under normal circumstances(I've experimented with some node.js apps with response.writeHead, they worked fine most cases) it seems I am missing something from here. is it due to socket.io?
const fs = require("fs");
const server = require("http").createServer();
const io = require("socket.io").listen(server);
server.listen(52273,function(){
console.log("server up");
});
server.on("request",function(request,response){
fs.readFile("mainpage.html",function(error,data){
response.writeHead(200,{"Content-Type":"text/html"});
response.end(data);
});
});
io.sockets.on("connection",function(socket){
var roomName = null;
socket.on("join", function(data){
roomName = data;
socket.join(data);
console.log("client joined" + data);
});
socket.on("message",function(data){
io.sockets.in(roomName).emit("message","test");
});
});
It probably helps a bit here to understand a little bit about how socket.io works with your web server. socket.io uses the webSocket protocol as it's base protocol. A webSocket connection starts with an HTTP request that has special header set in it to indicate the start of a webSocket connection. A properly functioning web server will see this webSocket header and turn the request over to the webSocket handler to initiate the webSocket connection.
But, this handler you have:
server.on("request",function(request,response){
fs.readFile("mainpage.html",function(error,data){
response.writeHead(200,{"Content-Type":"text/html"});
response.end(data);
});
});
Looks like it is responding to every single request that arrives and sending a response, no matter what the request was. So, I can imagine that when the webSocket request comes in you're sending two responses, one from the webSocket server code and one from your request handler above.
Probably, you need to be able to only send your mainpage.html response for particular URLs that are not your webSocket request.
To see a little more about what's going in, insert a console.log() into here:
server.on("request",function(request,response){
console.log(request.url);
fs.readFile("mainpage.html",function(error,data){
response.writeHead(200,{"Content-Type":"text/html"});
response.end(data);
});
});
And, you will probably see you are sending your mainpage.html to a webSocket request which is not what you want to do. You will likely want to add some if logic so that your request handler is avoiding the webSocket requests.
What version of Node you using?
We had the same problem when we were using 0.9.x. I downgraded Node to 0.8.4 and the problem seems to have gone away.
My best guess is something in Node has changed that Socket.io doesnt agree with.
Thanks everyone. I've solved problem by installing express to my experiment app. I've read the manual again and discovered the socket.io v2 is now requiring express app as a dependency. It seems I have been using socket.io v2 but somehow sticked to socket.io v1 style app writing. It also worked when I downgraded it to socket.io v1.
TL;DR - socket.io v2 is not compatible with apps written for socket.io v1. When a socket.io app returns "can't set headers after they are sent" errors, try use proper version of the socket.io or install correct dependencies.

Tracking all the requests and responses of a server using node js

I am beginner in nodejs app development. I have the following requirement,
A Webapp running on a server-A on a host. Another service is to be implemented and run on a different host should intercept all the incoming requests and outgoing responses from the WebApp running on a server-A. All these details has to be stored in a file.
Looking for example or thought on how to implement the intercepting service. Thank you.
Take a look at socket.io, it's a socket client & server for Node.js (here is a demo: http://socket.io/get-started/chat/)
You can use socket.io to send the data between both apps, and then you write the data to a file using file stream:
var fs = require('fs');
fs.writeFile(__dirname "/file.txt", "Hello World!", function(err) {
if(err) {
return console.log(err);
}
console.log("File saved!");
});

Connecting to socket.io 1.x manually using websockets, capacity testing

I am working with a nodejs express server which uses socket.io to communicate an iOS client, and am having a little trouble trying to test how many clients can connect and exchange data at any one time.
My goal is to be able to run a script which connects to socket.io with thousands of different sessions, as well as send and receive data to understand our system's scale. Currently we are using a single dyno on Heroku but will likely be considering other options on AWS soon.
I have found code which should do what I am trying to do for earlier versions of socket.io, such as this, but have had issues since it seems v1.x has a very different handshake protocol. I tried out using the socket.io-client package, but trying to connect multiple times only simulates use of one session, I need to simulate many in independent users.
I have been picking apart the socket.io-client code, but have only gotten so far as creating a connection - I am stuck on the sending data part. If anyone has any knowledge or could point to some written resources on how data is sent between a client and a socket.io server, it would help me out a lot.
Here's what I have so far:
var needle = require('needle'),
WebSocket = require('ws'),
BASE_URL = 'url-to-socket-host:5002';
var connectionNo = 0;
needle.get('http://' + BASE_URL + '/socket.io/?EIO=3&transport=polling&t=1416506501335-0', function (err, resp) {
// parse the sid
var resp = JSON.parse(resp.body.toString().substring(5, resp.body.toString().length));
// use the sid to connect using websockets
var url = 'ws://' + BASE_URL + '/socket.io/?EIO=3&transport=websocket&sid=' + resp.sid;
console.log(connectionNo + ' with sid: ' + resp.sid);
var socket = new WebSocket(url, void(0), {
agent: false
});
socket.on('open', function () {
console.log('Websocket connected: ' + connectionNo);
// I don't understand how to send data to the server here,
// from looking at the source code it should use some kind
// of binary encoding, any ideas?
socket.on('message', function (msg) {
console.log(msg);
});
});
});
I will continue deconstructing the socket.io-client code but if anyone has any clues or recourses that may help, let me know. Thanks.
I ended up setting for using the socket.io-client npm package which has the ability to connect to a new session on every connection. I found an example benchmark in this issue.
There is not so much need for me to manually connect to socket.io using pure websockets and HTTP, but thanks to Yannik for pointing out the parser in use. The spec of the inner workings of v1.x can be found here.
Thanks!
The problem my reside in the fact that you are not using socket.io in your client code. You have imported ('ws') which is another module whose docs are here: https://www.npmjs.org/package/ws.
You probably want to ws.send('something');. When you receive a message in ws, it also comes with an object with a property indicating whether it is binary data or not. If it is, you will need to concatenate the chunks incrementally. There is a canonical way to do this which you can find via google. But it looks a little like this:
var message;
socketConnection.on('data', function(chunk){ message += chunk});

Restify not sending complete xml response

I have a small restify api that talks to sql server and returns xml back. xml response can be quite large and is consumed by Adobe InDesign. Api call works in the browser but when called from InDesign, I get incomplete xml response.
InDesign uses a proprietary scripting language called ExtendScript which uses sockets to communicate. Not sure in Streams is an option.
I have a very similar problem and after a lot of playing around I added a few seconds pause between connection write and read and this resolved the problem for now. I am not a fan of this fix. Anyone has a better idea? I suspect that as the files get bigger you will have to start increasing the timeout.
var conn = new Socket;
if (conn.open (host + ":7000","UTF-8"))
{ conn.write("GET /report/" + ReportID +" HTTP/1.0\n" +
"Content-Type: application/xml; charset=UTF-8\n\n");
$.sleep(2000);
reply = conn.read (999999);
conn.close();
}
You really need to use callbacks and the ->net<- library.
net library doc
var net = require('net');
var client = net.connect({port: 8124},
function() { //'connect' listener
console.log('connected to server!');
client.write('world!\r\n');
});
client.on('data', function(data) {
console.log(data.toString());
client.end();
});
client.on('end', function() {
console.log('disconnected from server');
});
I copied that example from the oficial docs, as you can see you really need to use callbacks on the events, in this case de "data" event, when you get the complete response THEN you proceed to send your response.
Your XML is incomplete because you send the response before the Socket finish to recieve the data.
Remember javascript is non-blocking, and this things can happen, thats why you need to learn how to use events and callbacks.
PLEASE use the net library.
Hope it helps.
PD: im sorry about my poor english but im trying to be helpful.

TCP send message to localhost on port - node.js

I am trying to create using nodes core only a message sent by one server to another server (not clients just server-to-server).
In fact the servers are both the same server message is sent between 2 apps that must not be linked together. one must receive a remote message from the other.
I am looking over all google things and node docs but can't make sense of a few parts of the code for sending.
The first server only should receive messages:
var net=require('net');
var server1=net.createServer(function(nets){
nets.addListener('message',function(data){
console.dir(data);
});
});
server1.listen(8000,'localhost');
The second server should only send messages:
var net=require('net');
var server2=net.createConnection(8000,'localhost',function(nets){
nets.on('connect',function(){
nets.write('message',{'a':1,'foo':'bar'});
});
});
I am having trouble understanding the docs though, I defiantly need to use net because the 2 apps must not be attached to each other so eventEmitter is a no-no
The node.js documentation has some easy examples of both a TCP server as well as a TCP client that you can tweak for your application-specific logic.
Also: the documentation for Socket shows what you can do with an incoming or outgoing socket connection. As you will see, you cannot write JSON directly with node core. You have to stringify it first: sock.write(JSON.stringify({ foo: 'bar' }));

Resources