Can´t resolve React & SOCKET.IO CORS Error - node.js

I trying to setup a very simple App to get familar with using SOCKET.IO in an React APP. Server looks like this:
const io = require('socket.io')();
io.origins('*:*');
io.on('connection', (client) => {
client.on('subscribeToTimer', (interval) => {
console.log('client is subscribing to timer with interval ', interval);
setInterval(() => {
client.emit('timer', new Date());
}, interval);
});
});
const port = 8000;
io.listen(port);
console.log('listening on port ', port);
and React Client, which is setup with Create-React-App, looks like this:
import React, { Component } from 'react';
import './App.css';
import openSocket from 'socket.io-client';
const socket = openSocket('http://localhost:8000');
function subscribeToTimer(cb) {
socket.on('timer', timestamp => cb(timestamp));
socket.emit('subscribeToTimer', 1000);
}
class App extends Component {
constructor(props) {
super(props);
subscribeToTimer((timestamp) => {
this.setState({
timestamp
});
});
}
state = {
timestamp: 'no timestamp yet'
};
render() {
return (
<div className="App">
<div className="App-header">
<h2>Our awesome drawing app</h2>
</div>
This is the value of the timer timestamp: {this.state.timestamp}
</div>
);
}
}
export default App;
So basically server is sending a timestamp to the client using socket.io and this get´s then reflected there every second.
However this setup is running into the following CORS issue:
localhost/:1 Failed to load
http://localhost:8000/socket.io/?EIO=3&transport=polling&t=MEwUo-e:
Redirect from
'http://localhost:8000/socket.io/?EIO=3&transport=polling&t=MEwUo-e'
to
'https://localhost:8443/socket.io/?eio=3&transport=polling&t=MEwUo-e'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource. Origin
'http://localhost:3000' is therefore not allowed access.
I checked all the solutions provided here in other questions, i.e. io.origins{*:*}, I tried the same with using express.js and the cors npm package, etc. but the error remains. Any idea what I am doing wrong here? I am using Chrome Browser. Thanks a lot in advance

OK, I finally found the solution here: https://github.com/socketio/socket.io-client/issues/641
which lead me to change on the code on the client side in line 4 to const socket = openSocket('http://localhost:8000', , {transports: ['websocket']});

Use This :
const server = app.listen('3001', () => {
console.log("Server Up")});
const io = socket(server, {
cors: {
origin: "http://localhost:3000",
}
});
});

My fix was simply to
update my NPM packages: socket-io (on the client, and the Node server).
npm update
I was using outdated and incompatible packages.
DO NOT FORGET to specify the allowed origins on the server
const server = app.listen('8002', () => {
console.log("Server Up")});
const io = socket(server, {
cors: {
origin: "http://localhost:3000", //your own :port or a "*" for all origins
}
});
});

Related

Integrating socket.io(^3.0.0) with Strapi Server("3.2.5") CORS Error

I'm trying to build a simple chat app. I'm using create-react-app for the front-end, and I'm trying to integrate socket.io with Strapi server. My create-react-app server is running on Port 3000, while my Strapi local server is running on port 1337.
I've used this command to install starpi yarn create strapi-app chat-app and manually selected mongodb as database.
Receiving this error in the React app:
Code
On my React component, I have this:
import io from 'socket.io-client';
const socket = io('http://localhost:1337');
const handleClick = () => {
const username = props.username;
socket.emit("sendMessage", {
chatMessage,
username
})
}
In the Strapi backend, inside ./config/functions/bootstrap.js
module.exports = async () => {
process.nextTick(() => {
var io = require('socket.io')(strapi.server);
strapi.io.on('connection', async function(socket) {
socket.on('sendMessage', (msg) => {
console.log("msg is", msg)
})
socket.on('disconnect', () =>{
console.log('a user disconnected')
});
});
strapi.io = io;
})
};
I know to solve this cors error inside node app using cors module and use it like app.use(cors()) But not sure how I resolve this in case of strapi?
I followed this thread and tried some of the workarounds, but none of them seem to work. How do I resolve this issue?
So I resolved this issue by providing cors object to my socket.io. Option origins have been replaced with cors in the lastest version of socket.io(3.0.0)
var io = require('socket.io')(strapi.server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true
}
});
Checkout the socket migration guide for more info:
https://socket.io/docs/migrating-from-2-x-to-3-0/
I'm able to receive messages in the backend now. Thanks, Arya!

vue-socket.io app not receiving emit from express socket.io app

I am trying to create a socket.io communication between an express app using socket.io (localhost:8000) and a vue app using vue-socket.io (localhost:8080). The express app is receiving emissions from the vue app but not vice versa. Here is my express app though I'm pretty sure the problem lies in the vue app:
Backend Express
const port = 8000
const express = require("express")
const socket = require("socket.io")
const app = express()
const server = app.listen(port, () => {
console.log(`App is lisening to port ${port}...`)
} )
const io = socket(server)
io.on("connection", (socket) => {
console.log("connected to " + socket.id) //this is successfully getting logged
socket.on("chat", (msg) => {
console.log(socket.id + ": " + msg) //this is successfully getting logged when I click send
io.sockets.emit("chat", msg)
} )
} )
I'm guessing the problem is somewhere below:
Frontend Vue (using CLI)
main.js:
import Vue from 'vue'
import App from './App.vue'
import VueSocketIO from 'vue-socket.io'
import SocketIO from 'socket.io-client'
Vue.use(new VueSocketIO( {
debug: true,
connection: SocketIO('http://localhost:8000')
} )
)
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
Chat component (Chat.vue)
<template lang="html">
<div>
<input type="text" v-model="input"/>
<button #click="send">Send</button>
</div>
</template>
<script>
export default {
sockets: {
//These dont work, nothing is printed to the console
connect: function () {
console.log('socket connected')
},
chat: function (msg) {
console.log("chat message recieved!: " + msg)
}
},
data(){
return {
input: ""
}
},
methods: {
send(){
this.$socket.emit('chat', this.input) //This works and is recieved by the express app!
}
}
}
</script>
I've been trying to figure this out for a day now with no luck.
Once again my only goal is to be able to receive emissions front the express app. As a side note if there is a better way to use socket.io in vue without using vue-socket.io I would be glad to investigate.
I was able to get this working simply by using vue-socket.io-extended instead of vue-socket.io. That was it, no major changes to the code necessary. I know technically this doesn't solve the issue using vue-socket.io, but until someone figures that out, I will leave this as the answer for future searchers.

Vuejs not firing code when receiving message from socket.io server

I've been working on allowing a vuejs app talk to a remote, standalone socket.io server. I've managed to get the vuejs app to send messages to the socket.io server (confirmed through console logs on the nodejs instance), and I appear to be getting the responses back, but I can't seem to get it to fire code based on the responses.
I'm using Vue-socket.io, in the most basic form and i've added localhost and null to origins to hopefully rule out that issue.
I'm running socket.io server on localhost:3000
I'm running vuejs app
on localhost:8888
Why aren't the listeners firing in the following code? I also don't get any of the console logs for sockets.connect and sockets.customMessage in app.vue.
socket.io (nodejs) server:
var http = require('http').createServer({
origins: ['localhost','null',null]
});
var io = require('socket.io')(http);
io.on('connection', (socket) => {
console.log('a user connected');
socket.broadcast.emit('hi, welcome to live chat');
socket.on('disconnect', () => {
console.log('user disconnected');
});
socket.on('chatMessage', (msg) => {
console.log('chatMessage: ' + msg);
io.emit('chatMessage', msg);
});
})
http.listen(3000, () => {
console.log('listening on port 3000');
});
app.js (entry point for vuejs app):
import Vue from 'vue'
//import store from './store'
import App from './App.vue'
import VueSocketIO from 'vue-socket.io'
import SocketIO from "socket.io-client"
Vue.use(new VueSocketIO({
debug: true,
connection: 'http://localhost:3000'
}))
new Vue({
render: h => h(App)
}).$mount('#app')
App.vue:
<template>
<div>
hello chat app
<input type="text" v-model="message"/>
<button #click="clickButton()">Send Msg</button>
</div>
</template>
<script>
export default {
name: "Home",
sockets: {
connect: function () {
console.log('socket connected')
},
chatMessage: function(data) {
console.log('this method was fired by the socket server. eg: io.emit("chatMessage", data)')
}
},
methods: {
clickButton: function () {
console.log('button clicked');
console.log(this.message);
// $socket is socket.io-client instance
this.$socket.emit('chatMessage', this.message)
}
},
data: () => {
return {
message: '',
};
},
computed: {
},
mounted() {
this.$socket.on('chatMessage',data => {
console.log('listen fired')
console.log(data);
});
}
}
</script>
I created an VueApp, then copied, pasted your code to use. It's working well.
Checked in network tab on browser, the vueApp connected to the socket on localhost:3000 - check this image: https://prnt.sc/skbglc
Console tab: https://prnt.sc/skbhjz
Sent a message: https://prnt.sc/skbi1y https://prnt.sc/skbiij
Got the message from server: https://prnt.sc/skbj19
So what I changed in your code is just: comment out the unused code:
Hope this helps!
Can you try to put this configuration in your app.js
Just add a option for connection, and use it when instantiating the VueSocketIO instance.
const options = { path: '/socket.io/' }; //<--
Vue.use(new VueSocketIO({
debug: true,
connection: 'http://localhost:3000',
options //<--
})
);
And try again? If it does not work, I can post mine solution.

socket.io is not able to connect react-native and nodejs

I am trying to establish websocket connection between nodejs and react-native. But unfortunately it is not working.
The issue is that client side do not get connected with server via sockets.
Here is nodejs (server-side) code
const express = require('express');
const app = express();
var server = app.listen(3000, () => console.log('server connected'))
const io = require("socket.io")(server)
io.on("connect", (socket) => {
console.log("user connected");
socket.on("chat message", mssg => {
console.log(mssg);
io.emit("chat message", mssg)
})
})
app.get('/', (req, res) => {
res.send("Hey! u are connected to server");
})
Here is react-native(client-side) code
import React from 'react'
import { Button } from 'react-native'
import io from 'socket.io-client'
export default class extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.socket = io("http://localhost:3000");
this.socket.on('connect', () => console.log("connected"))
this.socket.on("chat message", mssg => {
console.log("mssg recieved in client:", mssg)
})
}
render() {
return <Button title="click to send message" onPress={() => {
this.socket.emit("chat message", "anshika this side")
}
} />
}
}
Libraries used: react-native version:0.62.1, socket.io-client version:2.3.0 (client-side), socket.io version:2.3.0 (server-side)
I solved the issue by adding ip address of my laptop instead of putting localhost as a link in react-native code
you must use your ipv4 address and the catch was to specify "transports" parameters in io as ['websocket'] what's no needed in web apps
import io from 'socket.io-client'
io('http://xxx.xxx.x.xxx:port', {
transports: ['websocket']
})

React-Native not able to connect to a Node.js server (Network request failed onerror)

I am trying to make a simple React Native app able to send data to a Node.js server.
Nonetheless I get a 'Network request failed' error...
It is the first time I'm trying to implement this kind of project so I may have done a stupid mistake but it's been 2 days I've been unable to find
Thanks for any help or advice!
This is my app code:
import React from 'react'
import {Text, View, TextInput, Button, StyleSheet, ImageBackground, Image, TouchableOpacity} from 'react-native' //import des components natifs
import {StackNavigator } from 'react-navigation';
const io = require('socket.io-client');
let socket = io('https://localhost:8080');
class Connexion extends React.Component{
constructor(props){
super(props);
}
validationConnexion(){
fetch('https://localhost:8080', {
method: 'POST',
headers: {
Accept: 'text/plain',
},
}).catch((error) => {
console.error(error);
});
}
On the backend side:
const express = require('express');
const https = require('https')
const socketio = require('socket.io');
const app = express();
const server = https.Server(app, function(req, res) {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end();})
const websocket = socketio(server);
server.listen(8080, () => console.log('listening on *:8080'));
// The event will be called when a client is connected.
websocket.on('connection', (socket) => {
console.log('A client just joined on', socket.id);
});
Try your IP address instead of localhost
For example:
https://localhost:8080 to https://192...*:8080

Resources