Duplicate messages between connected servers using hyperswarm library - javascript

I am trying to send a message from one connected node server to the other using the following code in server.js and server1.js:
const hyperswarm = require('hyperswarm')
const crypto = require('crypto')
const swarm = hyperswarm()
// look for peers listed under this topic
const topic = crypto.createHash('sha256')
.update('mycoolstuff')
.digest()
swarm.join(topic, {
lookup: true, // find & connect to peers
announce: true // optional- announce self as a connection target
})
swarm.on('connection', (socket, details) => {
//console.log('new connection!', details)
// you can now use the socket as a stream, eg:
process.stdin.pipe(socket).pipe(process.stdout)
})
The problem is the message from one terminal is duplicated on the other.
For example, if I type the following in server.js's terminal:
test 123
I get the following in server1.js's:
test 123
test 123
. . . and vice versa
I can work around this by setting one of the two servers to not announce:
swarm.join(topic, {
lookup: true, // find & connect to peers
announce: false // <--------- don't announce, stops duplicates
})
But I would prefer that both servers announce.
What am I misunderstanding about sockets, stdin, or hyperswarm here?

Well, I found my own answer inside the node module folder for hyperswarm in the file called example.js
I added the following:
const {
priority,
status,
retries,
peer,
client
} = details
if (client) process.stdin.pipe(socket)
else socket.pipe(process.stdout)
Which solved my problem.

Related

How can I debug Stanza.js Authentication?

I'm currently attempting to setup an XMPP client using Stanza.js
https://github.com/legastero/stanza
I have a working server that accepts connections from a Gajim client, however when attempting to connect using Stanza.js client.connect method, the server opens up a websocket connection, but no events for authentication, or session started ever fire.
The server logs do not show any plaintext password authentication attempts.
How can I actually see any of the stanza logs to debug this issue?
import * as XMPP from 'stanza';
const config = { credentials: {jid: '[jid]', password: '[password]'}, transports: {websocket: '[socketurl]', bosh: false} };
const client = XMPP.createClient(config)
client.on('raw:*', (data) => {
console.log('data', data)
})
client.connect();
onconnect event does fire, but this is the only event that fires.
Is there a way to manually trigger authentication that isn't expressed in the documentation?
The raw event handler should be able to give you the logging you want - but in your code sample, you are invoking it incorrectly. Try the following.
client.on('raw:*', (direction, data) => {
console.log(direction, data)
})
For reference, the docs state that the callback for the raw data event handler is
(direction: incoming | outgoing, data: string) => void
So the data that you are looking for is in the second argument, but your callback only has one argument (just the direction string "incoming" or "outgoing", although you have named the argument "data").
Once you fix the logging I expect you will see the stream immediately terminates with a stream error. Your config is incorrect. The jid and password should be top level fields. Review the stanza sample code. For the options to createClient - there is no credentials object. Try the following:
const config = { jid: '[jid]', password: '[password]', transports: {websocket: '[socketurl]', bosh: false} };
Since your username and password are hidden behind an incorrect credentials object, stanza.io does not see them and you are effectively trying to connect with no username and password so no authentication is even attempted.
This issue happened to be caused by a configuration problem.
The jabber server was using plain authentication.
Adding an additional line to the client definition file helped.
Also adding
client.on('*', console.log)
offered more complete server logs.
client.sasl.disable('X-OAUTH2')
How can I actually see any of the stanza logs to debug this issue?
If the connection is not encrypted, you can sniff the XMPP traffic with tools like
sudo tcpflow -i lo -Cg port 5222
You can force ejabberd to not allow encryption, so your clients don't use that, and you can read the network traffic.
Alternatively, in ejabbed.yml you can set this, but probably it will generate a lot of log messages:
loglevel: debug

Command that takes info from FiveM

I would like to build a command , in Node.js with Visual Studio Code, which will take data from FiveM and will show in a message how many players are online and if there is a Queue !
I will post an image and I will show what i mean:
I am using a code that logs in console and the code is :
const Gamedig = require('gamedig');
Gamedig.query({
type: 'fivem',
host: 'fivem.example.com'
}).then((state) => {
console.log(state);
}).catch((error) => {
console.log("Server is offline");
});
I would like to ask if there is a way to set as command and display "image" view!
According to the gamedig documentation, the state param that is going in the callback function have not that much predefined properties. You can retrieve directly how many players are online by the players.length property, accessing it by state.players.length inside the callback function in the then() method. But there's too a raw property which seems to return all the info the server gives you back, so you can try to parse it and retrieve any other relevant info.
Use the FiveM package to get server info.
You can get the players like this:
const FiveM = require("fivem") // Import the npm package.
const srv = new FiveM.Server('IP:PORT') // Set the IP with port.
srv.getPlayers().then(data => console.log(data)) // Get & log the data!
or the whole server object:
srv.getServer().then(data => console.log(data)) // Get & log the data!
Enjoy.

How to connect to a TCP server and pass a Javascript to it

I'm definitely a newbie with JS and node. I have telescope management software called SkyX Pro, and it has the ability to run a TCP Server on port 3040. I can connect to it using Netcat and hand it a Javascript starting with //* Javascript *// this works and allows me to startup cameras and other equipment and send commands for taking pictures etc. The issue is it needs to be run from a batch file which makes getting any information back to an HTML page tough (Like Camera, focuser and filter wheel status and temperatures).
The NC call looks like "NC localhost 3040 < Javascript-file.js
To get around the browser to local machine security issues I want to run this from node.js with maybe socket.io-client if possible, but I don't know the proper syntax for it.
I have seen plenty of client syntax sending hello's etc. but nothing send javascript and allowing for two-way connectivity that I can understand.
I have tried using:
var socket = io.connect('http://localhost');`enter code here`
socket.on('httpServer', function (data) {
console.log(data);
document.write(data + "\r\n");
socket.emit('tcp', "For TCP");
});
const net = require('net');
const client = new net.Socket();
client.connect({ port: 3040, host: process.argv[2] });
client.on('data', (data) => {
console.log(data.toString('utf-8'));
But I do not understand it well enough to troubleshoot why it's not working.
Any help would be wonderful, and please treat me like a baby that needs its step by step.
Cheer
Peter
Reading [1], We can assume socket-io isn't the perfect fit for you, because that Server you have sound like a typical tcp-socket server, not a socket.io server ( which requires special headers ) or a web-socket server.
So you only needs "net" library to do the job.
const net = require('net');
// module to send a message to TCP-socket server and wait for the response from socket-server
const sendAndReceive = async (client, message) => {
client.write(message);
let response = null
await ( new Promise( (resolve, reject) => {
client.on('data', function(data) {
response = data;
resolve()
});
}))
return response;
}
// send a single message to the socket-server and print the response
const sendJSCode = (message) => {
// create socket-client
const client = new net.Socket();
client.connect(3040, 'localhost', async function() {
console.log('Connected');
// send message and receive response
const response = await sendAndReceive(client, message)
// parse and print repsonse string
const stringifiedResponse = Buffer.from(response).toString()
console.log('from server: ', stringifiedResponse)
// clean up connection
client.destroy()
});
}
sendJSCode('var Out; \n Out="TheSky Build=" + Application.build \n\r')
This script will:
Initiate a socket client
on connection successfully, client sends a message
client receives back response from that message
client prints response to terminal
Note that TheSkyX has a limitation of 4096 bytes for each message[2], any more than that and we will need to chunk the message. So you may want to keep the js-code short and precise.
that snippet I gave is minimal, it doesn't handle errors from server. If you want, you can add client.on("error", .. ) to handle it.
Your point of connecting to the socket server directly from browser is very intriguing, unfortunately it is not allowed by modern browsers natively due to security concerns 3
[1] https://socket.io/docs/#What-Socket-IO-is-not:~:text=That%20is%20why%20a%20WebSocket%20client,to%20a%20plain%20WebSocket%20server%20either.
[2] https://www.bisque.com/wp-content/scripttheskyx/scriptOverSocket.html#MSearchField:~:text=set%20to%204096%20bytes

SMTP-server npm does not receive the mail data

I have been looking during hours for an answer to my question. I think this question (Send email to localhost smtp server in Node.js) is quite the same but the answer didn't help me.
So I have two VM's which run on Centos7. And I want my VM 1 to send an email to my VM 2. Here is what I have done :
VM 1 : Postfix is installed and configured with it : relayhost = [ip of vm 2]:25
VM 2 : The port 25 is opened. There is the code which listen in port 25 :
'use strict'
const fs = require('fs-extra')
const SMTPServer = require('smtp-server').SMTPServer
const simpleParser = require('mailparser').simpleParser
const date = require('date-and-time')
const builder = require('xmlbuilder') //9.0.4
const say = msg => {
console.log(msg)
}
const server = new SMTPServer({
logger: true,
//secure: true,
//authOptional: true,
//disabledCommands: ['AUTH'],
disabledCommands: ['AUTH', 'STARTTLS'],
// By default only PLAIN and LOGIN are enabled
authMethods: ['PLAIN', 'LOGIN', 'CRAM-MD5'],
onConnect: function(session, callback){
say('hello')
callback()
},
onData: function(stream, session, callback) {
say('received');
callback()
},
})
server.on('error', err => {
say('Error %s', err.message)
})
server.listen(25)
From VM 2 : When I send a mail to locahost with sendmail :
sendmail ldecaudin#localhost < email.txt
, I can see the "hello" and the "received"
From VM 1 : When I send a mail with sendmail (which is automatically relayed by postfix to my VM2) using it :
sendmail ldecaudin#[192.168.56.101] < email.txt
I can only see the "hello", so the connection is running, but I am not able to pass in the "onData" function to get the stream I need.
Also from my VM1, I have a node code which send mails using nodemailer, this code works. When I use this code, I have the same result ("hello" but not "received"), but there are 2 connections instead of one.
So I am totally lost, I tried to add the "onAuth" function, to try many options of "new SMTPServer".
I wonder if this is a problem with a port (but port 25 is open!), or maybe I forgot to put something on Postfix. I don't know.
Can you help me please ?
Thank you a lot by advance !
I might be late to answer but I faced a similar issue a couple of hours ago writing this answer. Answering in a hope that somebody will find it helpful in the future...
As per the SMTP standards, it sends mailform, rcptto commands before actually sending the body.. and hence, here in this nodeJs lib, the handler methods equivalent to those commands mailfrom -> onMailFrom(...) & rcptto -> onRcptTo(...) is getting called and ARE EXPECTED TO CALL callback() in order to send success signal on the connected SMTP socket.
In my case, I wrote an empty handler and was not calling the callback on onMailFrom & onRcptTo. This was creating the problem.
Calling the callbacks from the above handlers fixed it.
Code sample when I faced the issue:
.
.
.
onMailFrom: (address, session, callback) => {},
onRcptTo: (address, session, callback) => {},
.
.
Code sample when I called callback:
.
.
.
onMailFrom: (address, session, callback) => {
return callback();
},
onRcptTo: (address, session, callback) => {
return callback();
},
.
.
.
Adding a note: Do check on other handler functions as well, if this solution doesn't work. Debugging helped me here to identify the problem in my case.

get data from mqtt broker -6lbr

I followed this tutorial :
Running the CC26xx Contiki Examples
but instead of using the cc26xx-demo I used the cc26xx-web-demo and successfully manged to get everything up and running and I can access the 6lbr web page, when I access the sensorTag page I see a mqtt configuration page as shown:
and if I click index in the sensorTag page (pic above) I get to see the data:
the question is , how can I write a simple nodejs js file that uses the mqtt broker information to grab all the sensorTag sensors data and save it in an local object.
I tried to do run this example but no luck
var mqtt = require('mqtt')
client = mqtt.createClient(1883, '192.168.1.109');
client.subscribe(what do I write here);
client.on('message', function(topic, message) { console.log(message); });
I don't know what I'm doing wrong
UPDATE:
mqtt configuration page :
javascript file :
and I run the js with node and listen on port 1883:
tcpdump seems to detect mqqt packets on 1883 port but I can't to seem to be able to console.log the sensor data when I run the js file with node ??
I went on the contiki wiki and came across this info
"You can also subscribe to topics and receive commands, but this will only work if you use "Org ID" != 'quickstart'. Thus, if you provide a different Org ID (do not forget the auth token!), the device will subscribe to:
iot-2/cmd/+/fmt/json"
does this mean that the topic to subscribe to is quickstart but even if that's so, I used '+/#' which subrcibes to all topics and still got nothing printing on the console ?
Hope this works for you:
var mqtt = require('mqtt');
var fs = require('fs');
var options = { port: PORT, host: HOST };/*user, password and others authentication if there.*/
var client = mqtt.connect('HOST', options);
client.on('connect', function ()
{
client.subscribe("topic, command or data");
client.publish("topic, command or data", data, function () {
});
});
client.on('error', function () { });
client.on('offline', function () { });
client.on('message', function (topic, message) {
console.log(message.toString());
});

Categories

Resources