Okay. I set up a socket.io system to get this error:
GET http://localhost:500/socket.io?EIO=4&transport=polling&t=<somevalue> 404 NOT FOUND
My client looks like this:
<script>
const socket = io()
</script>
And my server looks like this:
const server = require("http").createServer();
const app = express();
app.use("/", express.static("dist"));
const io = require("socket.io")(server);
io.sockets.on("connection", (socket) => {
console.log("new socket connection");
});
dist/index.html contains the script from earlier.
I tried various solutions, but they are not working :/
Does someone know why?
Use the app to create your http server:
const app = express();
const server = require("http").createServer(app);
app.use("/", express.static("dist"));
const io = require("socket.io")(server);
io.on("connection", (socket) => {
console.log("new socket connection");
});
Related
Started working on a new application and decided to write tests from very early stage to avoid any future mistakes. However, little bit struggling I guess with setting up the Jest correctly. I made a follow on few tutorials and documentation, but the result is not the one I'm expecting. What I am trying to do is to make a basic test for creating a user, however I receive and error:
error: Error: cannot POST /register (404)
I get the point that the test can't find the endpoint /register, but I thought that is the point to keep server.js and app.js for supertest, because he will be smart enough to understand the path to this endpoint, which actually is: "/api/v1/auth/register". I want to mark that the registration process works fine trough postman.
Here is the app.js:
require("dotenv").config();
require("express-async-errors");
const express = require("express");
const app = express();
// routers
const authRouter = require("./src/routes/auth/auth.router");
// packages
const morgan = require("morgan");
const fs = require("fs");
const cookieParser = require("cookie-parser");
// middlewares
const errorMiddleware = require("./src/middlewares/errorMiddleware");
app.use(express.json());
app.use(cookieParser(process.env.ACCESS_TOKEN));
app.use(morgan("common", {
stream: fs.createWriteStream("./src/utils/logs/logs.log", {
flags: "a"
})
}));
// endpoints
app.use("/api/v1/auth", authRouter);
app.use(errorMiddleware);
module.exports = app;
Here is the server.js:
const app = require("./app");
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}...`);
});
Here is the auth.test.js:
const request = require("supertest");
const app = require("../../../app");
describe("POST /register", () => {
it("Should create a new user", async () => {
const response = await request(app).post("/register").send({
email: "superemail#gmail.com",
username: "superusername",
password: "superpassword"
});
console.log(response); // I see here the 404 error.
});
});
Not sure if it helps, but here is the router file:
const express = require("express");
const router = express.Router();
const {check} = require("express-validator");
const {registerUserController, loginUserController} = require("../../controllers/auth/auth.controller");
router.post("/register", [
check("email").trim().not().isEmpty().isEmail(),
check("username").trim().not().isEmpty().isString(),
check("password").trim().not().isEmpty().isString().isLength({
min: 6
}).withMessage("Password has to be at least 6 characters long"),
check("firstName").optional().trim().not().isEmpty().isString(),
check("lastName").optional().trim().not().isEmpty().isString(),
check("age").optional().trim().not().isEmpty().isNumeric().isInt({
min: 0
}).withMessage("Age can't be less than 0"),
], registerUserController);
module.exports = router;
I'm building an app with you can pay by scanning a QR code with some points.
I'm trying to open web socket with socket io :
In my client (RN app)
import io from "socket.io-client";
//Inside my component vvv
const socket = io(url)
socket.on("connect_error", (err) => {
console.log(err.message)
});
On My server :
const app = express()
const http = require('http').Server(app);
const io = require('socket.io')(http);
/**
* Socket io
*/
io.on('connection',(socket)=>{
console.log('new connection')
})
This code log me an error on my client console:
xhr poll error
I tried every solutions I found on the internet but I'm not able to fix this error.
I also try with url ="localhost" & with url="myIP" but it does not work.
Edit : After 2 days, I resolved my problem !
On my server, I was listening on my app but I had to listen on my server :
I replaced :
app.listen(4000, () => {
console.log('listening on 4000')
})
by
server.listen(4000, () => {
console.log('listening on 4000')
})
where
const server = http.createServer(app);
And now it's working well... What a mistake...
Im doing a mern tutorial on freecodecamp and I have run into an issue that is driving me nuts.
I have a route which is localhost:5000/exercises/1234
however I keep getting a 404 on that route.
If someone could point out the error if would be appreciated.
I have a server file:
const express = require("express");
const cors = require("cors");
const mongoose = require("mongoose");
const exerciseRouter = require("./routes/exercises");
const usersRouter = require("./routes/users");
require("dotenv").config();
const app = express();
const port = process.env.PORT || 5000;
const uri = process.env.ATLAS_URI;
mongoose.connect(uri, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
});
const connection = mongoose.connection;
connection.once("open", () => {
console.log("Mongo DB database connection established successfully πΎπΎπΎ");
});
app.use(cors());
app.use(express.json());
app.use("/exercises", exerciseRouter);
app.use("/users", usersRouter);
app.listen(port, () => {
console.log(`server is running on port ${port} π»`);
});
and the route is defined here in an exercise.js file:
const router = require("express").Router();
const Exercise = require("../models/exercise.model");
router.route("/:id").get((req, res) => {
console.log(req.params);
Exercise.findById(req.params.id)
.then((exercise) => res.json(exercise))
.catch((err) => res.status(400).json(`Error ${req.params}`));
});
When i run this in the browser I get a 404 and not even the console log is run. Im really not sure why it isnt working.
Ah disregard this issue, i did an idiotic mistake. I had the method get inside another method (which isnt apparent in the above question).
Note to myself and others make sure your route aren't nested by accident in another route! lol
res.sendFile is not a function.
The following is my server js code
var app = require('express')();
var http = require('http').Server(app);
var fs = require('fs');
var io = require("socket.io")(http);
var users = {};
app.get('/', function(req, res) {
res.sendFile(__dirname + '/client.html');
});
app.listen(3000)
io.on("connection", function (client) {
client.on("join", function (name) {
users[client.id] = name;
client.emit("update", "Connected to Server");
socket.sockets.emit("update", name + " has entered the confession room");
socket.sockets.emit("update-users", users);
});
client.on("send", function (msg) {
socket.sockets.emit("chat", users[client.id], msg);
});
client.on("disconnect", function () {
socket.sockets.emit("update", users[client.id] + " has left the confession room");
delete users[client.id];
socket.sockets.emit("update-users", users);
});
});
Things I have tried:
- Checking the order of the parameter.
- Installing express module.
You have duplicate servers with these two lines of code and you're passing the one to socket.io that you never start:
var http = require('http').Server(app); // one on port 80
app.listen(3000); // one on port 3000
Remove the first one, then modify your code as shown below. And, make sure you're connecting on port 3000 where the Express server and socket.io severs are.
Or, if you want the server and socket.io to be on port 80, then change to:
const server = app.listen(80);
So, you should end up with this:
const app = require('express')();
const fs = require('fs');
const users = {};
app.get('/', function(req, res) {
res.sendFile(__dirname + '/client.html');
});
const server = app.listen(3000);
const io = require("socket.io")(server);
// various socket.io code here
I'm trying to create a really simple node API using express.js 4 but I need a few 'realtime' events for which I added socket.io. I'm fairly new to both so I'm likely missing something basic but I can't find good docs/tuts on this.
In the express app (created with the express generator) I have something like this based on simple examples and project docs that I read. This works OK and from client apps, I can send/receive the socket events:
var express = require('express');
var path = require('path');
var logger = require('morgan');
var api = require('./routes/api');
var app = express();
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', api);
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
// error handlers omitted
module.exports = app;
but I want to use the sockets from my API routes (in the ./routes/api.js file that I 'require' above). For example, someone might use the API to PUT/POST a resource and I want that broadcast to connected socket.io clients.
I cannot see how to use the 'io' variable or organise the code currently in the io.sockets.on('connection' ... function inside express routes. Here's the ./routes/api.js file:
var express = require('express');
var router = express.Router();
var io = ???;
router.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
io.sockets.emit('update', foo); // how?
});
module.exports = router;
One option is to pass it in to req object.
app.js:
var express = require('express');
var path = require('path');
var logger = require('morgan');
var api = require('./routes/api');
var app = express();
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
// Make io accessible to our router
app.use(function(req,res,next){
req.io = io;
next();
});
app.use('/api', api);
// error handlers omitted
module.exports = app;
./routes/api.js:
var express = require('express');
var router = express.Router();
router.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
req.io.sockets.emit('update', foo);
});
module.exports = router;
I've modified your files a little bit, may you check if it works?
You can pass the io you've defined to your routes like below;
require('./routes/api')(app,io);
I didn't test the Socket.IO parts but there is no syntax error and routes also working.
server.js file:
var express = require('express');
var app = express();
var path = require('path');
var logger = require('morgan');
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
require('./routes/api')(app,io);
console.log("Server listening at port 3000");
api.js:
module.exports = function(app,io) {
app.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
console.log("PUT OK!");
io.sockets.emit('update'); // how?
res.json({result: "update sent over IO"});
});
}
Supposing you want to access the SocketIO from anywhere in your application, not just in the router, you could create a singleton for it. This is what works for me:
//socket-singletion.js
var socket = require('socket.io');
var SocketSingleton = (function() {
this.io = null;
this.configure = function(server) {
this.io = socket(server);
}
return this;
})();
module.exports = SocketSingleton;
Then, you need to configure it using your server:
//server config file
var SocketSingleton = require('./socket-singleton');
var http = require('http');
var server = http.createServer(app);
SocketSingleton.configure(server); // <--here
server.listen('3000');
Finally, use it wherever you want:
//router/index.js
var express = require('express');
var router = express.Router();
var SocketSingleton = require('../socket-singleton');
/* GET home page. */
router.get('/', function(req, res, next) {
setTimeout(function(){
SocketSingleton.io.emit('news', {msg: 'success!'});
}, 3000);
res.render('index', { title: 'Express' });
});
module.exports = router;
One more option is to use req.app.
app.js
const express = require('express');
const path = require('path');
const logger = require('morgan');
const api = require('./routes/api');
const app = express();
const io = require('socket.io').listen(app.listen(3000));
// Keep the io instance
app.io = io;
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
// ...
app.use('/api', api);
module.exports = app;
routes/api.js
const express = require('express');
const router = express.Router();
router.put('/foo', function(req, res) {
/*
* API
*/
// Broadcast the updated foo..
req.app.io.sockets.emit('update', foo);
});
module.exports = router;
Refactored Edudjr's answer.
Change the singleton to create a new instance of socket.io server
const { Server } = require('socket.io');
const singleton = (() => {
this.configure = (server) => this.io = new Server(server)
return this
})();
module.exports = singleton
Initialise your express app, the server and the singleton.
// initialise app
const app = express();
const server = require('http').createServer(app);
// configure socket.io
socket.configure(server)
Then in your router
const socket = require('/utils/socket-singleton');
socket.io.emit('event', {message: 'your message here'})
I think best way is to set io as a property of req, like below:
app.use(function(req,res,next){
req.io = io;
next();
});
app.use('/your-sub-link', your-router);