I am building an API that uses socket connection to interact with a server backend built in C#. This is what I have so far
const request = require('request');
const express = require('express');
const app = express();
var server = require('http').createServer(app);
var cors = require("cors");
app.use(cors());
const net = require('net');
const client = new net.Socket();
const stringToJson=require('./stringToJson')
const port = process.env.PORT;
const host = process.env.HOST;
client.keepAlive=true
client.on('close', function() {
console.log('Connection closed');
});
app.get('/getScores',function (req,res) {
let dataSend=''
client.on('data', function (data) {
console.log('Server Says : ' + data);
if(data!='ANALYSIS-ERROR'){
dataSend=stringToJson.stringToJson(data)
}
else{
dataSend=stringToJson.stringToJson('0:0.0:0.0:0.0:0:0:0.0:0.0:0.0:0.0:0.0:0:0.0:0.0:0.0:0.0:0.0:0:0.0:0.0:0.0:0.0:0.0:0:0.0:0.0:0.0:0.0:0.0')
}
client.destroy()
return res.send(dataSend)
});
client.connect(port, host, function () {
client.write(`GENERAL-ANALYSIS|${req.query.id}|${req.query.website}|`)
return
});
return
})
app.get('/getPlace',function (req,res) {
console.log(req.query)
request(
{ url: `https://maps.googleapis.com/maps/api/place/textsearch/json?query=${req.query.name}+in+${req.query.city}&key=${process.env.API_KEY}` },
(error, response, body) => {
if (error || response.statusCode !== 200) {
return res.status(500).json({ type: 'error', message: error.message });
}
return res.json(JSON.parse(body));
}
)
})
//TODO ADD 404 500 PAGES
app.use((req, res, next) => {
res.status(404).send("Sorry can't find that!");
});
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
server.listen(9000, () => {
console.log(`App running at http://localhost:9000`);
});
Basically it creates a connection with the server and listens for some data to be sent back. Then processes the string and sends it to the React frontend. The api calls are made by the frontend using axios
It works but if you refresh the page it throws this error Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
How do I fix this?
Try setting the headers as found in the documentation request.setHeader(name, value)
request.setHeader('Content-Type', 'application/json');
Related
I have tried using the following approach but when hosted the application . I'm getting the ip address that the application us hosted on.
Also I have used req.ip and req.socket.remoteAddress but it was returning the local host ip I.e ,::1
here is what I tried.
var express = require('express');
var request = require('request');
var app = express();
const IPData = require("ipdata").default;
require('dotenv').config();
const apiKey = process.env.API_KEY;
const ipdata = new IPData(apiKey);
app.get('/location', async (req, res) => {
try{
request.get('http://ipinfo.io/ip', (error, response, body) => {
if (!error && response.statusCode == 200) {
let clientIp = req.headers["x-forward-ip"] || body
console.log(body);
ipdata.lookup(clientIp)
.then((data) => {
console.log(data);
return res.json({
city: data.city,
region: data.region,
country: data.country_name,
postal: data.postal
});
})
.catch((error) => {
console.log(error);
res.status(500).send('Error looking up location');
});
}
});
}catch(error) {
console.log(error);
res.status(500).send('Error looking up location');
}
});
app.listen(8000, () => {
console.log('Server started on port 8000');
});
Try this:
const express = require("express");
const app = express();
const IpGeoLocation = require("ip-geolocation-api-javascript-sdk");
app.get("/", (req, res) => {
// Get client's IP address
const clientIp = req.connection.remoteAddress;
// Initialize IpGeoLocation with your API key
const apiKey = "YOUR_API_KEY";
const ipGeoLocation = new IpGeoLocation(apiKey);
// Get location information for the client's IP address
ipGeoLocation
.getGeoLocation(clientIp)
.then((location) => {
console.log(location);
res.send(location);
})
.catch((error) => {
console.error(error);
res.status(500).send(error);
});
});
app.listen(3000, () => {
console.log("Server listening on port 3000");
});
const ipGeoLocation = require("ip-geolocation-node");
const clientIp = req.connection.remoteAddress;
ipGeoLocation
.getGeoLocation(clientIp)
.then((location) => {
console.log(location);
})
.catch((error) => {
console.error(error);
});
My frontend service is running on netlify.
And backend is on heroku.
I am trying to make chatApp.
After I entered chatRoom press sending button below error message pop up on console log.
"Failed to execute 'send' on 'WebSocket': Still in CONNECTING state."
I guess
problem is below code.
client
created() {
this.channel = this.$route.query.channel || '';
this.$store.state.user.stateWebSocket = new WebSocket('ws://peaceful-ridge-59102.herokuapp.com:9999/ws');
// this.websocket = new SockJS('http://localhost:8080/ws/realtime');
this.websocket=this.$store.state.user.stateWebSocket;
this.websocket.onmessage = ({ data }) => {
const vo = JSON.parse(data);
if (vo.channel === this.channel) {
this.appendNewMessage(this.tempName, vo.message, vo.time);
}
};
this.websocket.onopen = (event) => {
console.log('open event..', event);
};
this.websocket.onerror = (event) => {
console.log('error', event);
};
this.websocket.onclose = (event) => {
console.log('close', event);
};
}
This is sever.js
const cors = require('cors');
const express = require('express');
const app = express();
const WebSocket = require('ws');
const PORT = 9999;
app.use(
cors({
origin: true,
credentials: true,
})
);
const server = app.listen(PORT, () => {
console.log(PORT, 'waiting unitil connects');
});
app.get('/', (req, res) => {
res.send('Hello World!');
});
const wss = new WebSocket.Server({ server, path: '/ws' });
wss.on('connection', (ws, req) => {
// connection
console.log('새로운 클라이언트 접속');
ws.on('message', (message) => {
// receiving message
const json = JSON.parse(message.toString());
json.time = Date.now()
message = JSON.stringify(json)
console.log(message.toString());
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(message.toString());
}
});
// Runs when client disconnects
wss.on('disconnect', () => {
});
});
ws.on('error', (err) => {
// error
console.error(err);
});
ws.on('close', () => {
// close
console.log('Client close');
clearInterval(ws.interval);
});
});
some people say I am sending your message before the WebSocket connection is established.
I am newbie on JS plz help me~!
I am using node.js package prom-client to try to push different custom metrics to the Prometheus Pushgateway server.
The code is working and now I am writing the test code for the functionality. I wonder whether there is a way to mock the Prometheus Pushgateway server?
I had tried to use a normal express API server (like the following)
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
let data = null;
// ROUTES FOR OUR API
// =============================================================================
const router = express.Router();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
router.get('/', (req, res) => {
console.log("pushgateway server: get to '/' received");
res.json(data);
});
router.post('/', (req, res) => {
console.log("pushgateway server: post to '/' received");
console.log(req.body);
data = req.body;
res.send('POST request to the homepage');
})
app.use(router);
// API JSON BASED ERRORS
// =============================================================================
app.use((err, req, res, next) => {
if (req.xhr) {
console.error(err);
res.status(500).send({ err: 'Something failed!' });
} else {
next(err);
}
});
app.use((err, req, res, next) => { // eslint-disable-line
console.error(err);
res.status(500).send({ err: err.message });
});
// START THE SERVER
// =============================================================================
const port = 9876;
const server = app.listen(port, '0.0.0.0');
console.log(`Prometheus Pushgateway Mock Server is listening on port ${port}`);
// SHUTDOWN HANDLING
// =============================================================================
// Nodemon Signal Handling
process.once('SIGUSR2', () => {
console.log('Received kill signal, attempting gracefully close');
server.close(() => {
console.log('Closed out remaining connections');
process.kill(process.pid, 'SIGUSR2');
});
setTimeout(() => {
console.error('Timeout, forcefully shutting down');
process.kill(process.pid, 'SIGUSR2');
}, 3000);
});
module.exports = server;
but it did not work -- when I call gateway.pushAdd() on my test code, the server did not receive any post message.
Can anyone give me some hints on how to do this (mock the prometheus pushgateway server)?
There are different options out there to mock a third party http server. Here are 3:
Nock
Dyson
Stubborn
Disclaimer: I am the maintainer behind stubborn.
Nock and Dyson are the most popular ones, they have pro and cons. Stubborn is more recent and tries to cover some limitations of Nock and Dyson.
You can checkout this reddit post first comment I wrote for a comparison between the 3 solutions.
So I have solved the problem by creating a simple http server.
The following is the code of the server:
const http = require('http');
const body = [];
let text = null;
let path = null;
function createServer(port) {
return http.createServer()
.on('request', (req, res) => {
if (req.method === 'POST' || req.method === 'PUT') {
path = req.url;
req.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
text = Buffer.concat(body).toString();
res.end(`${req.method} success`);
}).on('error', (err) => {
console.error(err);
});
} else if (req.method === 'GET') {
res.end(JSON.stringify({ path, text }));
} else if (req.method === 'DELETE') {
path = null;
text = null;
res.end('DELETE success');
}
}).on('error', (err) => {
console.log(`Server error: ${err}`);
})
.listen(port, '0.0.0.0');
}
module.exports = (createServer);
The server accepts POST/PUT/DELETE/GET requests, to handle the pushAdd()/push()/delete() functions of the gateway to handle the metric data, as well as checking the push data on the mocked pushgateway.
Also, the request.url and the text data pushed to the server are saved and passed to the test program for verification.
The following is one of the test cases (using Mocha+Chai):
describe('Check adding custom push count metric', () => {
it('Check connection: should return - network status: 200, result contains custom count metric string', async () => {
metricInstance = promMetric.createCustomPushMetric({
name: 'test_counter',
help: 'Used to test the pushgateway for custom counter metrics',
type: 'counter',
jobName: 'custom-metric-pushgateway-counter',
groupings: { key: 'test', type: 'customMetric' },
});
await promMetric.addPushMetric(metricInstance, 0.879);
await sleep(500);
const result = await chai.request(mockPgwServer).get('/');
expect(result).to.have.status(200);
const json = JSON.parse(result.text);
expect(json.path).to.equal('/metrics/job/custom-metric-pushgateway-counter/key/test/type/customMetric');
expect(json.text).to.match(/# HELP Push_gateway_test_test_counter Used to test the pushgateway for custom counter metrics/);
expect(json.text).to.match(/# TYPE Push_gateway_test_test_counter counter/);
expect(json.text).to.match(/Push_gateway_test_test_counter 0.879/);
});
});
The "path" and "text" stored in the server when the metric is posted from the client are sent back to the client when queried and verified.
So I'm trying to create a node app that calls an ldap serve and to authenticate users. In the code below, the app successfully connects to the server and processes the request. But when I try to send a response back, I get this error:
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
I'm not really sure why this is occurring. I'm pretty new to node, express, and ldap
// ldapjs required for ldap connection
const ldap = require('ldapjs');
//express required for exposing endpoints
const express = require('express');
const app = express();
const assert = require('assert');
var client = ldap.createClient({
url: 'ldap://someserve.com'
});
//Search filter for users in the directory
var opts = {
filter: '(&(objectCategory=person)(objectClass=user))',
scope: 'sub',
};
//General Ldap serch user
var UserName = '123.test.com';
var Pass = '123longpass'
//Base URL
app.get('/', (req,res) => {
res.send('hello from node')
});
//Get all ldap users
app.get('/api/ldapUsers', (req, res) =>
{
client.bind(UserName, Pass, function (err)
{
client.search('DC=sdf,DC=sdfa,DC=gdfgd', opts, function (err, search)
{
search.on('searchEntry', function (entry)
{
res.setHeader('Content-Type', 'application/json');
var users = entry.object;
console.log(users);
res.json(users);
res.end();
});
});
});
// client.unbind( err => {
// assert.ifError(err);
// });
});
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listening on port ${port}...`));
searchEntry event is called once for each found item which means you are calling res.json multiple times.
Try this:
app.get('/api/ldapUsers', (req, res) =>
{
client.bind(UserName, Pass, function (err)
{
client.search('DC=sdf,DC=sdfa,DC=gdfgd', opts, function (err, search)
{
var users = [];
search.on('searchEntry', function (entry) {
users.push(entry.object);
});
search.on('end', function (entry) {
res.setHeader('Content-Type', 'application/json');
console.log(users);
res.json(users);
res.end();
});
});
});
});
below node.js code is using express to route to different urls, how can I do the same with http instead of express?
var express = require('express');
var app = express();
app.use(express.static('public'));
app.get('/', function (req, res) {
res.send('Welcome Home');
});
app.get('/tcs', function (req, res) {
res.send('HI RCSer');
});
// Handle 404 - Keep this as a last route
app.use(function(req, res, next) {
res.status(404);
res.send('404: File Not Found');
});
app.listen(8080, function () {
console.log('Example app listening on port 8080!');
});
Here's a quick example. Obviously, there are many ways of doing this, and this is probably not the most scalable and efficient way, but it will hopefully give you an idea.
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res) => {
req.on('error', err => {
console.error(err);
// Handle error...
res.statusCode = 400;
res.end('400: Bad Request');
return;
});
res.on('error', err => {
console.error(err);
// Handle error...
});
fs.readFile('./public' + req.url, (err, data) => {
if (err) {
if (req.url === '/' && req.method === 'GET') {
res.end('Welcome Home');
} else if (req.url === '/tcs' && req.method === 'GET') {
res.end('HI RCSer');
} else {
res.statusCode = 404;
res.end('404: File Not Found');
}
} else {
// NOTE: The file name could be parsed to determine the
// appropriate data type to return. This is just a quick
// example.
res.setHeader('Content-Type', 'application/octet-stream');
res.end(data);
}
});
});
server.listen(8080, () => {
console.log('Example app listening on port 8080!');
});
Try the code below . It is a pretty basic example
var http = require('http');
//create a server object:
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'}); // http header
var url = req.url;
if(url ==='/about'){
res.write('<h1>about us page<h1>'); //write a response
res.end(); //end the response
}else if(url ==='/contact'){
res.write('<h1>contact us page<h1>'); //write a response
res.end(); //end the response
}else{
res.write('<h1>Hello World!<h1>'); //write a response
res.end(); //end the response
}
}).listen(3000, function(){
console.log("server start at port 3000"); //the server object listens on port 3000
});
express can also be used by http directly.
From: https://expressjs.com/en/4x/api.html#app.listen
The app returned by express() is in fact a JavaScript Function, designed to be passed to Node’s HTTP servers as a callback to handle requests.
var http = require('http')
var express = require('express')
var app = express()
http.createServer(app).listen(80)
With this, you can still make use of express for routing, while keeping native http support.