Express routes not called with node-fetch - node.js

I have an express server with one route. When I call this route in my browser I am able to get data sent by my server. However when I try to call this route from script with a simple node-fetch I have an response but my route is not called (not data retrieved). I explain :
Here the code of my express server:
App.ts
import express from "express";
import httpServer from "./httpServer";
import HttpRoutes from "./httpRoutes";
class BrokerServer {
public httpServer!: express.Application;
public httpRoutes!: HttpRoutes;
constructor() {
this.initHttpServer();
}
private initHttpServer(): void {
this.httpServer = httpServer;
this.httpRoutes = new HttpRoutes();
this.httpRoutes.routes();
}
}
new BrokerServer();
Server.ts
import express from "express";
import * as bodyParser from "body-parser";
class HttpServer {
public HTTP_PORT: number = 9000;
public server!: express.Application;
constructor() {
this.server = express();
this.server.use(bodyParser.json());
this.server.listen(this.HTTP_PORT, () => {
console.log('Broker HTTP Server listening on port 9000');
});
}
}
export default new HttpServer().server;
And my routes.ts
import httpServer from "./httpServer";
export default class HttpRoutes {
public routes(): void {
httpServer.get("/getNodes", (req, res) => {
console.log("GET");
res.status(200).send(JSON.stringify({ nodes: [] }));
});
}
}
When I launch my server and naviguate on the url http://localhost:9000/getNodes I can see my console.log('GET'). this is not the case when I try with node-fetch.
Here my little script:
const fetch = require('node-fetch');
console.log('launch fetch');
fetch('http://localhost:9000/getNodes')
.then(response => {
console.log('response', response);
return response.json()
})
.then(results => {
console.log('results', results);
})
.catch(error => {
console.log('error', error);
});
With the script I reach the console.log('response', response); but never my results.
Anyone knows where is the problem ?

I found why it didn't work. I used a ramdom port (port 9000) which is already used. Changed the port works...

Related

socket.io wont connect after reload when communicating with react socket.io-client

I am trying to create simple socket.io server/client
this error appears to happen when I send http request to the server
First I created html file to act as client and everything was working fine
When I started using Socket inside my React app server went nuts !
First time I start the server everything is fine and socket is working
but when I refresh the page I can't connect to server from anywhere anymore
Server code ...
const express = require('express');
class Server {
constructor({ config, router, logger }) {
this.config = config;
this.logger = logger;
this.express = express();
this.express.disable('x-powered-by');
this.express.use(router);
}
startSocket(server) {
console.log('initing');
const io = require('socket.io')(server, {
cors: {
origin: '*',
methods: ['GET', 'POST'],
},
});
io.on('connection', (socket) => {
console.log('connected ' + socket.id);
});
}
start() {
return new Promise((resolve) => {
const http = this.express.listen(this.config.web.port || 6066, () => {
const { port } = http.address();
this.logger.info(`[p ${process.pid}] Listening at port ${port}`);
resolve();
});
this.startSocket(http);
});
}
}
module.exports = Server;
React code
import { io } from 'socket.io-client';
export class Socket {
constructor() {
this.socket = io('http://localhost:4000', {
rejectUnauthorized: false,
});
this.binds();
}
binds() {
this.socket.on('connect', () => {
console.log(this.socket.id);
});
this.socket.on('bong', (msg) => {
console.log(msg);
});
}
bing() {
this.socket.emit('bing', { msg: 'test' });
}
}
export default new Socket();
turns out 'socket.io' conflicts with 'express-status-monitor' which caused this problem

Problems connecting to my NodeJs server socket and typescript

I've tried everything and I can't afford to waste any more time please need help, I've been trying to run the code in this post:https://medium.com/#mogold/nodejs-socket-io-express-multiple-modules-13f9f7daed4c,I've been trying to run the code in this post, I liked it a lot because as I see it fits very well with big projects, the problem arises when I want to connect to it, throws the following errors at me: console: I already try setting up the headers of my application and I've tried codes that I read from similar problems but none ah worked, I leave you the condigo of my server.ts, socket.ts, job.ts and routes.ts, I hope you can help me please :c
server.ts
import express from "express";
const http = require("http");
import { router} from './routes/routes';
import bodyParser from "body-parser";
import morgan from "morgan";
import { PORT} from "./core/utils/config"
import errorMiddleware from './core/middleware/error.middleware';
import socket from "./socket";
const app = express();
const server = http.createServer(app);
app.use(bodyParser.json());
app.use(router);
app.use(morgan("dev"));
app.use(errorMiddleware);
app.listen(3000, ()=> console.log("[SERVER] list is running in port http://localhost:"+PORT));
socket.connect(server);
socket.ts
let connection: any = null;
export class Socket {
socket: any;
constructor() {
this.socket = null;
}
connect(server: any) {
const io = require("socket.io").listen(server);
io.on("connection", (socket: any) => {
this.socket = socket;
});
}
emit(event: any, data: any) {
this.socket.emit(event, data);
}
static init(server: any) {
if (!connection) {
connection = new Socket();
connection.connect(server);
}
}
static getConnection() {
if (connection) {
return connection;
}
}
}
export default {
connect: Socket.init,
connection: Socket.getConnection
}
job.ts
import socket from "../../../socket";
export class JobSockets {
emitUpdate() {
const connection = socket.connection();
if (connection) {
connection.emit("jobs", {
hola: "hola desde mi backend"
});
}
}
}
routes.ts
import express from "express";
import indexAppointment from "../features/Appointment/routes/index";
import indexUser from "../features/User/routes/index";
import cors from "cors";
const router = express.Router();
const options: cors.CorsOptions = {
allowedHeaders: [
'Origin',
'X-Requested-With',
'Content-Type',
'Accept',
'X-Access-Token',
],
credentials: true,
methods: 'GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE',
origin: "*",
preflightContinue: false,
};
router.use(cors(options));
router.options('*', cors(options));
router.use(indexAppointment);
router.use(indexUser);
export {
router
};
client index.html
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
</head>
<body>
<p>Check the console to see the messages coming through</p>
<script>
let socket;
window.onload = () => {
socket = io.connect("http://192.168.1.7:3000");
socket.on("jobs", (msg) => {
console.log(msg)
})
};
</script>
</body>
</html>
import indexAppointment from "../features/Appointment/routes/index";
import expres from "express"
import getAppointment from "./getAppointment/getAppointment";
import createAppoinment from "./createAppointment/create_appointment";
import updateAppoinment from "./updateAppointment/update_appointment";
import deleteAppoinment from "./deleteAppointment/delete_appointment";
const router = expres.Router();
router.use("/appointment",getAppointment);
router.use("/appointment",createAppoinment);
router.use("/appointment",updateAppoinment);
router.use("/appointment",deleteAppoinment);
export default router;
import indexUser from "../features/User/routes/index";
import expres from "express"
import createUser from "./createUser/create_user";
import deleteUser from "./deleteUser/delete_user";
import updateUser from "./updateUser/update_user";
import getUsers from "./getUser/get_user";
import createUserInfoAppointment from "./createUserInfoAppointment/create_user_info_appointment";
import getUserInfoAppointments from "./getuserinfoappointment/get_user_info_appointment";
const router = expres.Router();
router.use("/user",createUser);
router.use("/user",deleteUser);
router.use("/user",updateUser);
router.use("/user",getUsers);
//managment use case
router.use("/user",createUserInfoAppointment);
router.use("/user",getUserInfoAppointments);
export default router;
By default front end socket.io will connect to path /socket.io at the url provided. In your case it is localhost:3000. It doesn't seem like you have any routes re-defining this endpoint which is good.
The issue appears to be how the server is being started. You want http to be the listener here rather than the express app. So do the following,
Remove this part
app.listen(3000, ()=> console.log("[SERVER] list is running in port http://localhost:"+PORT));
And add this instead
app.set( "ipaddr", "127.0.0.1" ); --> May be omitted since you're using a different ip. This way it lets app use the ip that it finds. So try it without first and see if that works. If not, then change to your ip.
app.set( "port", 3000 );
server.listen(3000, () => {
console.log('server is running on port', server.address().port);
});

Error handling with Typescript and Express in Node.js

I'm starting with Node and Typescript and I have a question.
I have these 2 files.
server.ts
import express = require('express');
import IConfiguration from "../config/config";
export default class Server {
public app: express.Application;
public configuration: IConfiguration;
constructor( configuration: IConfiguration ) {
this.configuration = configuration;
this.app = express();
}
static init(configuration: IConfiguration) {
return new Server(configuration);
}
start(callback: Function) {
this.app.listen(this.configuration.port, callback());
this.app.use(express.static(this.configuration.public_path))
}
}
index.ts
import Server from './server/server';
import Configuration from "./config/config";
import * as dotenv from 'dotenv';
import router from './router/router';
//Loading .env file
dotenv.config();
//Init config
const configuration = Configuration.init();
//Init server
const server = Server.init(configuration);
server.app.use(router);
server.start(() => {
console.log('Server running at port ' + configuration.port);
});
In index.ts I have the app.listen callback on start function, but I dont know how write this error handling for capture the errors.
How I can add this .on("error") on my callback function?
server.start(() => {
console.log('Listening on port: ', port);
}).on('error', (e) => {
console.log('Error happened: ', e.message)
});
I have tried put this in my index.ts but I get this error:
"Property 'on' does not exist on type 'void'"
Your server variable is an instance of your Server class and when you call start it does not return anything, it just implicitly returns undefined (or void in Typescript terms) and undefined surely does not have on method, so you cannot chain it like that. This is what error message says, basically.
What you can do is return this.app from start method, for example.
start(callback: Function) {
this.app.listen(this.configuration.port, callback());
this.app.use(express.static(this.configuration.public_path))
return this.app;
}
Or separate this two line like this:
server.start(() => {
console.log('Listening on port: ', port);
});
server.app.on('error', (e) => {
console.log('Error happened: ', e.message)
});
you cannot pass "err" to app.listen in express. I think you guys are confusing with http server:
const http = require('http');
const server = http.createServer(app);
server.on('error', (err) => {
if (err) {
console.log(err);
}
});
server.listen(PORT, () => {
console.log('Running')
});

Node.js Rest Api and Socket.io and typescript

I would like to do a hybrid rest api with some socket event.
For my app I use Express and socket io.
This is my code :
index.ts
import {App} from "./app";
async function main() {
const app = new App(3000);
await app.listen();
}
main();
app.ts
import express, {Application} from 'express';
import { createServer, Server } from 'http';
import sio from 'socket.io';
import morgan from 'morgan';
import bodyParser from 'body-parser';
import { genericError,erroHandler } from "./routes/errorHandler.routes";
//Middleware
import {corsManager} from "./middlewares/cors-manager.middleware";
export class App {
public static readonly PORT:number = 3000;
private app:Application;
private _server:Server;
private io:any;
constructor(private port?: number | string){
this.createApp();
this.settings();
this.createServer();
this.sockets();
//this.middlewares();
//this.routes();
}
private createApp(): void {
this.app = express();
}
private createServer(): void {
this._server = createServer(this.app);
}
settings(){
this.app.set('port', this.port || process.env.PORT || App.PORT);
}
private sockets(): void {
this.io = sio(this._server);
}
middlewares(){
this.app.use(morgan('dev'));
this.app.use(bodyParser.urlencoded({extended:false}));
this.app.use(bodyParser.json());
//corse handler
this.app.use(corsManager)
}
routes(){
//error handler
this.app.use(genericError);
this.app.use(erroHandler);
}
async listen(){
this._server=await this._server.listen(this.app.get('port'),()=>{
console.log('Server on port %s', this.app.get('port'));
});
this.io.on('connect', (socket: any) => {
console.log('Connected client on port %s.', this.port);
socket.on('disconnect', () => {
console.log('Client disconnected');
});
});
}
get server(): Server {
return this._server;
}
}
The server start on port 3000 and works fine but when I try to connect to it with a socket client, i use "smart websocket client" it's a chrome extension at following url:
ws://localhost:3000/
I retrieve this error:
WebSocket connection to 'ws://localhost:3000/' failed: Connection closed before receiving a handshake response
Please can you help me
Sorry for my English

data sent from socket.io client unavailable at server socket to emit even tho emit event is registering

I am running a node server on port 3000 and an angular app on port 4200. I am attempting to send data through web sockets from the client to the server for the server. Sending data from the server to the client through web sockets is working. The screenshot shows my angular CLI info on the node server next to a browser sending messages to the server.
The browser logs the information being sent to the server(chat.service.ts:22). I join this array so that a string is sent to simplify things.(chat.service.ts:23)
The server receives socket.on('new-message') from the client, then logs the data received. Unfortunately it's an empty string, noted by the blank space created by console.log(data). The word "string" comes from console.log(typeof(data))
I included the websocket.service.ts file but I'm not actually sure if it's relevant or if I'm even using it. I am new to websockets and services in angular, and angular over all, so I'm still trying to wrap my head around how services work in angular.
Cheers,
[Image showing node server at localhost:3000 as well as client-side console outputimage
server.js:
const express = require('express');
const bodyParser = require('body-parser');
const http = require('http');
let socket = require('socket.io’);
// Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
const app = express();
const server = http.createServer(app);
let io = socket(server);
//Set Port
const port = process.env.PORT || '3000';
app.set('port', port);
io.on('connection', function(socket){
console.log('made socket connection', socket.id);
socket.on('new-message', function(data) {
console.log(data);
io.sockets.emit('new-message', data);
console.log(typeof(data));
});
});
websocket.service.ts:
import { Injectable } from '#angular/core';
import * as io from 'socket.io-client';
import { Observable } from 'rxjs/Observable';
import * as Rx from 'rxjs/Rx';
import { environment } from '../environments/environment';
#Injectable()
export class WebsocketService {
// Our socket connection
private socket;
constructor() { }
connect(): Rx.Subject<MessageEvent> {
this.socket = io(localhost:3000);
let observable = new Observable(observer => {
this.socket.on('new-message', function(data){
console.log("Received message from Websocket Server")
observer.next(data);
})
return () => {
this.socket.disconnect();
}
});
// We define our Observer which will listen to messages
let observer = {
next: (data: Object) => {
this.socket.emit('message', JSON.stringify(data));
},
};
return Rx.Subject.create(observer, observable);
}
}
chat.service.ts:
import * as io from 'socket.io-client';
import { Observable } from 'rxjs/Observable';
import { Injectable } from '#angular/core';
import { Http, Headers, RequestOptions } from '#angular/http';
import { map } from "rxjs/operators";
#Injectable({
providedIn: 'root'
})
export class ChatService {
private url = 'http://localhost:3000';
private socket;
result:any;
constructor(private _http: Http) {
this.socket = io(this.url);
}
public sendMessage(messageArray) {
console.log('message array is now:')
console.log(messageArray);
this.socket.emit('new-message', messageArray.join('-'));
}
public loadPreviousMessages() {
return this._http.get("http://localhost:3000/api/messages")
.pipe(map(result => this.result = result.json().data));
}
public getMessages = () => {
return Observable.create((observer) => {
this.socket.on('new-message', (messageArray) => {
observer.next(messageArray);
});
});
}
}

Resources