How do I send messages on a timer with websockets - node.js

I have the following node.js code
const WebSocket = require("ws");
const db = require('./db')
const wss = new WebSocket.Server({port: 5000});
wss.on("connection", ws => {
console.log("New Client Connected!");
ws.on("message", data => {
console.log(data);
let interval = setInterval(()=> getSelPos(ws), 2000);
});
ws.on("close", () => {
console.log("Client has Disconnected");
});
});
const getSelPos = async(ws) =>{
try {
const result = await db.pool.query("select value from db.tags where tag in ('1006', '1004', '1002')");
ws.send({selector: result[2].value.toString(), pressure: result[1].value.toString(), temperature: result[0].value.toString()});
console.log(result);
} catch (err) {
throw err;
}
}
My intention is to perform an initial handshake with my React code, then once a message is received from React (a confirmation of the connection opening), I start a 2 second interval to send database updates to my react component data. However this code currently doesn't work. I'm not sure how to fix it now. Any ideas?
EDIT: Here is my code on the other end for testing purposes currently:
const ws = new WebSocket("ws://localhost:5000");
ws.addEventListener("open", () => {
console.log("We are connected!");
ws.send("Hello!");
});
ws.addEventListener("message", ({data}) => {
console.log(data);
});
EDIT 2:
Console output I got was:
New Client Connected!
<Buffer 48 65 6c 6c 6f 21>
(node:16492) UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received an instance of Object
at Function.from (buffer.js:330:9)
at toBuffer (my-path\node_modules\ws\lib\buffer-util.js:95:18)
at Sender.send (my-path\node_modules\ws\lib\sender.js:270:17)
at WebSocket.send (my-path\node_modules\ws\lib\websocket.js:423:18)
at getSelPos (my-path\server.js:22:12)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:16492) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:16492) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Looking at the error, it seems like you are using the socket instance ws in your getSelPos function but the function doesn't have access to it. Pass the instance to the function when you call it and it should work:
wss.on("connection", ws => {
console.log("New Client Connected!");
ws.on("message", data => {
console.log(data);
let interval = setInterval(()=> getSelPos(ws), 2000);
});
// rest of the function
});
const getSelPos = async(ws) =>{
// Use socket instance
}

Related

Expected 'port' to be a 'number', got 'object', minecraft server status check error

i have this simple code in my discord bot to check mc server.
const Discord = require('discord.js')
const client = new Discord.Client()
const { MessageButton, MessageButtonStyles } = require('discord-buttons')
require('discord-buttons')(client)
const db = require('quick.db')
let mineutil = require('minecraft-server-util')
client.on('ready', () => {
console.log('Started!\n---')
client.user.setPresence({
status: 'online',
activity: {
type: 'LISTENING',
name: '!help'
}
})
})
client.on('message', async (message) => {
if (message.content == 'привет') {
message.reply('привет')
}
//more code
const SERVER_ADDRESS = 'adress'
const SERVER_PORT = 25565
const STATUS_ONLINE = '**Сервер включен** - '
const STATUS_PLAYERS = '**{online}** **человек(a) онлайн!**'
const STATUS_EMPTY = '**никто не играет**'
const cacheTime = 15 * 1000; // 15 sec cache time
let data, lastUpdated = 0;
function statusCommand(message) {
getStatus().then(data => {
let status = STATUS_ONLINE;
status += data.onlinePlayers ?
STATUS_PLAYERS.replace('{online}', data.onlinePlayers) : STATUS_EMPTY;
let statuspanel = new Discord.MessageEmbed()
.setColor('2ecc71')
.setDescription(status)
send(statuspanel)
}).catch(err => {
console.error(err)
let statuserror = new Discord.MessageEmbed()
.setColor('ff0000')
.setDescription('**Сервер выключен**')
send(statuserror)
})
}
function getStatus() {
if (Date.now() < lastUpdated + cacheTime) return Promise.resolve(data);
return mineutil.status(SERVER_ADDRESS, { port: SERVER_PORT })
.then(res => {
data = res;
lastUpdated = Date.now();
return data;
})
}
if (message.content == '!server') {
statusCommand(message)
}
})
client.login(TOKEN)
And it works in Visual studio, but i just placed it on Replit and it catches this error:
(node:172) UnhandledPromiseRejectionWarning: AssertionError [ERR_ASSERTION]: Expected 'port' to be a 'number', got 'object'
at Object.status (/home/runner/Makak-discord-bot/node_modules/minecraft-server-util/dist/status.js:23:26)
at getStatus (/home/runner/Makak-discord-bot/index.js:210:21)
at statusCommand (/home/runner/Makak-discord-bot/index.js:192:5)
at Client.<anonymous> (/home/runner/Makak-discord-bot/index.js:219:5)
at Client.emit (events.js:314:20)
at Client.EventEmitter.emit (domain.js:483:12)
at MessageCreateAction.handle (/home/runner/Makak-discord-bot/node_modules/discord.js/src/client/actions/MessageCreate.js:31:14)
at Object.module.exports [as MESSAGE_CREATE] (/home/runner/Makak-discord-bot/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_CREATE.js:4:32)
at WebSocketManager.handlePacket (/home/runner/Makak-discord-bot/node_modules/discord.js/src/client/websocket/WebSocketManager.js:384:31)
at WebSocketShard.onPacket (/home/runner/Makak-discord-bot/node_modules/discord.js/src/client/websocket/WebSocketShard.js:444:22)
(node:172) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:172) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
And if i change, for example { port: SERVER_PORT } to 25565, it always says that server is off, even if server online(
PS sorry for my english, and russian text in code
EDIT Just saw the question's last line about the server being reported as offline when using a number rather than an object. That actually confirms my suspicion below, as you're no longer getting an error from the SDK itself (ie, it seems to be "working," in that it's at least making the network call). I would double-check your address and port number, and ensure the server is accessible from replit.
--- Original response below ---
Difficult to say for sure without knowing the mineutil API you're using, but it looks like you may be sending more than you need to the mineutil.status() function (And if you're using this library, I'm fairly certain you are).
I'm guessing that the following line:
return mineutil.status(SERVER_ADDRESS, { port: SERVER_PORT })
which is sending an object `{port: SERVER_PORT}' as its second parameter, should just be sending the number itself. For example:
return mineutil.status(SERVER_ADDRESS, SERVER_PORT )
This is Replit server side error, it can not be repaired(

MongooseError: Query was already executed: User.countDocuments({})

(node:9540) UnhandledPromiseRejectionWarning: MongooseError: Query was already executed: User.countDocuments({})
at model.Query._wrappedThunk [as _countDocuments] (D:\Acadamic-LANGUAGE-PROJECTS\Angular-Projects\eShop-MEAN STACK\Back-End\node_modules\mongoose\lib\helpers\query\wrapThunk.js:21:19)
at D:\Acadamic-LANGUAGE-PROJECTS\Angular-Projects\eShop-MEAN STACK\Back-End\node_modules\kareem\index.js:370:33
at processTicksAndRejections (internal/process/task_queues.js:77:11)
(Use node --trace-warnings ... to show where the warning was created)
(node:9540) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node
process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:9540) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
this is my Code......
router.get(`/get/count`, async (req, res) =>{
const userCount = await User.countDocuments((count) => count)
if(!userCount) {
res.status(500).json({success: false})
}
res.send({
userCount: userCount
});
})
It seems that you are using Mongoose. It seems you are mixing between async-await and callbacks.
Change await User.countDocuments((count) => count) to
await User.countDocuments()
This is because countDocuments() is called using its callback (which passes its result to the callback), while on the other hand, it is also asked to pass its result to the userCount variable using the await command.
This is exactly what this error message is trying to say: hey, you're sending the same query to the database twice ! While, since since v6 of Mongoose, you can only get run query once - ie, either by adding the cbk argument, or using async-await block. Read about it here: https://mongoosejs.com/docs/migrating_to_6.html#duplicate-query-execution
Now let's move ahead to fixing the problem:
I don't completely understand what you're trying to do this in line:
const userCount = await User.countDocuments((count) => count)
I think what you're trying to do is just get the document count. If so, simply drop 'count => count'.
router.get(`/get/count`, async (req, res) =>{
const userCount = await User.countDocuments();
if(!userCount) {
res.status(500).json({success: false})
}
res.send({
userCount: userCount
});
})
If you were to add a filter to the count (which is what the countDocuments gets - a filter; see API here), then you should use the key:value pair form, ie {count: count}.
router.get(`/get/count`, async (req, res) =>{
/* let count; etc. */
const userCount = await User.countDocuments({count: count});
if(!userCount) {
res.status(500).json({success: false})
}
res.send({
userCount: userCount
});
})
Of course you should use a proper try-catch block when using await, to be able to handle the error if thrown.
(Just encountered this problem myself and made some research into it.)
module.exports.getUserCount = async(req,res)=>{
const numberOfUser = await User.countDocuments()
res.send({numberOfUser : numberOfUser});
}

Mongoose query not running - "cursor.toArray is not a function"

MongoDB beginner, having trouble getting queries to work. Was following a tutorial of sorts and it was a demo notes app. Their syntax for saving new notes works fine.
However when it comes to printing out the list of notes, there seems to be something wrong in the syntax given to me or something im doing wrong.
const mongoose = require("mongoose");
const url =
"mongodb+srv://Saif:<password>#cluster0.8d2lb.mongodb.net/notes-app?retryWrites=true&w=majority";
mongoose.connect(url, {
useNewUrlParser: true,
});
const noteSchema = new mongoose.Schema({
content: String,
date: Date,
important: Boolean,
});
const Note = mongoose.model("Note", noteSchema);
Note.find({}).then((result) => {
result.forEach((note) => {
console.log(note);
});
mongoose.connection.close();
});
After looking up documentation, the actual syntax of find is a little different where they pass in a callback instead of using promises. But changing that block to use a callback still doesnt work
Note.find({}, (error, data) => {
if (error) {
console.log(error);
} else {
data.forEach((note) => {
console.log(note);
})
}
mongoose.connection.close()
})
Error
TypeError: cursor.toArray is not a function
at model.Query.<anonymous> (D:\Folders\Documents\CS.........
(Use `node --trace-warnings ...` to show where the warning was created)
(node:27108) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:27108) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
.find method from model returns Query object not Cursor
For cursor you need to do .exec
Note.find({}).exec((error, data) => {
if (error) {
console.log(error);
} else {
data.forEach((note) => {
console.log(note);
})
}
mongoose.connection.close()
})

Unzipper stream "Bad password" issue in node js

I am extracting password protected zip in node js for this i am using unzipper node module. below is the code which i am using.
const unzipper = require('unzipper');
const fs = require('fs');
const path = require('path');
async function checkPasswordValid(zipFilePath, password) {
let directory = null;
try {
directory = await unzipper.Open.file(zipFilePath);
return new Promise((resolve, reject) => {
// console.log(directory.files[0].path)
directory.files[0].stream(password)
.on('error', (err) => {
console.log('I am heere too bro in error')
console.log(err.message);
})
.on("readable", () => {
console.log('I am heere too bro')
})
});
}
catch (err) {
console.log('I am heere too bro in error in catch')
console.log(err.message);
}
}
let zpath = 'D:/NodeJs/upload/zip/text.zip';
let exPath = 'D:/NodeJs/upload/extractFile/';
let pass = 'DEXTER';
checkPasswordValid(zpath, pass)
when i try to manually open zip with password it's works fine but when i am using same password with node module unzipper i am getting below error.
I am heere too bro in error
BAD_PASSWORD
(node:6100) UnhandledPromiseRejectionWarning: #<Object>
(node:6100) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:6100) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I don't know where i am doing wrong. Code looks perfect for me but not working. to made password protected zip i used winrar software on windows 10.
It appears that unzipper doesn't support all encryption methods. This issue has produced a feature request that has not been developed yet.

Try to cach UnhandledPromiseRejectionWarning discord.js

i'm trying to catch an discord.js error
This error pops up when internet is off, but i want some clean code instead this messy one...
How can i catch this?
I did really try everything..
code:
(node:11052) UnhandledPromiseRejectionWarning: Error: getaddrinfo ENOTFOUND disc
ordapp.com
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:66:26)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:11052) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This
error originated either by throwing inside of an async function without a catch
block, or by rejecting a promise which was not handled with .catch(). To termin
ate the node process on unhandled promise rejection, use the CLI flag `--unhandl
ed-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejecti
ons_mode). (rejection id: 2)
(node:11052) [DEP0018] DeprecationWarning: Unhandled promise rejections are depr
ecated. In the future, promise rejections that are not handled will terminate th
e Node.js process with a non-zero exit code.
i did try this at the very top :
process.on('uncaughtException', function (err) {
//console.log('### BIG ONE (%s)', err);
console.log("555")
});
aswell this one :
client.on('error', error => {
if (error.code === 'ENOTFOUND') {
console.log(no internet!!)
}
});
I also did try this to see where its from, but nothing shows up its still the same
try {
var err = new Error("my error");
Error.stackTraceLimit = infinity;
throw err;
} catch(e) {
console.log("Error stack trace limit: ")
console.log(Error.stackTraceLimit);
}
Error stack trace limit:
10
(node:11008) UnhandledPromiseRejectionWarning: Error: getaddrinfo ENOTFOUND disc
ordapp.com
here is the code i use for now what gives the error.
i just want to catch the error in something like this: (No connection)
const Discord = require('discord.js')
const client = new Discord.Client({ autoReconnect: true });
const opn = require('opn')
const getJSON = require('get-json')
const request = require('request');
const config = require("./config/config.json");
const pushbullet = require("./config/pushbullet.json");
const addons = require("./config/addons.json");
const Registration = require("./config/Reg.json");
client.on('uncaughtException', function (err) {
//console.log('### BIG ONE (%s)', err);
console.log("555")
});
client.login(config.Settings[0].bot_secret_token);
I would try to wrap it with try/catch.
And maybe add the following code to understand better what is happening.
Error.stackTraceLimit = Infinity
Reference:
https://developer.mozilla.org/en-US/docs/Archive/Web/JavaScript/Microsoft_Extensions/Error.stackTraceLimit
Remember to remove it after the problem solved, this is not suitable for production use.
Well i solved it!!
I put this on top and its all solved.
process.on('unhandledRejection', error => {
if (error.code === "ENOTFOUND") { console.log ("No internet connection")}
if (error.code === "ECONNREFUSED") { console.log ("Connection refused")}
//console.log('Unhandled promise rejection:', error.code);
});

Resources