I'm running a nodejs socket.io server on a raspberry pi, and a socket.io web client on Firefox.
But Firefox keeps giving me a Cross-Origin Request Blocked (Same Origin Policy Error).
// nodeJS Server:
var app = require('express')();
var cors = require('cors');
app.use(cors({origin: '*:*'}));
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(3000);
io.on('connection', function(socket) {
socket.emit('announcements', { message: 'A new user jas joined!' });
});
//JS Browser client:
const socket = io('ws://<INSERT_MY_EXTERNAL_IP>:3000');
socket.on('connect', () => {
socket.send('Hello!');
});
I've also tried: io.origins(...), io.set("origin", ...), but those keep saying the functions origins and set are undefined.
Not sure what to do at this point.
You can pass in a cors prop when you initialize the server socket.
Pass in a config object with cors set to true, eg. cors: true or cors: { origin: '*' }.
Read more about that here.
In action (only tested in LAN):
client.js
const socket = io('ws://localhost:3000');
socket.on('testing', res => { console.log(res) });
server.js
const app = require('express')()
const server = require('http').createServer(app)
const opts = { cors: { origin: '*' } }
const io = require('socket.io')(server, opts)
const cors = require('cors')
app.use(cors())
io.on('connection', (socket) => {
console.log(`Client connected (id=${socket.id})`)
socket.emit('testing', 123)
socket.on('disconnect', () => {
console.log(`Client disconnected (id=${socket.id})`)
})
});
(
port => server.listen(
port,
() => console.log(`Express server running on port ${port}`)
)
)(3000)
Related
I got the above exception when I try to implement socket.io to count active users, i tried every solution but nothing works for me.
Server:
const express = require("express");
const app = express();
const cors = require("cors");
const socketIo = require('socket.io');
const http = require('http');
//Enable CORS policy
app.use(cors());
app.options("*", cors());
//socket io
const server = http.createServer(app);
const io = socketIo(server, {
cors: {
origins: ["http://localhost:4200", "http://localhost:3000"],
methods: ["GET", "POST"],
credentials: false
}
});
var count = 0;
io.on('connection', (socket) => {
console.log("Client connected");
if (socket.handshake.headers.origin === "http://localhost:3000") {
count++;
socket.broadcast.emit('count', count);
socket.on('disconnect', () => {
count--;
socket.broadcast.emit('count', count);
});
}
});
//Server
app.listen(8080, () => {
console.log("Server is running on port 8080");
});
Change this:
app.listen(8080, () => {
console.log("Server is running on port 8080");
});
To this:
server.listen(8080, () => {
console.log("Server is running on port 8080");
});
You are facing this issue because the instance you've passed when initializing socket and instance you are listening to are different.
For more refer this:
Should I create a route specific for SocketIO?
i am new to socket.io and i can't get it to connect to react app. here is my app.js in node
const express = require('express');
const port = process.env.PORT || 4000;
const router = require('./routes/routes');
const cors = require('cors');
const app = express();
const bodyParser = require('body-parser');
const db = require('./db/db');
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', () => {
console.log('connected');
});
app.use('*', cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
(router);
app.listen(port, () => {
console.log('listening on port ' + port);
db.sync({
// force: true,
logging: false,
});
});
and my front end code.
import React, { useState, useEffect, useRef } from 'react';
import { io } from 'socket.io-client';
import classes from './Chatroom.module.css';
const Chatroom = ({ user, getAllMessages, setGetAllMessages }) => {
const ENDPOINT = 'http://localhost:4000/getallmessages';
var socket = io(ENDPOINT);
const messagesEndRef = useRef(null);
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
};
useEffect(() => {
socket.on('connect', () => {
socket.send('hello');
console.log('connected.');
});
console.log(socket);
}, []);
Whenever i look in the console on it shows connected: false and nothing is logging on the backend.
In order to fix the issue i had to add options to my io declaration as follows.
const server = require('http').createServer(app);
const options = {
cors: true,
origins: ['http://127.0.0.1:3000'],
};
const io = require('socket.io')(server, options);
127.0.0.1 being home and on client side my server is on 3000 so that's where that comes from. and on the client side you were right i had to remove "getallmessages" route so now it is as follows.
onst ENDPOINT = 'http://localhost:4000/';
var socket = io(ENDPOINT);
const messagesEndRef = useRef(null);
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
};
useEffect(() => {
socket.on('connect', () => {
socket.send('hello');
console.log('connected.');
});
console.log(socket);
}, []);
socket.io is bound to the server object so you should listen to the server instead of the app.
Change app.listen to server.listen
Change endpoint by removing getallmessages if you are not using namespaces
i followed instructions in this link Rohit Nishad and my data is well passed from client to server.
But the ID is not passed from my middleware with the overwritten function. A new Generated ID is shown on socket.io connection.
Any idea what's going wrong please ?
I'm using socket.io v3.1.0
server.js
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const socketIO = require('socket.io');
const io = socketIO(server, {
cors: {
origin: "http://localhost:4200",
methods: ["GET", "POST"]
},
});
// Socket.io configuration
io.of('/notification').use((socket, next) => {
console.log('(socket.handshake.query.userId) :', socket.handshake.query.userId);
io.engine.generateId = (req) => {
socket.handshake.query.userId;
};
next(null, true);
});
io.of('/user').use((socket, next) => {
io.engine.generateId = () => socket.handshake.query.userId;
next(null, true);
});
io.of('/notification').on('connection', socket => {
console.log('[Notification] - New client connected : ID ', socket.id);
});
io.of('/user').on('connection', socket => {
console.log('[User] - New client connected : ID ', socket.id);
});
const serverPort = process.env.PORT || port;
// Launch server
server.listen(serverPort, () => {
console.log(`App is running ! Go to http://${host}:${port}`);
});
and console output:
App is running ! Go to http://localhost:3000
(socket.handshake.query.userId) : 5ffdb966c204c85d4061bf9f
[Notification] - New client connected : ID EjdB0uz8K7NSGWYyAAAB
[User] - New client connected : ID E4tu9sKXliWTFEcsAAAC
I am trying to establish socket.io 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 http = require("http");
const app = express();
const server = http.createServer(app);
const socket = require("socket.io");
const io = socket(server);
server.listen(process.env.PORT || 8000, () => console.log('server is running on port 8000'));
app.use(express.static('client/build'));
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
io.on('connection', socket => {
console.log('connection')})
Here is react-native(client-side) code (trimmed)
import React from 'react'
import { Button } from 'react-native'
import io from 'socket.io-client';
const Room = props => {
const sock = useRef();
useEffect(() => {
sock.current = io.connect(<HOSTNAME>, {
forceNode: true,
transports: ['websocket'],
});
//to check if mobile connected to server
console.log('test');
console.log('check 11', sock.current.connected);
sock.current.on('connect', function() {
console.log('check 2', sock.current.connected);
});
});
}
When I try to connect I am not getting 'check 2' message in my console, which is to be printed on execution of sock.current.on('connect'....
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 have a really simple NodeJS app that I want to run on Heroku. This is how the index.js file looks like:
Server (port 3030)
const http = require('http');
const os = require('os');
const express = require('express')
const throng = require('throng'); // For cluster management
const { port, env, isProduction } = require('./config/vars');
const SocketIO = require('socket.io');
// Setting up a simple express app and wrapping it with http server
const setupServer = () => {
const app = express();
app.use(express.static(path.join(__dirname, '../public')));
const server = http.createServer(app);
return server;
};
const setupSocket = (server) => {
const io = new SocketIO(server);
io.on('connection', (socket) => {
console.log(`[Socket] Connection established: ${socket.id}`);
socket.on(msg.rooms.join, (room) => {
socket.join(room);
socket.to(room).emit(msg.rooms.joined);
console.log(`[Socket] User ${socket.id} joined '${room}' room`);
});
socket.on('disconnect', () => {
console.log(`[Socket] Distonnected: ${socket.id}`);
});
});
return io;
};
const WORKERS = (() => {
if (!isProduction) return 1;
return process.env.WEB_CONCURRENCY || os.cpus().length;
})();
async function master() {
console.log(`Preparing ${WORKERS} workers...`);
console.log('Master started.');
}
// There should be one server instance for each worker
const start = () => {
const server = setupServer(); // Returns and `http` server instance
const socket = setupSocket(server);
server.listen(port, async () => {
Logger.info(`Server – listening on port ${port}`);
});
return server;
};
const instance = throng({
workers: WORKERS,
lifetime: Infinity,
start,
master,
});
module.exports = instance;
Client (port 3000)
const setupSocket = ({ room }) => {
// Fallback if already setup
if (window.sockets[room]) {
return window.sockets[room];
}
const socket = io('http://localhost:3030');
socket.on('connect', () => {
console.log('[Socket] Connection established!', socket.id);
socket.emit('room.join', room);
});
socket.on('room.joined', () => {
console.log(`[Socket] Connected to ${room} room!`);
});
window.sockets[key] = socket;
return socket
};
The problem – the connection is sometimes established properly but most of the time I get an error
Error during WebSocket handshake: Unexpected response code: 400
What might be the problem here? Is it because I have it on two different ports or is it because of the clusters?
I've tried removing the throng part of the code, and just calling start() method without any cluster setup, but the problem remains :(
why would you use http module? The server instance that you send in the socketIO constructor should be the return object of the expressInstance.listen
Something more like this:
const express= require('express')
const app = express()
const socketio = require('socket.io')
app.use(express.static(__dirname + '/public'))
const server = app.listen('4000',()=>{
console.log('Listening to port:4000')
})
const io = socketio(server)
io.on('connect',(socket)=>{
socket.broadcast.emit('new_user')
socket.on('new_message',(message)=>{
io.emit('new_message',message)
})
})
source code: socket-io chat