Api request from nodejs - javascript

It is necessary to obtain data from https://forkdelta.io using api https://github.com/forkdelta/backend-replacement/tree/master/docs/api
Here is the code:
var http = require("http");
http.createServer(function(request, response) {
const io = require('socket.io-client');
socket = io.connect('https://api.forkdelta.com', { transports:
['websocket'] });
socket.on('connect', function() {
console.log('socket connected');
socket.emit('getMarket', {
token: "0x6fff3806bbac52a20e0d79bc538d527f6a22c96b",
user: "" });
});
socket.on('market', function(payload) {
console.log(payload.orders.buys);
});
}).listen(3000);
console.log("Server has started.");
I save it in server.js and execute the command node server.js
I run the code at the link http: // localhost: 3000 from the local server - hangs
I run the code from here https://repl.it/repls/DeafeningBlushingAddons - successfully
Please help me figure out how to correctly run the code from the browser. Next, we intend to parse the data array and convert it to a table.

Please check the console from where you are executing this code, it is actually fetching the data you require...
This is what the data looks like
{ id: '0xd7ff1f49ffde2380b1fd42877b8ce573bfb2c1cace509b1edcb07e757fa13889_buy',
user: '0x5b38d2298666c89efe5f1819347a6004b93bbbe2',
state: 'OPEN',
tokenGet: '0x6fff3806bbac52a20e0d79bc538d527f6a22c96b',
amountGet: '3.50e+22',
tokenGive: '0x0000000000000000000000000000000000000000',
amountGive: '3.500e+15',
expires: '104747875',
nonce: '1340442292',
v: 27,
r: '0xc929ec3f336b4641d84545d27764c43470946c3119221c856c8f72ac3f625edb',
s: '0x5a79fe5728fb47d22c837ae322bff8b43f3de638ddfa3ee5122bf344a0e507dc',
date: '2018-02-14T20:18:30.052233',
updated: '2018-10-02T10:06:53',
availableVolume: '3.15e+18',
ethAvailableVolume: '3.150000000',
availableVolumeBase: '3.150e+11',
ethAvailableVolumeBase: '3.150000000e-7',
amount: '-3.15e+18',
amountFilled: '0',
price: '1e-7' }

Related

SO_REUSEADDR in NodeJs using net package

I have two backends. Backend A and Backend B.
Backend B sends and receives info using a socket server running at port 4243.
Then, with Backend A, I need to catch that info and save it. But I have to also have a socket server on Backend A running at port 4243.
The problem is that, when I run Backend A after running Backend B I receive the error "EADDRINUSE", because I'm using the same host:port on both apps.
If, for Backend A I use Python, the problem dissapear because I have a configuration for sockets that's called SO_REUSEADDR.
Here we have some examples:
https://www.programcreek.com/python/example/410/socket.SO_REUSEADDR
https://subscription.packtpub.com/book/networking-and-servers/9781849513463/1/ch01lvl1sec18/reusing-socket-addresses
But, I want to use JavaScript for coding my Backend A, so I was using the net package for coding the sockets, and I can't get it to work, because of the "EADDRINUSE" error.
The NodeJS documentation says that "All sockets in Node set SO_REUSEADDR already", but it doesn't seem to work for me...
This is my code so far:
// Step 0: Create the netServer and the netClient
console.log(`[DEBUG] Server will listen to: ${HOST}:${PORT}`);
console.log(`[DEBUG] Server will register with: ${AGENT_ID}`);
const netServer = net.createServer((c) => {
console.log('[netServer] Client connected');
c.on('message', (msg) => {
console.log('[netServer] Received `message`, MSG:', msg.toString());
});
c.on('*', (event, msg) => {
console.log('[netServer] Received `*`, EVENT:', event);
console.log('[netServer] Received `*`, MSG:', msg);
});
}).listen({
host: HOST, // 'localhost',
port: PORT, // 4243,
family: 4, // ipv4, same as socket.AF_INET for python
});
// Code copied from nodejs documentation page (doesn't make any difference)
netServer.on('error', function (e) {
if (e.code == 'EADDRINUSE') {
console.log('Address in use, retrying...');
setTimeout(function () {
netServer.close();
netServer.listen(PORT, HOST);
}, 1000);
}
});
const netClient = net.createConnection(PORT, HOST, () => {
console.log('[netClient] Connected');
});
// Step 1: Register to instance B of DTN with agent ID 'bundlesink'
netClient.write(serializeMessage({
messageType: AAPMessageTypes.REGISTER,
eid: AGENT_ID,
}));
With this code, I get the following output in the terminal:
But, with the Python code, the socket connects successfully:
I don't know what to do :(
I hope I get some help here.
Edit 1
By the way, the lsof command, throws me this output for the JavaScript backend:
And this other output for the Python backend:
Edit 2
It really seems to be a problem with JavaScript. I also found this snippet:
var net = require('net');
function startServer(port, host, callback) {
var server = net.createServer();
server.listen(port, host, function() {
callback(undefined, server);
});
server.on('error', function(error) {
console.error('Ah damn!', error);
callback(error);
});
}
startServer(4000, '0.0.0.0', function(error, wildcardServer) {
if (error) return;
startServer(4000, '127.0.0.1', function(error, localhostServer) {
if (error) return;
console.log('Started both servers!');
});
});
From this post:
https://medium.com/#eplawless/node-js-is-a-liar-sometimes-8a28196d56b6
As the author says:
Well, that prints “Started both servers!” which is exactly what we don’t want.
But for me, instead of printing that, I get an error:
Ah damn! Error: listen EADDRINUSE: address already in use 127.0.0.1:4000
at Server.setupListenHandle [as _listen2] (node:net:1319:16)
at listenInCluster (node:net:1367:12)
at doListen (node:net:1505:7)
at processTicksAndRejections (node:internal/process/task_queues:84:21) {
code: 'EADDRINUSE',
errno: -98,
syscall: 'listen',
address: '127.0.0.1',
port: 4000
}
I really cannot make it to run and print "Started both servers!".
Because that's what I want my code to do.
Edit 3
This is the Python server socket: https://gitlab.com/d3tn/ud3tn/-/blob/master/tools/aap/aap_receive.py
This is the important part:
addr = (args.tcp[0], int(args.tcp[1])) # args.tcp[0] = "localhost", args.tcp[1] = "4243"
with AAPTCPClient(address=addr) as aap_client:
aap_client.register(args.agentid) # args.agentid = "bundlesink"
run_aap_recv(aap_client, args.count, args.verify_pl)
It creates an AAPTCPClient, and the only thing that AAPTCPClient does, is the following:
def __init__(self, socket, address):
self.socket = socket
self.address = address
self.node_eid = None
self.agent_id = None
def register(self, agent_id=None):
"""Attempt to register the specified agent identifier.
Args:
agent_id: The agent identifier to be registered. If None,
uuid.uuid4() is called to generate one.
"""
self.agent_id = agent_id or str(uuid.uuid4())
logger.info(f"Sending REGISTER message for '{agent_id}'...")
msg_ack = self.send(
AAPMessage(AAPMessageType.REGISTER, self.agent_id)
)
assert msg_ack.msg_type == AAPMessageType.ACK
logger.info("ACK message received!")
def send(self, aap_msg):
"""Serialize and send the provided `AAPMessage` to the AAP endpoint.
Args:
aap_msg: The `AAPMessage` to be sent.
"""
self.socket.send(aap_msg.serialize())
return self.receive()
def receive(self):
"""Receive and return the next `AAPMessage`."""
buf = bytearray()
msg = None
while msg is None:
data = self.socket.recv(1)
if not data:
logger.info("Disconnected")
return None
buf += data
try:
msg = AAPMessage.parse(buf)
except InsufficientAAPDataError:
continue
return msg
I don't see any bind, and I don't understand why the python code can call "socket.recv", but in my JavaScript code I can't do "netServer.listen". I think it should be the same.
There are things to clarify.
1.) The client uses the bind syscall where the kernel selects the source port automatically.
It does so by checking sys local_portrange sysctl settings.
1.) If you want to bind the client to a static source port, be sure to select a TCP port outside the local_portrange range !
2.) You cannot subscribe to event "*", instead you've to subscribe to the event "data" to receive messages.
For best practice you should also subscribe to the "error" event in case of errors !
These links will get you started right away:
How do SO_REUSEADDR and SO_REUSEPORT differ?
https://idea.popcount.org/2014-04-03-bind-before-connect/
So, for all beginners, who want to dig deeper into networking using node.js…
A working server example:
// Step 0: Create the netServer and the netClient
//
var HOST = 'localhost';
var PORT = 4243;
var AGENT_ID = 'SO_REUSEADDR DEMO';
var net = require('net');
console.log(`[DEBUG] Server will listen to: ${HOST}:${PORT}`);
console.log(`[DEBUG] Server will register with: ${AGENT_ID}`);
const netServer = net.createServer((c) => {
console.log('[netServer] Client connected');
c.on('data', (msg) => {
console.log('[netServer] Received `message`, MSG:', msg.toString());
});
c.on('end', () => {
console.log('client disconnected');
});
c.on('error', function (e) {
console.log('Error: ' + e.code);
});
c.write('hello\r\n');
c.pipe(c);
}).listen({
host: HOST,
port: PORT,
family: 4, // ipv4, same as socket.AF_INET for python
});
// Code copied from nodejs documentation page (doesn't make any difference)
netServer.on('error', function (e) {
console.log('Error: ' + e.code);
if (e.code == 'EADDRINUSE') {
console.log('Address in use, retrying...');
setTimeout(function () {
netServer.close();
netServer.listen(HOST, PORT);
}, 1000);
}
if ( e.code = 'ECONNRESET' ){
console.log('Connection reset by peer...');
setTimeout(function () {
netServer.close();
netServer.listen(HOST, PORT);
}, 1000);
}
});
The Client:
/* Or use this example tcp client written in node.js. (Originated with
example code from
http://www.hacksparrow.com/tcp-socket-programming-in-node-js.html.) */
var net = require('net');
var HOST = 'localhost';
var PORT = 4243;
var client = new net.Socket();
client.setTimeout(3000);
client.connect(PORT, HOST, function() {
console.log("Connected to " + client.address().address + " Source Port: " + client.address().port + " Family: " + client.address().family);
client.write('Hello, server! Love, Client.');
});
client.on('data', function(data) {
console.log('Received: ' + data);
client.end();
});
client.on('error', function(e) {
console.log('Error: ' + e.code);
});
client.on('timeout', () => {
console.log('socket timeout');
client.end();
});
client.on('close', function() {
console.log('Connection closed');
});
Best Hannes
Steffen Ullrich was completely right.
In my JavaScript code, I was trying to create a server to listen to the port 4243.
But you don't need to have a server in order to listen to some port, you can listen with a client too! (At least that's what I understood)
You can create a client connection as following:
const netClient = net.createConnection(PORT, HOST, () => {
console.log('[netClient] Connected');
});
netClient.on('data', (data) => {
console.log('[netClient] Received data:', data.toString('utf8'));
});
And with "client.on", then you can receive messages as well, as if it were a server.
I hope this is useful to someone else.

Cant get connection with Socket.IO from Angular to NodeJS

I am trying to solve this for hours.. if someone can help me.
I cant understand why this doenst emit or receive the message.
At angular I got this error:
http://localhost:4200/socket.io/?EIO=3&transport=polling&t=NEhK-JT 404
4200 is the PORT of my Angular Application and 8080 from my server.
NodeJS:
// Define Porta
const port = process.env.PORT || 8080;
var server = app.listen(port, function () {
console.log('Server Online - ' + port);
});
// Socket.io
var io = require('socket.io').listen(server);
io.on('connect', function (socket) {
console.log(`${socket.id} is connected`);
socket.on('room', function (room) {
console.log('room', room)
socket.join(room);
});
});
Angular 9:
import * as io from 'socket.io-client'
public socket
public orgId: string = '123abc'
ngOnInit(): void {
this.setupSocketConnection();
}
chat(nome: string, avatar: number, mensagem: string) {
io.connect(this.orgId).emit('organizacao', {
nome: nome,
mensagem: mensagem,
avatar: avatar,
});
}
setupSocketConnection() {
this.socket = io.connect(`http://localhost:8080`, {
reconnectionDelay: 1000,
reconnection: true,
reconnectionAttempts: 10,
transports: ['websocket'],
agent: false,
upgrade: false,
rejectUnauthorized: false
});
}
From my Console.log at Server
zEnR7Cp23zcur4_kAAAH is connected
86sIiMA8vRZEN-WcAAAI is connected
SU4K2n9jAx_UO2ndAAAJ is connected
UAwlMpNiZWhw_eo9AAAK is connected
K6myruVum4FPKTeLAAAL is connected
Z5QULdZtdsRo5gC1AAAM is connected
If you are trying to implement rooms then please read https://socket.io/docs/rooms/
For your case what I can see here is that on server-side you are listening to the event named room and on client-side you are emitting to organizacao and also you need to use the socket object instead of io, refer from here https://www.npmjs.com/package/socket.io-client
socket.connect(this.orgId).emit('room', {
nome: nome,
mensagem: mensagem,
avatar: avatar,
});

xterm.js reconnect with same PWD

I am using xterm.js in my web project to have a terminal on the web page. Every time I refresh my page or reconnect socket when a socket connection is broken due to internet fluctuation from the client. The current PWD directory is lost and it falls to specified CWD directory which is user home in my case. So again I have to do cd where I was working.
How can I connect and remain at same PWD where I was last time before page refreshing or socket disconnect?
One of the things I tried is to store term object and connect through the same object when reconnecting if it is already present. Not deleting process and object in on WebSocket disconnect.
var http = require('http');
var express = require('express');
var app = express();
var expressWs = require('express-ws')(app);
var pty = require('node-pty');
var cors = require('cors');
app.use(cors());
app.options('*', cors());
var terminals = {}; //global terminals
function getUser(token) {
return new Promise((resolve, reject) => {
try {
return http.get({
host: '',
path: '',
headers: {'token': token}
}, function(response) {
// Continuously update stream with data
var body = '';
response.on('data', function(d) {
body += d;
});
response.on('end', function() {
return resolve(JSON.parse(body));
});
});
} catch (err) {
console.log('Api failed');
console.log(err);
reject;
}
})
}
app.ws('/terminals/:user_id', function (ws, req) {
try {
getUser(req.params.user_id) /* cheking with api if user exist in my database*/
.then(user_info => {
if(terminals[parseInt(req.params.user_id)]){
var term = terminals[parseInt(req.params.user_id)];
}else {
var term = pty.spawn(process.platform === 'win32' ? 'cmd.exe' : 'bash', [], {
name: 'xterm-color',
cwd: cwd,
env: process.env
});
terminals[parseInt(req.params.user_id)] = term;
}
term.on('data', function(data) {
ws.send(data);
});
ws.on('message', function(msg) {
term.write(msg);
});
ws.on('close', function () {
// process.kill(term.pid);
// delete terminals[parseInt(req.params.pid)];
// delete logs[req.params.pid];
});
})
.catch(err => {
})
} catch (err) {
console.log('Terminal webSocket failed');
console.log(err);
}
});
app.listen(3000);
This is not working for me. This gets me connect only first time but when I refresh my page terminal does not connect with existing store object.
Also, this has a problem if the spawned process is killed by the system but it still remains in javascript object and script try to reconnect with same term object it will fail.
Any guidelines how to achieve reconnect with same PWD.
Details
OS version: Mac OS ,
xterm.js version: 2.2.3
This can be solved very easily by just updating the ~/.bashrc on server
Putting below two line in ~/.bashrc file worked for me
PROMPT_COMMAND+='printf %s "$PWD" > ~/.storepwd'
[ -s ~/.lastdirectory ] && cd `cat ~/.lastdirectory`
Ref Save last working directory on Bash logout

Getting error while creating server fir display wifi scanning result in browser

i am writing a code for display the scan result on web server via http but is always gives me errr any one can solve this issue here is my code
var http = require('http');
var wifi = require('node-wifi');
wifi.init({
debug : true,
iface: 'wlan0'
});
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'application/json'});
var otherArray = ["item1", "item2"];
var otherObject = { item1: "item1val", item2: "item2val" };
var json = JSON.stringify({
anObject: otherObject,
anArray: otherArray,
another: "item"
});
wifi.scan(function(networks){
console.log(networks);
});
res.end(json,networks);
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
Don't know why I'am answering, cause I think your code is completely copied from these posts:
How to run server written in js with Node.js
Responding with a JSON object in NodeJS (converting object/array to JSON string)
But here you go. Try this:
var http = require('http');
var wifi = require('node-wifi');
wifi.init({
debug : true,
iface: 'wlan0'
});
// listen on port 1337
http.createServer((req, res) => {
// set response header
res.writeHead(200, {
'Content-Type': 'application/json'
});
// scan for wifi networks
wifi.scan((err, networks) => {
// check if there is an error
if (err) {
res.end(`{"error":"${err}"}`);
}
// stringify your network object and give it back to the client
else {
res.end(JSON.stringify(networks));
}
});
}).listen(1337);
console.log('Server running at http://127.0.0.1:1337/');
You can also type this into your cli:
Get all network devices: arp -a
Filter network devices: arp -a | grep en0

ember-cli-mirage redirects socket.io client, which is injected in mirage

the issue that occurs here, is that, when i connect between sample socekt.io client with this socket.io server by node.js ( just running two terminals and opening socket connection between client and server)
I have no problems. But, when I am trying to inject this socket.io-client into my Ember.js application, precisely to ember-cli-mirage it redirects my client from given address : ( 'http: //localhost:8080') to something like http: //localhost:8080/socket.io/?EIO=3&transport=polling&.....
also Mirage displays me an error that I cannot handle, even by setting up precise namespace, routing the wsClient.connect() method or calling this.passthrough() , before calling wsClient.connect() .
I also paste the the screenshot of error from inspect console in browser:
error image
Do you have any idea how to resolve this problem? Thank you in advance and I also hope that the topic is not duplicated.
// server.js
var app = require('http').createServer(handler);
var io = require('socket.io')(app);
app.listen(8080);
function handler(req, res) {
res.writeHead(200);
res.end('default.index');
}
var rooms = {
'room1': [
],
'room2': [
]
};
io.on('connection', function(socket) {
console.log('client connected');
socket.on('join', function(roomName) {
rooms[roomName].push(socket.id);
socket.join(roomName);
});
socket.on('leave', function(roomName) {
var toRemove = rooms[roomName].indexOf(socket.id);
rooms[roomName].splice(toRemove, 1);
socket.leave('roomName');
});
socket.on('eNotification', function(data) {
console.log(data);
io.to(socket.id).emit('eNotificationCall', data);
io.to('room2').emit('eventNotification', data);
});
socket.on('gNotification', function(data) {
console.log(data);
io.to(socket.id).emit('gNotificationCall', data);
io.to('room1').emit('diagram1Notification', data);
});
socket.on('close', function() {
console.log('client disconnected');
});
});
//client.js
var wsClient = {
socket: null,
connect: function() {
this.socket = io.connect('http://localhost:8080');
this.socket.on('connect', function() {
console.log('mirage client connected!');
});
},
send: function(eventData, graphData) {
this.socket.emit('eNotification', eventData);
this.socket.emit('gNotification', graphData);
}
};
export default wsClient;
//config.js
import wsClient from './websockets/client';
export default function() {
wsClient.connect();
console.log(wsClient.socket);
var graphData = {X: "2", Y: "3"};
var eventData = {myDAta: 'myDAta', message: 'message'};
setInterval(function() {
wsClient.send(graphData, eventData);
}, 5000);
}
If you call this.passthrough() with no args it only allows requests on the current domain to passthrough. It looks like the websocket connection is on a different port, so try specifying it directly:
this.passthrough('http://localhost:8080/**');
See the docs for more information.

Categories