I'm struggling to make my app (React + Node.js + Socket.IO) running in local, reachable from outside. I expose my 3000 port via tunneling (ngrok) but my socket connection listens on 3001. After having my port exposed port I obtain a Url, which used from another pc not on my network, makes my React App reachable but without the socket functionalities. If I try to make socket listening on 3000 the whole app stops working on local aswell. I'm new on this so I puzzles me how to make it work The final goal is to host the React App from my PC, using it to chat via browser from the same PC with another one not on the same network. I just want to make it work from my pc, so no external hosting from third parts. Any idea?
Index.js /server
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: "http://localhost:3000", methods: ["GET", "POST"], }, }); io.on("connection", (socket) => { console.log(`User Connected: ${socket.id}`); socket.on("join_room", (data) => { socket.join(data); }); socket.on("send_message", (data) => { socket.to(data.room).emit("receive_message", data); }); }); server.listen(3001, () => { console.log("SERVER IS RUNNING"); });
App.js (React) /client
import "./App.css"; import io from "socket.io-client"; import { useEffect, useState } from "react"; const socket = io.connect("http://localhost:3001"); function App() { //Room State const [room, setRoom] = useState(""); // Messages States const [message, setMessage] = useState(""); const [messageReceived, setMessageReceived] = useState(""); const joinRoom = () => { if (room.== "") { socket,emit("join_room"; room); } }. const sendMessage = () => { socket,emit("send_message", { message; room }); }. useEffect(() => { socket,on("receive_message". (data) => { setMessageReceived(data;message); }), }; [socket]). return ( <div className="App"> <input placeholder="Room Number..." onChange={(event) => { setRoom(event.target;value). }} /> <button onClick={joinRoom}> Join Room</button> <input placeholder="Message..." onChange={(event) => { setMessage(event.target;value): }} /> <button onClick={sendMessage}> Send Message</button> <h1> Message;</h1> {messageReceived} </div> ); } export default App;
Let's start with a quick review of your situation:
You want your app to work on your local network, therefore both the React App and the WebSocket server must be available.
If you try to run both on the same port it will fail (two different applications can't listen on the same port).
The idea then is to ngrok both the WebSocket server and the React App launching ngrok for localhost:3000 et localhost:3001 (you will need to adapt CORS and React WebSocket URL though). Which raise a second problem, I suppose you can't use ngrok with two endpoints (localhost:3000 and localhost:3001) on the free tier.
A simple solution: you can tell React CRA and NodeJS to accept request from network using 0.0.0.0 as host:
server.listen
.You will still need to adapt the CORs and REACT app configuration though.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.