I have connected socket io to Webhook and it succeeds. It can get information and can express But I'm stuck with one problem. When the desired value is displayed on the client-side, the response is delayed. For example, when the server-side detects an event will show on console.log(); But it won't show on the client-side. But when the server-side detects the event again (second time) The value saved the first time is sent to the client-side, and if the server detects the event again (third time) The second event value is sent to the client-side, which means it will delay the event one time. How can I fix this incident?
// Server
const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io', {
transports: ['websocket', 'polling']
})(http, {
cors: {
origin:'*'
}
});
const bodyParser = require("body-parser");
PORT = 8080;
io.on('connection', socket => {
app.use(bodyParser.json());
app.post('/api', (req, res) => {
let x = req.body[0];
let dates = x.created_date;
let name = x.name;
let watchlist = x.watchlist[Object];
if (watchlist == "Matched"){
console.log("Date :", dates)
console.log("Name :", name)
io.emit('FromAPI', dates, name);
}
else {
console.log("Unmatch")
}
res.status(200).end("Successfully");
});
console.log('Socket connected');
socket.on('disconnect', () => { console.log('Socket disconnected')});
});
http.listen(PORT, () => {
console.log(`Server : http://localhost: ${PORT}`);
});
// Client
import { useEffect, useState } from 'react';
import io from 'socket.io-client';
const socket = io("http://localhost:8080", { transports: ['websocket', 'polling'] });
export default function App() {
const [date, setDate] = useState('');
const [name, setName] = useState('');
const [hook_event, setHook_event] = useState([
{ "date": date, "name": name},
{ "date": date, "name": name}
]);
useEffect(() => {
socket.on('FromAPI', (date, name) => {
setDate(date);
setName(name);
hook_event.unshift({"date": date, "name": name});
hook_event.pop();
})
}, [];
return (
<>
<p>Date : {hook_event[0].date} and {hook_event[0].name}</p>
<p>Date : {hook_event[1].date} and {hook_event[1].name}</p>
</>
);
};
I think I found the problem.
const [countState, setCountState] = useState()
useEffect(() => {
socket.on('FromAPI', (date, name) => {
setDate(date);
setName(name);
hook_event.unshift({"date": date, "name": name});
hook_event.pop();
setCountState(hook_event[0])
})
}, [setCountState]; // update setCountState
Related
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";
I am getting the error :ERR_CONNECTION_REFUSED. Send button doesn't work. There is also no welcome message displayed at the start for the newly joined user. I tried to solve it by changing ports to localhost. I've seen similar threads in this forum. No solutions help. What are the possible solutions to this problem? Is it related to false endpoint address?
Screenshot
import React, { useState, useEffect } from "react";
import queryString from 'query-string';
import io from "socket.io-client";
import Messages from '../Messages/Messages';
import InfoBar from '../InfoBar/InfoBar';
import Input from '../Input/Input';
import './Chat.css';
let socket;
const Chat = ({ location }) => {
const [name, setName] = useState('');
const [room, setRoom] = useState('');
const [users, setUsers] = useState('');
const [message, setMessage] = useState('');
const [messages, setMessages] = useState([]);
const ENDPOINT = 'localhost:5000';
useEffect(() => {
const { name, room } = queryString.parse(location.search);
socket = io(ENDPOINT);
setRoom(room);
setName(name)
socket.emit('join', { name, room }, (error) => {
if(error) {
alert(error);
}
});
}, [ENDPOINT, location.search]);
useEffect(() => {
socket.on('message', message => {
setMessages(messages => [ ...messages, message ]);
});
socket.on("roomData", ({ users }) => {
setUsers(users);
});
}, []);
const sendMessage = (event) => {
event.preventDefault();
if(message) {
socket.emit('sendMessage', message, () => setMessage(''));
}
}
return (
<div className="outerContainer">
<div className="container">
<InfoBar room={room} />
<Messages messages={messages} name={name} />
<Input message={message} setMessage={setMessage} sendMessage={sendMessage} />
</div>
</div>
);
}
export default Chat;
Server part
const http = require('http');
const express = require('express');
const socketio = require('socket.io');
const cors = require('cors');
const { addUser, removeUser, getUser, getUsersInRoom } = require('./users');
const router = require('./router');
const app = express();
const server = http.createServer(app);
const io = socketio(server);
app.use(cors());
app.use(router);
io.on('connect', (socket) => {
socket.on('join', ({ name, room }, callback) => {
const { error, user } = addUser({ id: socket.id, name, room });
if(error) return callback(error);
socket.join(user.room);
socket.emit('message', { user: 'admin', text: `${user.name}, welcome to room ${user.room}.`});
socket.broadcast.to(user.room).emit('message', { user: 'admin', text: `${user.name} has joined!` });
io.to(user.room).emit('roomData', { room: user.room, users: getUsersInRoom(user.room) });
callback();
});
socket.on('sendMessage', (message, callback) => {
const user = getUser(socket.id);
io.to(user.room).emit('message', { user: user.name, text: message });
callback();
});
socket.on('disconnect', () => {
const user = removeUser(socket.id);
if(user) {
io.to(user.room).emit('message', { user: 'Admin', text: `${user.name} has left.` });
io.to(user.room).emit('roomData', { room: user.room, users: getUsersInRoom(user.room)});
}
})
});
server.listen(process.env.PORT || 5000, () => console.log(`Server has started.`));
two info: [HMR] Waiting for update signal from WDS...
Download the React DevTools for a better development experience: fb.me/react-devtools
error: http://127.0.0.1:4001/socket.io/?EIO=3&transport=polling&t=N4qdmGu
Failed to load resource: net::ERR_CONNECTION_REFUSED what should be done to make this work?
const express = require("express");
const http = require("http");
const socketIo = require("socket.io");
const axios = require("axios");
const port = process.env.PORT || 4001;
const index = require("./routes/index");
const app = express();
app.use(index);
const server = http.createServer(app);
const io = socketIo(server);
let interval;
io.on("connection", socket => {
console.log("New client connected");
if (interval) {
clearInterval(interval);
}
interval = setInterval(() => getApiAndEmit(socket), 10000);
socket.on("disconnect", () => {
console.log("Client disconnected");
});
});
const getApiAndEmit = async socket => {
try {
const res = await axios.get(
"https://api.darksky.net/forecast/db057094f57ede5e1f8d33d5e528e4b3/30.9871097,34.9408864"
);
let temp = (((res.data.currently.temperature - 32) * 5) / 9).toFixed(2);
socket.emit("FromAPI", temp);
} catch (error) {
console.error(`Error: ${error.code}`);
}
};
server.listen(port, () => console.log(`Wee wee i'm on port ${port}`));
than
import React, { Component } from "react";
import socketIOClient from "socket.io-client";
class App extends Component {
constructor() {
super();
this.state = {
response: false,
endpoint: "http://127.0.0.1:4001"
};
}
componentDidMount() {
const socket = socketIOClient(this.state.endpoint);
socket.on("FromAPI", data => this.setState({ response: data }));
}
render() {
const { response } = this.state;
return (
<div style={{ textAlign: "center" }}>
{
response ?
(<p>The temperature is {response} degrees</p>)
:
(<p>load load...</p>)
}
</div>
);
}
}
export default App;
You have to first connect to the socket server on the client side so for that add this
socket.on('connect', function(){});
before your event listener.
socket.on("FromAPI", data => this.setState({ response: data }));
server side:
const express = require("express");
const http = require("http");
const socketIo = require("socket.io");
const axios = require("axios");
const port = process.env.PORT || 4001;
const index = require("./routes/index");
const app = express();
app.use(index);
const server = http.createServer(app);
const io = socketIo(server);
let interval;
io.on("connection", socket => {
console.log("New client connected");
if (interval) {
clearInterval(interval);
}
interval = setInterval(() => getApiAndEmit(socket), 10000);
socket.on("disconnect", () => {
console.log("Client disconnected");
});
});
const getApiAndEmit = async socket => {
try {
const res = await axios.get(
"https://api.darksky.net/forecast/db057094f57ede5e1f8d33d5e528e4b3/30.9871097,34.9408864"
);
let temp = (((res.data.currently.temperature - 32) * 5) / 9).toFixed(2);
socket.emit("FromAPI", temp);
} catch (error) {
console.error(`Error: ${error.code}`);
}
};
server.listen(port, () => console.log(`Wee wee i'm on port ${port}`));
client side:
import React, { Component } from "react";
import socketIOClient from "socket.io-client";
class App extends Component {
constructor() {
super();
this.state = {
response: false,
endpoint: "http://127.0.0.1:4001"
};
}
componentDidMount() {
const socket = socketIOClient(this.state.endpoint);
socket.on("FromAPI", data => this.setState({ response: data }));
}
render() {
const { response } = this.state;
return (
<div style={{ textAlign: "center" }}>
{
response ?
(<p>The temperature is {response} degrees</p>)
:
(<p>load load...</p>)
}
</div>
);
}
}
export default App;
2 info:
[HMR] Waiting for update signal from WDS...
Download the React DevTools for a better development experience: fb.me/react-devtools
1 error:
http://127.0.0.1:4001/socket.io/?EIO=3&transport=polling&t=N4qdmGu
Failed to load resource: net::ERR_CONNECTION_REFUSED
What's wrong?
You should try to set endpoint in client side to 'http://localhost:4001'.
I have an API endpoint in my Node/Express app. The endpoint is responsible to upload files. There are several stages involved in the upload process. like image conversion, sending images to another third party API, etc. I am using socket.io to tell the client about the current stage of upload.
The problem is, The socket connection works fine in the first call, but in my second call to the endpoint, the socket connection runs twice and retains the data which I sent in the previous call.
Here's my code:
server.js
import ClientsRouter from './api/routes/clients';
import express from 'express';
import http from 'http';
import io from 'socket.io';
const port = process.env.PORT || 3000;
const app = express();
const server = http.Server(app);
const socket = io(server);
app.set('socket', socket);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.use(express.static('dist'))
app.use('/uploads', express.static('uploads'));
app.use('/api/clients', ClientsRouter);
server.listen(port, () => console.log(`Server Listening on ${process.env.URL}`));
api/routes/clients.js
import express from 'express';
import ClientsController from '../controllers/clients';
ClientsRouter.post('/uploadClientData/', clientDataUpload.array('client_data'), ClientsController.uploadClientData);
controllers/clients.js
const uploadClientData = async (req, res) => {
try {
const files = req.files
const clientFolder = req.body.client_folder
const { dbxUser } = req;
const team_member_id = req.body.team_member_id;
const data = req.files.map( i => ({team_member_id, destination: i.destination.substring(1), filename: i.filename, status: 1 } ))
const io = req.app.get("socket");
console.log("Outside Socket", data); //This contains my currently passed data
io.on('connection', async socket => {
console.log("Socket Connection established");
console.log("Inside Socket", data); //But This contains my current data aling with the data that I passed in previous call
await uploadQueue.collection.insertMany(data)
socket.emit('upload stage', { upload_stage: 2, progress: 33 })
await helpers.convertImagesToWebResolution(team_member_id, req.body.dpi, req.body.resolution);
socket.emit('upload stage', { upload_stage: 3, progress: 66 })
await helpers.uploadImagesToDropbox(team_member_id, dbxUser, clientFolder)
socket.emit('upload stage', { upload_stage: 4, progress: 100 })
})
res.status(200).json({message: "Uploaded"});
} catch (error) {
console.log(error)
res.status(500).json({
error
});
}
}
And in my front-end react component
componentDidMount(){
const { currentFolder } = this.props;
this.setState({ client_folder: currentFolder }, () => this.afterFileSelect())
}
componentDidUpdate(prevProps){
const { selectedFiles } = this.props;
if(prevProps.selectedFiles !== selectedFiles){
this.afterFileSelect()
}
}
afterFileSelect = async () => {
const { selectedFiles, setSelectedFiles, currentFolder, user, uploadSettings} = this.props;
let formData = new FormData()
formData.append('client_folder', currentFolder)
formData.append('team_member_id', user.team_member_id)
formData.append('resolution', uploadSettings.resolution.split("x")[0])
formData.append('dpi', uploadSettings.dpi)
for(let selectedFile of selectedFiles){
formData.append('client_data', selectedFile)
}
let uploadResp = uploadSettings.convert_web_res ? await uploadClientData(formData) : await dropboxDirectUpload(formData)
const endpoint = uploadResp.config.url;
const host = endpoint.substring(0, endpoint.indexOf("api"));
const socket = socketIOClient(host);
socket.on("upload stage", data => {
this.setState({upload_stage: data.upload_stage, progress: data.progress})
data.upload_stage === 4 && this.setState({client_folder: ""})
})
}
Also I want to know if this is the correct way to to track upload progress?