Reputation: 90
I'm trying to use react with socket.io but don't know why socket.emit()
not working. Here is a simplified code.
Frontend
import React , {useEffect,useRef} from 'react'
import io from 'socket.io-client'
const Chat = () => {
const socketRef = useRef(null);
useEffect(()=>{
socketRef.current = io.connect("http://127.0.0.1:4000")
return () => socketRef.current.disconnect()
},[])
const submit=()=>{
socketRef.current.emit('hello');
}
return(
<button onClick={submit}>Send</button>
)
}
export default Chat
Backend
const cors = require('cors')
const http = require('http').createServer()
const io = require('socket.io')(http, {
cors: {
origin: "http://localhost:3000"
}
})
io.on('connection', socket => {
console.log(socket.id+" connected")
socket.on('disconnect', function () {
console.log(socket.id+' disconnected')
socket.removeAllListeners();
});
socket.on('hello', ()=>{
console.log("hello");
})
})
http.listen(4000, function() {
console.log('listening on port 4000')
})
technically, When I press the button
, "hello" should be logged in console, but instead nothing happens. Although Connected and Disconnented events are getting logged.
I've tried every solutions I can find like, useContext
hook, proxy,etc but nothing seems to be working.
edit: added cors but nothing changes. problem remains same.
Upvotes: 0
Views: 802
Reputation: 407
Runned you example and it looks like client connection is rejected because of the CORS policy.
You can get this fixed by adding this to your server:
const io = require('socket.io')(http, {
cors: {
origin: "http://localhost:3000"
}
});
Above assumes that you are running reactjs server in port 3000. If you are using different port then you need to change this to match.
You can also set cors to "*"
. This means that all origins are accepted. But please keep in mind that this is considered a bad practice.
const io = require('socket.io')(http, {
cors: {
origin: "*"
}
});
About CORS
CORS is a security mechanism in the browser. When browser takes connection to some other server than the host of the website, the browser will block the response by default.
In your case you are running your website on one origin (for example localhost:3000
) and socket io server in localhost:4000
. These are considered to be different origins by the browser.
Way to fix this is that the server will send CORS-header with the response. That will inform the browser that this connection is OK to use "cross origin". The snippet above will just add CORS header to the socket IO's initial response.
You can see these headers in the chrome developer tools on the network tab. You will also get a CORS error in the console if the connection is blocked.
Working OK for me
Just copied your updated code and it is working fine for me. Added cat background for bonus.
Upvotes: 1