Heyo.
i have an websocket defined like this.
const express = require('express');
const app = express();
const http = require('http');
const { Server } = require('socket.io');
const cors = require('cors');
app.use(cors());
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: "*",
method: ["GET", "POST", "PUT"],
},
});
io.on("connection", (socket) => {
console.log(`user connected: ${socket.id}`);
});
server.listen(3001, () => {
console.log("websocket online");
});
The following code is the function i want to pass to my frontend html via websocket, which is accessed by pressing an button on my frontend html.
app.get("/updateSomething", (req,res) {
//some code
}
My question would be: How do i tell my frontend to access that specific function from my node script via button click.
<button>DoSomething</button>
You can use JavaScript to emit to your socket.io server when you press that button.
For example in your client html:
<button id="doSomethingBtn">DoSomething</button>
<script>
const socket = io();
document.getElementById("doSomethingBtn").addEventListener("click", () => {
socket.emit("buttonClicked", 'someData');
});
</script>
and in your server handle this emit
io.on("connection", (socket) => {
console.log(`user connected: ${socket.id}`);
socket.on("buttonClicked", (someData) => {
console.log("button Clicked!")
// here you can do any code you want including running whatever is in your app.get
});
});
Please dont hesitate to make a comment if you dont understand soemthing or you need more help.
Related
I have an app in the MERN stack and I want to use socket.io for real time notifications. The problem is that I am confused where to initialize socket.io in my app.
I want to send a real time notification on multiple post routes.
Should I just initialize and use socket.io in my very app.js or on every post route needed. I am not sure what to do.
const mongoose = require("mongoose");
const express = require("express");
const app = express();
const socket = require("socket.io");
mongoose
.connect(process.env.MongoDb_Url)
.then(() => {
const io = socket(
app.listen(5000, () => console.log("Server And Database Are Running")),
{
cors: {
origin: "http://localhost:3000",
},
}
);
io.on("connection", (socket) => {
socket.on("message", async (message) => {
const messageCreated = await chatModel.create({ ...message });
socket.emit("createdMessage", messageCreated);
});
});
})
.catch((error) => console.log(error.message));
This is what I am saying. Like how do I use socket.io on every post route to send real time notifications. Please give me the code for it and make it clear for me.
Hello everyone and happy holidays!
I'm creating a chat app using socket.io and Express and need some guidance on how to proceed.
As it is now, I have my socket.io module in the same file as my express js file.
And it works fine, but when I started to implement a login page i noticed that when a go to the "localhost:port/" i still get connected to the socket and i get assigned a socket.id.
And it does make sense, I suppose, to start from the top and go to the bottom.
My plan is:
Go through the login page first
Then get redirected to the "localhost:port/MessagingClient" and get a socket.id
How it works now:
Go to the login page, get assigned a socket.id without login in.
Go to "localhost:port/MessagingClient" and get assigned a new socket.id
But since i run everything in 1 js file it doesn't work as i want it to.
My question is how can I split "Login" page and "MessagingClient" page, but still run on the same port?
I imagine I could solve this by running 2 node js processes instead of 1 and use 2 ports, but is that a valid way of doing it?
MessaginServer.js:
const dotenv = require("dotenv").config();
const express = require("express");
const app = require("express")();
const http = require("http").Server(app);
const io = require("socket.io")(http);
const port = process.env.PORT || 3000;
// import { readFromDB } from "./mongoDB.js";
const { readFromDB } = require("./mongoDB");
app.use(express.static(__dirname + "/public/"));
app.get("/", (req, res) => {
res.sendFile(__dirname + "/Public/LoginClient.html");
});
app.get("/MessagingClient", (req, res) => {
res.sendFile(__dirname + "/Public/MessaginClient.html");
});
io.on("connection", async (socket) => {
// socket.on("test1", arr1, arr2)=>{};
// socket.on("test2", arr1, arr2)=>{};
})
http.listen(port, () => {
console.log(`Socket.IO server running at http://localhost:${port}/`);
});
What i have tried:
I tried to move all the socket.io code inside
app.get("/MessagingClient", (req, res) => {
res.sendFile(__dirname + "/Public/MessaginClient.html");
});
but that resulted in message duplication..
Then I thought about trying to use Npm concurrently, but could not find anything about whether it is okay to use it in a production environment.
Any tips?
you create a socket server in a separate file:
const socketServer = (server) => {
const io = require("socket.io")(server, {
cors: {
origin: "*",
methods: ["GET", "POST"],
},
});
//set middleware for socket server here before .on
io.use((socket, next) => {
yourMiddleware(socket, next);
});
// your io connection logic
io.on("connection", async (socket) => {
// socket.on("test1", arr1, arr2)=>{};
// socket.on("test2", arr1, arr2)=>{};
});
};
module.exports = {
socketServer,
};
then in app.js
//initialize app
const app = express();
// add your middlewares and routing
const server = http.createServer(app);
// import socketServer
socketServer(server);
server.listen(PORT, () => {
console.log(`Server is listening on ${PORT}`);
});
you create a socket server in a separate file:
const socketServer = (server) => {
const io = require("socket.io")(server, {
cors: {
origin: "*",
methods: ["GET", "POST"],
},
});
//set middleware for socket server here before .on
io.use((socket, next) => {
yourMiddleware(socket, next);
});
// your io connection logic
io.on("connection", async (socket) => {
// socket.on("test1", arr1, arr2)=>{};
// socket.on("test2", arr1, arr2)=>{};
});
};
module.exports = {
socketServer,
};
then in app.js
//initialize app
const app = express();
// add your middlewares and routing
const server = http.createServer(app);
// import socketServer
socketServer(server);
server.listen(PORT, () => {
console.log(`Server is listening on ${PORT}`);
});
I have an Electron project initiated with VueCLI and a litle nodejs socket.io server, here's the server's file :
const http = require('http');
const express = require('express');
const socketio = require('socket.io');
const {
userJoin,
getCurrentUser,
userLeave,
getRoomUsers,
users
} = require('./utils/users');
const app = express();
const server = http.createServer(app);
const io = socketio(server);
// Set static folder
app.use(express.static(path.join(__dirname, 'public')));
// Run when client connects
io.on('connection', socket => {
console.log(`Connected tp ${socket.id}`)
app.get('/send-file', (req, res, next) => {
res.send('Sent')
})
socket.on('joinRoom', (args)=>{
console.log('joinroom')
})
// Runs when client disconnects
socket.on('disconnect', () => {
const user = userLeave(socket.id);
});
});
const PORT = process.env.PORT || 7575;
server.listen(PORT, () => console.log(`Server running on port ${PORT}`));
And here's my preload.js file :
const io = require('socket.io-client');
window.socket = io('http://localhost:7575');
window.socket.on('welcome', () => {
console.log('on welcome : welcome received renderer'); // displayed
window.socket.emit('test')
});
window.socket.on('error', (e) => {
console.log(e); // displayed ?
});
window.socket.on('ok', () => {
console.log("OK received renderer"); // displayed
});
window.socket.on('connect', () => {
console.log("connected renderer"); // displayed
window.socket.emit('test');
});
And here's my createWindow function:
async function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 700,
height: 600,
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
enableRemoteModule: true,
preload: path.join(__dirname, 'preload.js')
}
})
win.setMenu(null)
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
// Load the index.html when not in development
win.loadURL('app://./index.html')
}
}
The connection is made between the client and the server, because the console.log(Connected tp ${socket.id}) show a different socket ID everytime, but on my compenent, when I call the emit function nothing happens : window.socket.emit('joinRoom', {email:this.email, apikey:this.apikey})
And I can't event receive message on the client side, I've tested the server and everything works fine on a normale browser, but on my electron application can't emit or receive messages.
Is this related to my electron application?
Here's how I did it -
Server side:
const express = require('express')
const app = express()
// middlewares
app.use(express.static('public'))
// routes
app.get('/', (req, res) => {
res.render('index')
})
server = app.listen(7575, () => {
console.log("Server started");
})
//socket.io instantiation
const io = require("socket.io")(server)
//listen on every connection
io.on('connection', (socket) => {
console.log('New user connected');
//listen on "test"
socket.on('test', (data) => {
var username = data.username;
})
})
Client side:
socket = io.connect('http://localhost:7575')
socket.emit('test', {username: 'username'})
I created Express, Node, React app.
Now, i want to integrate socket.io to the app.
I searched all over the internet and i found that all the socket.io events are in the initial server.js/app.js file.
But, i want to separate the socket.io events from the main file and then import it to the main file, just like routes/controllers files.
My code right now:
var app = require("express")();
var http = require("http").createServer(app);
var io = require("socket.io")(http);
const mongoose = require("mongoose");
const stocks = require("./routes/stockRoutes");
const bodyParser = require("body-parser");
const cors = require("cors");
const port = 5000;
app.use(stocks);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.set("socketio", io);
const uri =
"mongodb+srv://admin:admin1234#investockcluster0.jp2wh.mongodb.net/<stocks_data>?retryWrites=true&w=majority";
mongoose.connect(uri, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
});
const connection = mongoose.connection;
connection.once("open", () => {
console.log("MongoDB database connection established successfully");
});
io.on("connection", (socket) => {
socket.emit("hello", "world");
console.log("New Connection");
});
http.listen(port, () => {
console.log(`Server is running on port: ${port}`);
});
I want that this code will be in file like "socketEvents.js" and then require it.
io.on("connection", (socket) => {
socket.emit("hello", "world");
console.log("New Connection");
});
Thanks a lot :)
Just put your socket.io code in another module and pass in the server in an initialization method:
// in sock.js
module.exports = function(server) {
const io = require("socket.io")(server);
io.on("connection", (socket) => {
socket.emit("hello", "world");
console.log("New Connection");
});
// put other things that use io here
}
Then, in your main file:
require('./sock.js')(http);
FYI, http is a crummy variable name for your server. You really ought to name it server.
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)