socket.io connect issue - javascript

I keep getting this GET /socket.io/?EIO=3&transport=polling&t=MfRfeJD 404 4.438 ms - 149 error and I don't know where it's coming from.
I'm trying to integrate a live chat into my application using react, socket.io and express and I keep getting this not found error with the sockets. I'm not sure if the problem is on the client or server side. It appears to be trying to continuously poll the server, but is getting 404's back. That sounds like socket.io isn't running, but it all looks okay to me. It may also have something to do with paths, but I don't really know. I've tried adding different route to the io like "http://localhost:5000/" but still it still can't find the socket.
I get the page to show up and when I click send the message shows up but I can't get the sockets to connect.
In app.js
const express = require('express');
const http = require('http')
const bodyParser = require('body-parser')
const socketIo = require('socket.io')
var app = express();
const server = http.createServer(app)
const io = socketIo(server)
var PORT = process.env.PORT || 5000;
app.post('/', (req, res) => {
const { Body, From} = req.body
const message = {
body: Body,
from: From.slice(8),
}
io.emit('message', message)
res.send(`
<Response>
<Message>Thanks for texting!</Message>
</Response>
`)
})
io.on('connection', socket => {
socket.on('message', body => {
socket.broadcast.emit('message', {
body,
from: socket.id.slice(8)
})
})
})
server.listen(PORT);
In Chat.js
import React from "react";
import io from "socket.io-client";
class Chat extends React.Component {
constructor (props) {
super(props)
this.state = { messages: [] }
}
componentDidMount () {
this.socket = io('http://localhost:5000/')
this.socket.on('message', message => {
this.setState({ messages: [message, ...this.state.messages] })
})
}
handleSubmit = event => {
const body = event.target.value
if (event.keyCode === 13 && body) {
const message = {
body,
from: 'Me'
}
this.setState({ messages: [message, ...this.state.messages] })
this.socket.emit('message', body)
event.target.value = ''
}
}
render () {
const messages = this.state.messages.map((message, index) => {
return <li key={index}><b>{message.from}:</b>{message.body} </li>
})
return (
<div>
<h1>Admin Chat</h1>
<input type='text' placeholder='Enter a message...' onKeyUp={this.handleSubmit} />
{messages}
</div>
)
}
}
export default Chat;

404 is clearly saying no such page
149 will be the line number of the failure, your importing other code so it can be on any of the other code that the line 149 exists
i do see a maybe in app.js and the path
"app.post('/', (req, res) => {" Refers to an absolute path
try changing "http://localhost:5000/"
to "http://localhost:5000" or "http://localhost/:5000"
it looks like the "/" on the end puts the 5000 in the path not the port
--- EDIT --- on closer look at GET /socket.io/?EIO=3&transport=polling&t=MfRfeJD
if chat.js is running on the client and connecting to http://localhost:5000 than;
http://localhost/socket.io/?EIO=3&transport=polling&t=MfRfeJD would be the attempted connection
it looks like client is trying to connect back to itself.
how do you have the client / server setup?
if they are separate machines this would be looking for a non existing url.
either way is happening in the socket.io library.

Related

How to make React/Socket.IO app reachable from outside

I'm struggling to make my app (React + Node.js + Socket.IO) running in local, reachable from outside.
I expose my 3000 port via tunneling (ngrok) but my socket connection listens on 3001.
After having my port exposed port I obtain a Url, which used from another pc not on my network, makes my React App reachable but without the socket functionalities.
If I try to make socket listening on 3000 the whole app stops working on local aswell.
I'm new on this so I puzzles me how to make it work
The final goal is to host the React App from my PC, using it to chat via browser from the same PC with another one not on the same network.
I just want to make it work from my pc, so no external hosting from third parts.
Any idea?
Index.js /server
const express = require("express");
const app = express();
const http = require("http");
const { Server } = require("socket.io");
const cors = require("cors");
app.use(cors());
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
},
});
io.on("connection", (socket) => {
console.log(`User Connected: ${socket.id}`);
socket.on("join_room", (data) => {
socket.join(data);
});
socket.on("send_message", (data) => {
socket.to(data.room).emit("receive_message", data);
});
});
server.listen(3001, () => {
console.log("SERVER IS RUNNING");
});
App.js (React) /client
import "./App.css";
import io from "socket.io-client";
import { useEffect, useState } from "react";
const socket = io.connect("http://localhost:3001");
function App() {
//Room State
const [room, setRoom] = useState("");
// Messages States
const [message, setMessage] = useState("");
const [messageReceived, setMessageReceived] = useState("");
const joinRoom = () => {
if (room !== "") {
socket.emit("join_room", room);
}
};
const sendMessage = () => {
socket.emit("send_message", { message, room });
};
useEffect(() => {
socket.on("receive_message", (data) => {
setMessageReceived(data.message);
});
}, [socket]);
return (
<div className="App">
<input
placeholder="Room Number..."
onChange={(event) => {
setRoom(event.target.value);
}}
/>
<button onClick={joinRoom}> Join Room</button>
<input
placeholder="Message..."
onChange={(event) => {
setMessage(event.target.value);
}}
/>
<button onClick={sendMessage}> Send Message</button>
<h1> Message:</h1>
{messageReceived}
</div>
);
}
export default App;
Let's start with a quick review of your situation:
React app is running on port 3000 on your local computer ;
NodeJS app with WebSocket server is running on port 3001 on your local computer.
You want your app to work on your local network, therefore both the React App and the WebSocket server must be available.
If you try to run both on the same port it will fail (two different applications can't listen on the same port).
The idea then is to ngrok both the WebSocket server and the React App launching ngrok for localhost:3000 et localhost:3001 (you will need to adapt CORS and React WebSocket URL though).
Which raise a second problem, I suppose you can't use ngrok with two endpoints (localhost:3000 and localhost:3001) on the free tier.
A simple solution: you can tell React CRA and NodeJS to accept request from network using 0.0.0.0 as host:
for CRA it's the HOST variable (https://create-react-app.dev/docs/advanced-configuration/)
for NodeJS: you can use the host argument to server.listen.
You will still need to adapt the CORs and REACT app configuration though.

Unable to connect front end to back end while following a tutorial

I am following this tutorial https://www.youtube.com/watch?v=ZwFA3YMfkoc&ab_channel=JavaScriptMastery (github: https://github.com/adrianhajdin/project_chat_application) trying to create a real time chat app and I am unable to make a connection and I am unable to find what the issue is especially since my code looks exactly the same as the video.
import React, { useState, useEffect } from "react"; enter code hereimport queryString from "query-string"; import io from "socket.io-client";
import "./Chat.css";
let socket;
export default function Chat({ location }) { const [name, setName] = useState(""); const [room, setRoom] = useState(""); const ENDPOINT
= "localhost:5000"; console.log("logging!"); useEffect(() => {
const { name, room } = queryString.parse(location.search);
socket = io(ENDPOINT);
setRoom(room);
setName(name);
console.log(name,room)
socket.emit("join", { name, room }, (error) => {
if (error) {
alert(error);
}
}); }, [ENDPOINT, location.search]);
return <div>Hello World</div>; }
The console.log I put in isnt logging either and when I check the console this is the message I get repreatedly:
polling-xhr.js:202 GET http://localhost:5000/socket.io/?EIO=4&transport=polling&t=NSV19AI net::ERR_FAILED
The message I am expecting to get is an io object with "name" and "room" and also a "we have a new connection!!!" on the back end. This is the back end I am trying to connect to which as far as I've seen is working fine:
const express = require("express");
const socketio = require("socket.io");
const http = require("http");
const PORT = process.env.PORT || 5000;
const router = require("./router");
const { callbackify, isRegExp } = require("util");
const app = express();
const server = http.createServer(app);
const io = socketio(server);
io.on("connection", (socket) => {
console.log("we have a new connection!!!");
socket.on("join", ({ name, room }) => {
console.log(name, room);
const error = true;
if (error) {
callback({ error: "error" });
}
});
socket.on("disconnect", () => {
console.log("user disconnected :O!");
});
});
app.use(router);
server.listen(PORT, () => console.log(`server is running on port ${PORT}`));
I've been away from React and Express for a few months now so its likely there is something obvious I'm missing but when the useEffect console.log isnt logging anything I know something strange is happening.
This is the first time I will have posted a question on here so any feedback on how I can better phrase things is welcome.
You have defined,
const ENDPOINT= "localhost:5000";
It should be,
const ENDPOINT = "http://localhost:5000";

How to make a socket.io connection between two different interfaces?

I'm actually trying to make a real-time connection between two different apps. I've found a bunch of tutorials about how to make a chat using socket.io, but that doesn't really help me since it's just the same app duplicated in multiple windows.
I'm making a pick & ban overlay for League of Legends in local development. My first thought was to display the empty overlay on one hand and create an interface to manually update it on the other hand. Socket.io seems to be the right thing to use in my case since it can provide new data without having to reload the component.
This is what I wrote in both apps :
const express = require('express');
const socket = require('socket.io');
// App setup
const app = express();
const server = app.listen(4200, function () {
console.log('Listening to requests on port 4200')
});
// Static files
app.use(express.static('public'));
// Socket setup
const io = socket(server);
io.on('connection', function (socket) {
console.log('Made socket connection', socket.id);
socket.on('change', function (data) {
io.sockets.emit('change', data);
});
});
But I fail to connect them as they have to listen to the same port. What am I doing wrong?
(Forgive my bad English and lack of syntax, I'm doing my best here. :p)
I am certainly not an expert on network programming, but as far as I know you need to have one listening app (backend) and another one to connect to it (client). And you define what happens with all the data (messages) that backend recieves (for example sending the messages it recieves to all the clients in the same chat room).
If I am correct to assume you are trying to connect two listening apps?
simple google search of "nodejs socket server client example" revealed this https://www.dev2qa.com/node-js-tcp-socket-client-server-example/ might wanna take your research in this direction
u can try something like this way
var express = require('express');
var socket = require('socket.io');
// App setup
var app = express();
var server = app.listen(8080, () => {
console.log('App started')
})
// Static file
app.use(express.static('public'))
// Socket SetUp
var io = socket(server);
io.on('connection', socket => {
console.log('made the connection')
socket.on('chat',data => {
io.sockets.emit('chat',data)
});
socket.on('typing',data => {
socket.broadcast.emit('typing',data);
});
})
create another file and
var socket = io.connect('http://localhost:8080')
// Elenment
var message = document.getElementById('message');
handle = document.getElementById('handle');
btn = document.getElementById('send');
output = document.getElementById('output');
feedback = document.getElementById('feedback');
// Emit Events
btn.addEventListener('click', () => {
socket.emit('chat', {
message: message.value,
handle: handle.value
})
})
message.addEventListener('keypress', () => {
socket.emit('typing', handle.value)
})
socket.on('chat',data => {
feedback.innerHTML = '';
output.innerHTML += '<p><strong>' + data.handle +': </strong>' +
data.message + '</p>'
})
socket.on('typing', data => {
feedback.innerHTML = '<p><emp>' + data + ' is typing a message... </emp></p>'
})
details are given here node socket chat app
Ok, figured it out. Here's how it works using express and vue together :
First, setup socket.io in your express server js file :
const express = require('express')
const { Server } = require('socket.io')
const http = require('http')
const app = express()
const server = http.createServer(app)
const io = new Server(server, {
cors: {
origin: '*',
methods: ['GET', 'POST', 'REMOVE']
}
})
const PORT = process.env.PORT || 8080
io.on('connection', (socket) => {
console.log('New socket user')
socket.on('SEND_MESSAGE', data => {
console.log('received message in back')
io.emit('MESSAGE', data)
})
})
server.listen(PORT, () => { console.log(`Server started on port : ${PORT}`)})
As you can see we received from the client "SEND_MESSAGE" and we trigger MESSAGE from the server to forward the information to all the clients. The point I was missing is that we bind SEND_MESSAGE on the socked created from the connection but we emit from the io server.
Now you vue part :
import io from 'socket.io-client'
export default {
data() {
return {
messages: [],
inputMessage: null,
socket: io('http://localhost:8080')
}
},
mounted() {
this.socket.on('MESSAGE', data => {
this.messages.push(data)
})
},
methods: {
sendMessage() {
const message = {
senderID: this.myID,
message: this.inputMessage,
sendAt: new Date()
}
this.socket.emit('SEND_MESSAGE', message)
this.inputMessage = null
},
},
}

How to reach my backend API in a web host?

I need to access my backend API to send info from a contact form for an email, I deployed my app in a webhost called Kinghost and it gave me two urls the first is generically mywebaddr.com:port-number and the second is mywebaddr.com/site.
I have tried to use both addresses with the function route in the end just like I did in localhost, that in order to work I used http://localhost:4000/contact for example, but it didn't work...
this is my request:
const baseUrl = 'http://mywebsiteurl.com/contact'
const initialState = {
message: {
name: '',
email: '',
subject: '',
main: ''
},
}
export default class ContactUs extends Component {
state = { ...initialState }
reset = () =>{
this.setState({message: initialState.message})
}
send = () => {
const message = this.state.message
const url = baseUrl
console.log(message)
axios.post(url, message)
.then(this.reset())
.then(alert('Message successfully sent!'))
}
this is my index.js (backend)
const express = require('express')
const app = express()
const consign = require('consign')
const port = 4005
consign()
.then('./config/middlewares.js')
.then('./api')
.then('./config/routes.js')
.into(app)
app.listen(port, () => {
console.log(port)
})
my middlewares.js contains cors
const bodyParser = require('body-parser')
const cors = require('cors')
module.exports = app => {
app.use(bodyParser.json())
app.use(cors())
}
Actually, I don't think it's because of my code itself once I can execute everything perfectly in localhost, but somehow I can't get through with the correct URL
I'm new to node and I can't guess what am I doing wrongly, so if someone can help me I'd be really thankful :)
This is not a question for stack-overflow as your issue is not with the application but is with your network.
Anyhow, your API application is running on port 4005. Make sure the port is open with your hosting provider. while your at it make sure your port 4000 is open as well.
after you confirm your firewall settings ill update my answer if your still facing issues.

Hundreds of polling requests coming from socket.io, app really slow

I'm creating a real time chat app with socket.io, express and React.
My issue is that I get hundreds of polling requests until my browser basically crashes, I have no idea why.
I've tried to put a polling duration, a close timeout, a heartbeat interval, I've checked, both my socket.io and socket.io-client are on the same version.. I've tried everything could find on the web but nothing works.
I'm sure it's just a stupid little mistake that I just can't find, if you could help that would be great, thanks!
Here's my code :
import express from "express";
import socketio from 'socket.io';
import path from 'path';
import ioCookieParser from 'socket.io-cookie-parser'
import http from 'http';
const app = express()
const port = process.env.PORT || 8000
app.set("port", port)
const httpServer = new http.Server(app);
const io = socketio(httpServer);
io.use(ioCookieParser(secret));
io.on('connection', function (client) {
const userId = client.request.signedCookies._session;
const clients = new Map();
client.on('login', () => {
clients.set(userId, { client })
console.log("clients :", clients)
})
client.on('message', (message) => {
User.findById(userId, function(err, obj) {
if(err) {
console.log(err);
return null
}
let currentUser = obj["email"];
client.broadcast.emit("received", { message, currentUser });
Connect.then(db => {
console.log("connected correctly to the server");
let chatMessage = new Chat({ message: message, sender: currentUser});
chatMessage.save();
});
})
})
client.on('error', function (err) {
console.log('received error from client:', client.id)
console.log(err)
})
});
Here is an example of a request :
GET localhost:8000 /socket.io/?EIO=3&transport=polling&t=Mideit5&sid=OxvoE0uJbi9DZyk-AAt8 xhr
Thanks!
My issue was that, in the React component, I was declaring :
const socket = io.connect('http://localhost:8000')
inside the component.
I've moved this constant outside of the component and now the issue is solved!

Categories

Resources