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

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.

Related

React JS socket.io-client opens multiple connections

I have a simple React JS app connected to a socket io server. Whenever I open the app in the browser, the client sends new connection request to the server every 5 seconds.
server:
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log('socket id:', socket.id);
})
server.listen(3001, () => {
console.log('Listening on port 3001');
})
client:
import React from 'react';
import io from 'socket.io-client';
const socket = io('http://localhost:3001');
const App = () => {
return (
<div>Hi there!</div>
);
}
export default App;
logs on the server:
socket id: ByXQEMgeVaQ5AGw1AAAA
socket id: 8LzNQsyeYq7GSEvqAAAB
socket id: bbuYEs4kKzjxXuBsAAAC
socket id: vwprv4hnJbRlStG4AAAD
I suspect there could be something wrong on my laptop, cause I don't see anything wrong in the code, any ideas?
Thanks in advance
I would recommend calling connect inside a useEffect and return the disconnect method to be called when the component dismounts.
const [socket, setSocket] = useState(null)
useEffect(() => {
const newSocket = io('http://localhost:3001')
setSocket(newSocket)
return socket.disconnect()
}, [])
Can you try to wrap the client side socket creation in a useEffect that only runs once? I'm curious to see if the behavior still appears.
import React from 'react';
import io from 'socket.io-client';
const socket = io('http://localhost:3001');
const App = () => {
useEffect(() => {
const socket = io('http://localhost:3001');
}, [])
return (
<div>Hi there!</div>
);
}
export default App;
Actually I just found the root cause, I had a mismatch between my client version and my server version. I updated the client version to v4 and now it is working

ReactJS does not connect with NodeJS API using socket.io

I have an issue trying to connect a reactJS app with a nodeJS API using socket.io.
Here's API code :
const httpServer = require('http').createServer();
const io = require('socket.io')(httpServer);
httpServer.listen(8080, () => {
console.log('go to http://localhost:8080');
});
io.on('connection', socket => {
console.log('client connected');
});
And reactapp :
import React from "react";
import socketIOClient from "socket.io-client";
const ENDPOINT = "http://localhost:8080";
function App(){
const socket=socketIOClient.connect(ENDPOINT);
return(<p>Hello</p>);
}
export default App;
As you can see, it is a simple code but still it doesn't work.
The 'client connected' message from the API never shows up.
It looks like the react app can't connect to the port even if it's open or idk.
It may happen because of syntax in the react app side. Can you try this one in the function?
function App(){
let socket = io(ENDPOINT, {
transports: ["websocket"],
});
console.log("Connecting...");
socket.on("connect", () => console.log("Connected!"));
}
or you can define socket outside of the function.

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 failing after refresh page in client side

I am using socket.io in a react - node project. I have a problem with the socket not refreshing when the page refreshes.
It works first as the server and the react dev server run for the first time. After using the socket ( emitting something from the server ), refreshing the browser page would result in an error in the web socket.js file :
WebSocket connection to
'ws://localhost:4000/socket.io/?EIO=3&transport=websocket&sid=XTE63CeWdp676cRXAAAF'
failed: Error during WebSocket handshake: Unexpected response code:
400
here is the code I use in client and server :
SERVER :
const express = require('express');
const socketconfig = require('./socket.io');
class Server {
constructor({ config, router, logger, }) {
this.config = config;
this.logger = logger;
this.express = express();
this.express.disable('x-powered-by');
this.express.use(router);
}
start() {
return new Promise((resolve) => {
const http = this.express
.listen(this.config.web.port, () => {
const { port } = http.address();
this.logger.info(`[p ${process.pid}] Listening at port ${port}`);
resolve();
});
var io = require('socket.io').listen(http,function () {
console.log("I AM CONNECTIONG")
});
this.freshio=io.sockets;
socketconfig.setOnConnection(this.freshio, ()=>{
console.log('Connexion COnditions are set');
});
socketconfig.setOnDisconnect(this.freshio, ()=>{
console.log('client disconnected');
});
this.clients = socketconfig.clients;
});
}
}
module.exports = Server;
the start() method would be called when the server is initiated.
the socketConfig file is just a toolkit for saving clients and setting conditions, it doesn't interfere with anything.
CLIENT :
import openSocket from 'socket.io-client';
let url = Store.config.socketserverurl + ":" + Store.config.socketserverport;
const socket = openSocket.connect(url);
Store is just the flux store that has the config files linked to it.
I have tried adding the webSockets method of using socket.io instead of the http method but that was in vain as an other problem spiraled.
what should I do ?

Can´t resolve React & SOCKET.IO CORS Error

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
}
});
});

Resources