So i'm building an vscode extension in typescript and node and i have a python app which sends data with socket to localhost 8080 and im catching it like this :
export default async function getSock(port, adress, dataOld): Promise<void> {
let server = net.createServer(function (socket) {
socket.setEncoding('binary');
socket.on('data', async function (data) {
console.log('client send:' + data);
let m = port
new **UI**(data);
server.close()
});
socket.on('error', function (exception) {
console.log('socket error:' + exception);
socket.end();
});
socket.on('close', function (data) {
console.log('client close:' + data);
});
socket.on('end', function() {
console.log('disconnected from server');
server.close()
});
})
server.listen({port: port, adress: adress});
}
Now i need some mechanism that if listening for 5 seconds and no data passed from the socket, i stop listening and call "new UI(dataOld)"
Related
I found these two links about clinet/server socket programming in NodeJS:
TCP Example &
NetJS;
So i configured my micro server like this:
const SOCKETServer = net.createServer((socket) => {
socket.write('Server is listening!\r\n');
socket.pipe(socket);
});
SOCKETServer.on('data', (data) => {
console.log('CLIENT: ' + data.toString());
});
SOCKETServer.listen(5000, '127.0.0.1');
and also my client like this:
const net = require('net');
const client = new net.Socket();
client.connect(5000, '127.0.0.1', () => {
setTimeout(sender, 1500, null);
});
client.on('data', (data) => {
console.log('SERVER: ' + data);
});
let sender = () => {
client.write('Hello Server\r\n');
setTimeout(sender, 1500, null);
};
The code works fine and i can get data from server in client. I also can send data to server from client and i can read and see its feedback in client cause of socket.pipe(socket). The problem is i cannot read anything in data event in server.
Here:
SOCKETServer.on('data', (data) => {
console.log('CLIENT: ' + data.toString());
});
net.Server doesn't have data event.
You should read from incoming socket in createServer
const SOCKETServer = net.createServer((socket) => {
socket.write('Server is listening!\r\n');
socket.on('data', function(data) {
console.log('CLIENT:', data.toString());
})
socket.pipe(socket);
});
I have a problem with socket.io from nodeJs.
I am trying to create a connection from a client to a server. Once the client is connected, the server sends a message to the client (ack).
Until then, everything works fine but when I disconnect the server and restart it, it sends me the message twice to the client.
If I repeat the manipulation a third time, three messages will appear.
I have captured the problem:
client.js
var socket = require('socket.io-client')('http://localhost:8050', {
'forceNew':true
});
socket.on('connect', onConnect);
function onConnect(){
console.log('connect ' + socket.id);
socket.emit('sendConnect','First connect');
socket.on("ack", function(data) {
console.log("ack reçu");
});
socket.on('disconnect', function(reason) {
console.log(reason);
});
}
server.js
var io = require("socket.io");
var sockets = io.listen(8050);
sockets.on('connection', function (socket) {
socket.on('sendConnect', function (data) {
console.log("message :" + data);
socket.emit('ack');
socket.on('disconnect', function() {
console.log('Got disconnect!');
});
});
});
I looked if this bug was already arriving without finding an answer.
I must surely be doing something wrong!
Thank you in advance for your help.
Your onConnect function adds new event listeners each time the socket connects. Move the event subscriptions out of onConnect like this:
var socket = require('socket.io-client')('http://localhost:8050', {
forceNew: true
});
socket.on('connect', onConnect);
socket.on('ack', function(data) {
console.log('ack reçu');
});
socket.on('disconnect', function(reason) {
console.log(reason);
});
function onConnect() {
console.log('connect ' + socket.id);
socket.emit('sendConnect', 'First connect');
}
Here is an example of how to create a TCP client connection from the node net docs (https://nodejs.org/api/net.html#net_net_connect_options_connectlistener)
const client = net.createConnection({ port: 1905 }, () => {
// 'connect' listener
console.log('connected to server!');
client.write('world!\r\n');
});
client.on('data', (data) => {
console.log(data.toString());
client.end();
});
client.on('end', () => {
console.log('disconnected from server');
});
If the server is not available I get Error: connect ECONNREFUSED 127.0.0.1:1905.
What would be a good way to wait/reconnect until the server is available and connect when it is, instead of throwing an error?
EDIT: Here is an alternative approach I have tried, but here I get the problem
MaxListenersExceededWarning: Possible EventEmitter memory leak
detected. 11 connect listeners added. Use emitter.setMaxListeners() to
increase limit
I would like the latest listener to replace earlier listeners. They all listen for the same thing. I just want to retry.
function initTcpClient() {
console.log("Initiating TCP client...")
var tcpSocket = new net.Socket();
const client = net.createConnection({ port: 1905 }, () => {
tcpSocket.on('error', function onError(err) {
setTimeout(connect, 1000);
});
connect();
function connect() {
console.log("Looking for TCP server...");
tcpSocket.connect(argv.tcpport, argv.tcphost, function onConnected() {
console.log("Connecting to TCP server...");
tcpSocket.on('data', function onIncoming(data) {
if (connectedWebsocketClient) {
console.log('Forwarding to WebSocket: %s', data);
webSocketClient.send(data.toString());
} else {
console.log('Not connected to websocket client. Dropping incoming TCP message: %s', data);
}
});
tcpSocket.on('close', function onClose(hadError) {
console.log("Connection to TCP server was closed.");
connectedToTcpServer = false;
setTimeout(connect, 1000);
});
console.log("Connected to TCP server.");
connectedToTcpServer = true;
});
}
}
Here to elaborate on my comment. Is an example that will work. Try it with a simple tcp server. Start the client and then after a few seconds start the server. It is important to register you listeners after a reconnect happens in onError You may also want to have a limit of how many times you want to try to reconnect.
const net = require('net')
let client = connect()
client.on('data', onData);
client.on('error', onError);
client.on("close", onClose);
function onData(data) {
console.log(data)
}
function onError(err) {
if(err.message.indexOf('ECONNREFUSED') > -1) {
//do recconect
console.log("Attempting to reconnect shortly")
setTimeout(()=>{
client = connect();
client.on('data', onData);
client.on('error', onError);
client.on("close", onClose);
},1000)
}
}
function onClose() {
console.log("Removng all listeners")
client.removeAllListeners("data");
client.removeAllListeners("error")
}
function connect() {
const c = net.createConnection({
port: 3000
},
()=>{
console.log('connected')
});
return c
}
I am running mosquitto broker on 'iot.eclipse.org'.After publishing some commands to broker from my app server,client is disonnecting and calling reconnect and close methods continuously,but not connecting again unless I restart my server.But I want it to reconnect again,once connection breaks.
My code is as follows:
var options = {
host: 'iot.eclipse.org',
port: 1883,
};
var client = mqtt.connect(options);
client.on('connect', function (e) {
console.log("client is connected");
client.publish(topic, message,callback);
});
client.on("reconnect", function() {
console.log("client is reconnected",JSON.stringify());
})
client.on("error", function(err) {
console.log("error from client --> ", err);
})
client.on("close", function(e) {
console.log("client is closed",JSON.stringify(options),JSON.stringify(e));
})
client.on("offline", function(err) {
console.log("client is offline");
});
client.on('message', function (topic, message) {
console.log('*********');
console.log(message.toString());
})
I have two commands to send to server, first move forward, get the acknowledgment and then send next command move backward. I have written two separate java script files do achieve this. Can it is possible to write in single function. I am trying below code but only move forward command is sent to server.
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 1850;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
client.write('READER_FWD');
//client.end();
});
client.on('data', function(data) {
console.log('DATA: ' + data);
//client.destroy();
//
if (data == 'ACK')
{
console.log('DATA1: ' + data);
client.end();
console.log('DATA2: ' + data);
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
client.write('READER_BWD');
//client.end();
console.log('DATA3: ' + data);
});
}
client.end();
});
client.on('end', function() {
console.log('disconnected from server');
});
client.on('error', function(err) {
console.log(err)
});
I have updated the code, as you rightly pointed out connection is getting close while writing, i have added some delay.
var net = require('net');
var config = {
host: '127.0.0.1',
port: 1850
};
var move = {
forward: 'READER_FWD',
backward: 'READER_BWD'
};
var client = new net.Socket();
client.connect({
host: config.host,
port: config.port
}, function () {
console.log('connected to ' + config.host + ':' + config.port);
client.write(move.forward, function () {
console.log('move forward command sent');
});
});
client.on('data', function (data)
{
var str = data.toString();
if (str === 'ACK')
{
setTimeout(function()
{
console.log('ACK received');
client.write(move.backward, function ()
{
console.log('move backward sent');
client.end();
});
}, 3000);
}
});
client.on('error', function (err) {
console.log('Error : ', err);
});
client.on('close', function () {
console.log('socket closed');
});
You don't have to end your socket and re-open it again in your 'data' listener. You can keep the same socket.
Here is my client.js file which sends the commands:
var net = require('net');
var config = {
host: '127.0.0.1',
port: 1850
};
var move = {
forward: 'READER_FWD',
backward: 'READER_BWD'
};
var client = new net.Socket();
client.connect({
host: config.host,
port: config.port
}, function () {
console.log('connected to ' + config.host + ':' + config.port);
client.write(move.forward, function () {
console.log('move forward command sent');
});
});
client.on('data', function (data) {
var str = data.toString();
if (str === 'ACK') {
console.log('ACK received');
client.write(move.backward, function () {
console.log('move backward sent');
client.end();
});
}
});
client.on('error', function (err) {
console.log('Error : ', err);
});
client.on('close', function () {
console.log('socket closed');
});
The connect() method connects the socket to the server and send the forward command to it. It's exactly the same as yours.
Then, the problem comes from your 'data' listener. Your data listener must do the following things (as you mentionned in your description):
Get data from the server
If it's the ACK message: send the backward command
Then, close the connection (if needed; if not, keep it alive)
Be careful to the following point: the Socket nodejs documentation for the event 'data' says that we are receiving a Buffer. So you need to convert it to a String to compare with another String, using for this the .toString() method of the Buffer.
Thus, as is the Nodejs net.Socket is used with events, I don't think it is possible to send the forward command, listen to the 'data' event and send the backward command.
First, it is not a good idea, because you will put the on 'data' listener after the connection and it is possible that you will miss some data!
Secondly, as it is event based, you should create your architecture that follows the process :)
Below is my code for the server:
var net = require('net');
var port = 1850;
var move = {
forward: 'READER_FWD',
backward: 'READER_BWD'
};
var server = net.createServer(function (client) {
console.log('client connected');
client.on('end', function () {
console.log('client disconnected');
});
client.on('data', function (data) {
var str = data.toString();
if (str === move.forward) {
console.log('move forward command received');
client.write('ACK', function () {
console.log('ACK sent');
});
} else if (str === move.backward) {
console.log('move backward command received: do nothing...');
} else {
console.log('unknown received message: ', str);
}
});
});
server.listen(port, function () { //'listening' listener
console.log('server bound on port: ' + port);
});
Here are also the outputs if needed:
Server:
server bound on port: 1850
client connected
move forward command received
ACK sent
move backward command received: do nothing...
client disconnected
Client:
connected to 127.0.0.1:1850
move forward command sent
ACK received
move backward sent
socket closed
I hope it answers the question. Feel free to ask if there is anything.