From 387306cf12aa9217852ebf283bee5b8fec719042 Mon Sep 17 00:00:00 2001 From: qi <qi.c.zhang@outlook.com> Date: Fri, 22 Dec 2023 22:23:19 -0500 Subject: [PATCH 1/2] Added an example of implementing private messaging in Vite+React --- .../react-private-messaging/.eslintrc.cjs | 20 ++ examples/react-private-messaging/.gitignore | 24 +++ examples/react-private-messaging/LICENSE | 21 ++ examples/react-private-messaging/README.md | 20 ++ examples/react-private-messaging/index.html | 12 ++ examples/react-private-messaging/package.json | 31 +++ .../react-private-messaging/server/cluster.js | 31 +++ .../server/docker-compose.yml | 7 + .../react-private-messaging/server/index.js | 125 ++++++++++++ .../server/messageStore.js | 54 ++++++ .../server/package.json | 17 ++ .../server/sessionStore.js | 89 +++++++++ examples/react-private-messaging/src/App.css | 179 ++++++++++++++++++ examples/react-private-messaging/src/App.jsx | 141 ++++++++++++++ examples/react-private-messaging/src/Chat.jsx | 111 +++++++++++ .../react-private-messaging/src/SignIn.jsx | 91 +++++++++ examples/react-private-messaging/src/main.jsx | 9 + .../react-private-messaging/src/socket.js | 10 + .../react-private-messaging/vite.config.js | 10 + 19 files changed, 1002 insertions(+) create mode 100644 examples/react-private-messaging/.eslintrc.cjs create mode 100644 examples/react-private-messaging/.gitignore create mode 100644 examples/react-private-messaging/LICENSE create mode 100644 examples/react-private-messaging/README.md create mode 100644 examples/react-private-messaging/index.html create mode 100644 examples/react-private-messaging/package.json create mode 100644 examples/react-private-messaging/server/cluster.js create mode 100644 examples/react-private-messaging/server/docker-compose.yml create mode 100644 examples/react-private-messaging/server/index.js create mode 100644 examples/react-private-messaging/server/messageStore.js create mode 100644 examples/react-private-messaging/server/package.json create mode 100644 examples/react-private-messaging/server/sessionStore.js create mode 100644 examples/react-private-messaging/src/App.css create mode 100644 examples/react-private-messaging/src/App.jsx create mode 100644 examples/react-private-messaging/src/Chat.jsx create mode 100644 examples/react-private-messaging/src/SignIn.jsx create mode 100644 examples/react-private-messaging/src/main.jsx create mode 100644 examples/react-private-messaging/src/socket.js create mode 100644 examples/react-private-messaging/vite.config.js diff --git a/examples/react-private-messaging/.eslintrc.cjs b/examples/react-private-messaging/.eslintrc.cjs new file mode 100644 index 0000000000..4dcb43901a --- /dev/null +++ b/examples/react-private-messaging/.eslintrc.cjs @@ -0,0 +1,20 @@ +module.exports = { + root: true, + env: { browser: true, es2020: true }, + extends: [ + 'eslint:recommended', + 'plugin:react/recommended', + 'plugin:react/jsx-runtime', + 'plugin:react-hooks/recommended', + ], + ignorePatterns: ['dist', '.eslintrc.cjs'], + parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, + settings: { react: { version: '18.2' } }, + plugins: ['react-refresh'], + rules: { + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, +} diff --git a/examples/react-private-messaging/.gitignore b/examples/react-private-messaging/.gitignore new file mode 100644 index 0000000000..a547bf36d8 --- /dev/null +++ b/examples/react-private-messaging/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/examples/react-private-messaging/LICENSE b/examples/react-private-messaging/LICENSE new file mode 100644 index 0000000000..190bfbe0ea --- /dev/null +++ b/examples/react-private-messaging/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 qzhang1 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/examples/react-private-messaging/README.md b/examples/react-private-messaging/README.md new file mode 100644 index 0000000000..ac80695fc4 --- /dev/null +++ b/examples/react-private-messaging/README.md @@ -0,0 +1,20 @@ +# Private Message in React + Vite + +This is an implementation of the Private messaging example in React following +Socket.io recommendations https://socket.io/how-to/use-with-react + +## Running the frontend + +``` +npm install +npm run dev +``` + +### Running the server + +``` +cd server +npm install +npm start +``` + diff --git a/examples/react-private-messaging/index.html b/examples/react-private-messaging/index.html new file mode 100644 index 0000000000..c49a808a7b --- /dev/null +++ b/examples/react-private-messaging/index.html @@ -0,0 +1,12 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>React Socket.io</title> + </head> + <body> + <div id="root"></div> + <script type="module" src="/src/main.jsx"></script> + </body> +</html> diff --git a/examples/react-private-messaging/package.json b/examples/react-private-messaging/package.json new file mode 100644 index 0000000000..58d66c08ab --- /dev/null +++ b/examples/react-private-messaging/package.json @@ -0,0 +1,31 @@ +{ + "name": "basic-crud-socket-app", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.15.0", + "@mui/material": "^5.15.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "socket.io-client": "^4.7.2" + }, + "devDependencies": { + "@types/react": "^18.2.43", + "@types/react-dom": "^18.2.17", + "@vitejs/plugin-react": "^4.2.1", + "eslint": "^8.55.0", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "vite": "^5.0.8" + } +} diff --git a/examples/react-private-messaging/server/cluster.js b/examples/react-private-messaging/server/cluster.js new file mode 100644 index 0000000000..e3bad09f8c --- /dev/null +++ b/examples/react-private-messaging/server/cluster.js @@ -0,0 +1,31 @@ +const cluster = require("cluster"); +const http = require("http"); +const { setupMaster } = require("@socket.io/sticky"); + +const WORKERS_COUNT = 4; + +if (cluster.isMaster) { + console.log(`Master ${process.pid} is running`); + + for (let i = 0; i < WORKERS_COUNT; i++) { + cluster.fork(); + } + + cluster.on("exit", (worker) => { + console.log(`Worker ${worker.process.pid} died`); + cluster.fork(); + }); + + const httpServer = http.createServer(); + setupMaster(httpServer, { + loadBalancingMethod: "least-connection", // either "random", "round-robin" or "least-connection" + }); + const PORT = process.env.PORT || 3000; + + httpServer.listen(PORT, () => + console.log(`server listening at http://localhost:${PORT}`) + ); +} else { + console.log(`Worker ${process.pid} started`); + require("./index"); +} diff --git a/examples/react-private-messaging/server/docker-compose.yml b/examples/react-private-messaging/server/docker-compose.yml new file mode 100644 index 0000000000..4845950cf6 --- /dev/null +++ b/examples/react-private-messaging/server/docker-compose.yml @@ -0,0 +1,7 @@ +version: "3" + +services: + redis: + image: redis:5 + ports: + - "6379:6379" diff --git a/examples/react-private-messaging/server/index.js b/examples/react-private-messaging/server/index.js new file mode 100644 index 0000000000..1ab99be5c4 --- /dev/null +++ b/examples/react-private-messaging/server/index.js @@ -0,0 +1,125 @@ +const httpServer = require("http").createServer(); +const Redis = require("ioredis"); +const redisClient = new Redis(); +const io = require("socket.io")(httpServer, { + cors: { + origin: "http://localhost:8080", + }, + adapter: require("socket.io-redis")({ + pubClient: redisClient, + subClient: redisClient.duplicate(), + }), +}); + +const { setupWorker } = require("@socket.io/sticky"); +const crypto = require("crypto"); +const randomId = () => crypto.randomBytes(8).toString("hex"); + +const { RedisSessionStore } = require("./sessionStore"); +const sessionStore = new RedisSessionStore(redisClient); + +const { RedisMessageStore } = require("./messageStore"); +const messageStore = new RedisMessageStore(redisClient); + +io.use(async (socket, next) => { + const sessionID = socket.handshake.auth.sessionID; + if (sessionID) { + const session = await sessionStore.findSession(sessionID); + if (session) { + socket.sessionID = sessionID; + socket.userID = session.userID; + socket.username = session.username; + return next(); + } + } + const username = socket.handshake.auth.username; + if (!username) { + return next(new Error("invalid username")); + } + socket.sessionID = randomId(); + socket.userID = randomId(); + socket.username = username; + next(); +}); + +io.on("connection", async (socket) => { + // persist session + sessionStore.saveSession(socket.sessionID, { + userID: socket.userID, + username: socket.username, + connected: true, + }); + + // emit session details + socket.emit("session", { + sessionID: socket.sessionID, + userID: socket.userID, + }); + + // join the "userID" room + socket.join(socket.userID); + + // fetch existing users + const users = []; + const [messages, sessions] = await Promise.all([ + messageStore.findMessagesForUser(socket.userID), + sessionStore.findAllSessions(), + ]); + const messagesPerUser = new Map(); + messages.forEach((message) => { + const { from, to } = message; + const otherUser = socket.userID === from ? to : from; + if (messagesPerUser.has(otherUser)) { + messagesPerUser.get(otherUser).push(message); + } else { + messagesPerUser.set(otherUser, [message]); + } + }); + + sessions.forEach((session) => { + users.push({ + userID: session.userID, + username: session.username, + connected: session.connected, + messages: messagesPerUser.get(session.userID) || [], + }); + }); + socket.emit("users", users); + + // notify existing users + socket.broadcast.emit("user connected", { + userID: socket.userID, + username: socket.username, + connected: true, + messages: [], + }); + + // forward the private message to the right recipient (and to other tabs of the sender) + socket.on("private message", ({ content, to }) => { + const message = { + content, + from: socket.userID, + to, + }; + socket.to(to).to(socket.userID).emit("private message", message); + messageStore.saveMessage(message); + }); + + // notify users upon disconnection + socket.on("disconnect", async () => { + const matchingSockets = await io.in(socket.userID).allSockets(); + const isDisconnected = matchingSockets.size === 0; + if (isDisconnected) { + // notify other users + socket.broadcast.emit("user disconnected", socket.userID); + // update the connection status of the session + sessionStore.saveSession(socket.sessionID, { + userID: socket.userID, + username: socket.username, + connected: false, + }); + } + }); +}); + +setupWorker(io); diff --git a/examples/react-private-messaging/server/messageStore.js b/examples/react-private-messaging/server/messageStore.js new file mode 100644 index 0000000000..60ab0f6f72 --- /dev/null +++ b/examples/react-private-messaging/server/messageStore.js @@ -0,0 +1,54 @@ +/* abstract */ class MessageStore { + saveMessage(message) {} + findMessagesForUser(userID) {} +} + +class InMemoryMessageStore extends MessageStore { + constructor() { + super(); + this.messages = []; + } + + saveMessage(message) { + this.messages.push(message); + } + + findMessagesForUser(userID) { + return this.messages.filter( + ({ from, to }) => from === userID || to === userID + ); + } +} + +const CONVERSATION_TTL = 24 * 60 * 60; + +class RedisMessageStore extends MessageStore { + constructor(redisClient) { + super(); + this.redisClient = redisClient; + } + + saveMessage(message) { + const value = JSON.stringify(message); + this.redisClient + .multi() + .rpush(`messages:${message.from}`, value) + .rpush(`messages:${message.to}`, value) + .expire(`messages:${message.from}`, CONVERSATION_TTL) + .expire(`messages:${message.to}`, CONVERSATION_TTL) + .exec(); + } + + findMessagesForUser(userID) { + return this.redisClient + .lrange(`messages:${userID}`, 0, -1) + .then((results) => { + return results.map((result) => JSON.parse(result)); + }); + } +} + +module.exports = { + InMemoryMessageStore, + RedisMessageStore, +}; diff --git a/examples/react-private-messaging/server/package.json b/examples/react-private-messaging/server/package.json new file mode 100644 index 0000000000..6a0310bcd7 --- /dev/null +++ b/examples/react-private-messaging/server/package.json @@ -0,0 +1,17 @@ +{ + "name": "server", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "node cluster.js" + }, + "author": "Damien Arrachequesne <damien.arrachequesne@gmail.com>", + "license": "MIT", + "dependencies": { + "@socket.io/sticky": "^1.0.0", + "ioredis": "^4.22.0", + "socket.io": "^4.0.0", + "socket.io-redis": "^6.0.1" + } +} diff --git a/examples/react-private-messaging/server/sessionStore.js b/examples/react-private-messaging/server/sessionStore.js new file mode 100644 index 0000000000..0ace3f4eb5 --- /dev/null +++ b/examples/react-private-messaging/server/sessionStore.js @@ -0,0 +1,89 @@ +/* abstract */ class SessionStore { + findSession(id) {} + saveSession(id, session) {} + findAllSessions() {} +} + +class InMemorySessionStore extends SessionStore { + constructor() { + super(); + this.sessions = new Map(); + } + + findSession(id) { + return this.sessions.get(id); + } + + saveSession(id, session) { + this.sessions.set(id, session); + } + + findAllSessions() { + return [...this.sessions.values()]; + } +} + +const SESSION_TTL = 24 * 60 * 60; +const mapSession = ([userID, username, connected]) => + userID ? { userID, username, connected: connected === "true" } : undefined; + +class RedisSessionStore extends SessionStore { + constructor(redisClient) { + super(); + this.redisClient = redisClient; + } + + findSession(id) { + return this.redisClient + .hmget(`session:${id}`, "userID", "username", "connected") + .then(mapSession); + } + + saveSession(id, { userID, username, connected }) { + this.redisClient + .multi() + .hset( + `session:${id}`, + "userID", + userID, + "username", + username, + "connected", + connected + ) + .expire(`session:${id}`, SESSION_TTL) + .exec(); + } + + async findAllSessions() { + const keys = new Set(); + let nextIndex = 0; + do { + const [nextIndexAsStr, results] = await this.redisClient.scan( + nextIndex, + "MATCH", + "session:*", + "COUNT", + "100" + ); + nextIndex = parseInt(nextIndexAsStr, 10); + results.forEach((s) => keys.add(s)); + } while (nextIndex !== 0); + const commands = []; + keys.forEach((key) => { + commands.push(["hmget", key, "userID", "username", "connected"]); + }); + return this.redisClient + .multi(commands) + .exec() + .then((results) => { + return results + .map(([err, session]) => (err ? undefined : mapSession(session))) + .filter((v) => !!v); + }); + } +} +module.exports = { + InMemorySessionStore, + RedisSessionStore, +}; diff --git a/examples/react-private-messaging/src/App.css b/examples/react-private-messaging/src/App.css new file mode 100644 index 0000000000..c01137d449 --- /dev/null +++ b/examples/react-private-messaging/src/App.css @@ -0,0 +1,179 @@ +*, +*:before, +*:after { + box-sizing: border-box; +} + +body { + font-family: "Roboto", Arial, sans-serif; + background: #141e30; /* fallback for old browsers */ + background: -webkit-linear-gradient( + to right, + #243b55, + #141e30 + ); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient( + to right, + #243b55, + #141e30 + ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ +} + +.app-container { + display: flex; + justify-content: center; + align-items: center; + min-height: 80vh; + min-width: 80vw; +} + +/* Chat component */ +.chat-container { + display: grid; + grid-template-areas: "column1 column2"; + grid-template-columns: 30% 70%; + min-width: 80vw; + min-height: 70vh; + border: 1px solid #fff; + border-radius: 10px; + background-color: #f8f3eb; +} + +.user-list { + grid-area: column1; + box-shadow: 0 0 30px rgba(0, 0, 0, 0.1); + margin: 0 5px 0 5px; + padding: 0; + h3 { + margin-bottom: 10px; + } + ul { + list-style: none; + padding: 0; + overflow-y: auto; + } + li { + padding: 5px; + margin-right: 10px; + margin-bottom: 10px; + .name { + margin-right: 5px; + } + .logged-in { + color: green; + } + .logged-out { + color: black; + } + } + li:hover { + border-radius: 6px; + background-color: #aaa; + } + li.user.selected { + border-radius: 6px; + background-color: #aaa; + } +} + +.chat-window { + grid-area: column2; + display: flex; + flex-direction: column; + justify-content: space-between; + padding: 20px; + overflow-y: auto; + + .chat-input { + width: 100%; + border-radius: 6px; + border: 1px solid #fff; + padding: 10px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + transition: 0.3s border-color; + } + + .chat-input:hover { + border: 1px solid #e0e0e0; + } + + .chat-messages { + width: 100%; + + .message { + list-style: none; + } + + .message.receive { + text-align: left; + } + + .message.sent { + text-align: right; + } + } + + li.message.received > div.wrapper { + margin-bottom: 20px; + } + + li.message.received > div.wrapper > span { + background-color: #cfcfcf; + color: #000; + border-radius: 6px; + padding: 5px; + } + + li.message.sent > div.wrapper { + margin-bottom: 20px; + } + + li.message.sent > div.wrapper > span { + border-radius: 6px; + background-color: #4355ba; + color: #fae8e8; + padding: 5px; + } +} + +/* Sign in */ +.paper-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.paper { + padding: 60px 50px; + border: 1px solid #fff; + border-radius: 10px; + background-color: #f8f3eb; +} + +.paper-header { + text-align: center; +} + +.formgroup-input { + width: 100%; + margin: 5px 0; + padding: 5px; + border: 1px solid #ebebeb; + border-radius: 6px; + box-shadow: 5px 1px 10px rgba(0, 0, 0, 0.1); + transition: 0.6s border-color; +} +.formgroup-input:hover { + border: 1px solid #aaa; +} + +.formgroup-button { + padding: 5px; + border: none; + background-color: #3f51b5; + border-radius: 6px; + color: #fff; + font-weight: 600; + width: 100%; +} diff --git a/examples/react-private-messaging/src/App.jsx b/examples/react-private-messaging/src/App.jsx new file mode 100644 index 0000000000..fec1e0d68a --- /dev/null +++ b/examples/react-private-messaging/src/App.jsx @@ -0,0 +1,141 @@ +import { useEffect, useState } from "react"; +import SignIn from "./SignIn"; +import Chat from "./Chat"; +import { socket } from "./socket"; +import "./App.css"; + +const defaultUser = { + isLoggedIn: false, + username: null, + userID: null, + connected: false, +}; + +function App() { + const [user, setUser] = useState(defaultUser); + const [allUsers, setAllUsers] = useState([]); + const [selectedUser, setSelectedUser] = useState(); + const [currentChatMsg, setCurrentChatMsg] = useState( + selectedUser?.messages || [] + ); + + const onSignIn = (username) => { + setUser({ + ...user, + isLoggedIn: username.length > 0, + username, + }); + }; + + useEffect(() => { + if (user.isLoggedIn) { + function getAllUsers(users) { + console.log(users); + users = users.sort((a, b) => { + if (a.self) return -1; + if (b.self) return 1; + if (a.username < b.username) return -1; + return a.username > b.username ? 1 : 0; + }); + console.log(users); + setAllUsers(users); + } + function setSession({ sessionID, userID }) { + socket.auth.sessionID = sessionID; + socket.userID = userID; + setUser({ + ...user, + sessionID, + userID, + }); + localStorage.setItem("sessionID", sessionID); + } + function handleConnectError(err) { + if (err.message === "invalid username") { + setUser(defaultUser); + } + } + function addNewUser(user) { + let newList = [...allUsers]; + newList.push(user); + newList = newList.sort((a, b) => { + if (a.self) return -1; + if (b.self) return 1; + if (a.username < b.username) return -1; + return a.username > b.username ? 1 : 0; + }); + setAllUsers(newList); + } + function removeUser(userID) { + let newList = allUsers.filter((au) => au.userID !== userID); + setAllUsers([...newList]); + } + function updateWithMessages({ from, to, content }) { + for (let i = 0; i < allUsers.length; i++) { + const user = allUsers[i]; + if (user.userID === from) { + user.messages.push({ + from, + to, + content, + }); + } + if (user.userID === to) { + user.messages.push({ + from, + to, + content, + }); + } + } + + setAllUsers([...allUsers]); + if (new Set([from, to]).has(selectedUser?.userID)) { + setCurrentChatMsg( + allUsers.filter((u) => u.userID === selectedUser?.userID)[0] + .messages + ); + } + } + if (!socket.auth) { + socket.auth = { username: user.username }; + } + socket.connect(); + socket.on("connect_error", handleConnectError); + socket.on("users", getAllUsers); + socket.on("session", setSession); + socket.on("user connected", addNewUser); + socket.on("user disconnected", removeUser); + socket.on("private message", updateWithMessages); + return () => { + socket.off("connect_error", handleConnectError); + socket.off("users", getAllUsers); + socket.off("session", setSession); + socket.off("user connected", addNewUser); + socket.off("user disconnected", removeUser); + socket.off("private message", updateWithMessages); + }; + } + }, [user.isLoggedIn, allUsers.length]); + + return ( + <> + <div className="app-container"> + {user.isLoggedIn ? ( + <Chat + currentUser={user} + users={allUsers} + selectedUser={selectedUser} + setSelectedUser={setSelectedUser} + currentChat={currentChatMsg} + setCurrentChat={setCurrentChatMsg} + /> + ) : ( + <SignIn onSignIn={onSignIn} /> + )} + </div> + </> + ); +} + +export default App; diff --git a/examples/react-private-messaging/src/Chat.jsx b/examples/react-private-messaging/src/Chat.jsx new file mode 100644 index 0000000000..56d88b58ab --- /dev/null +++ b/examples/react-private-messaging/src/Chat.jsx @@ -0,0 +1,111 @@ +import "./App.css"; +import { socket } from "./socket"; +import { useState } from "react"; + +export default function Chat({ + currentUser, + users, + selectedUser, + setSelectedUser, + currentChat, + setCurrentChat, +}) { + const [newMsg, setNewMsg] = useState(""); + const handleOnSelectUser = (user) => { + if (user.userID !== currentUser.userID) { + setSelectedUser(user); + setCurrentChat(user.messages); + } + }; + const handleNewMsgKeyDown = (e) => { + if (e.keyCode === 13) { + console.log("socket emit new message"); + const message = { + from: currentUser.userID, + to: selectedUser.userID, + content: newMsg, + }; + socket.emit("private message", message); + selectedUser.messages.push(message); + setSelectedUser(selectedUser); + setNewMsg(""); + } + }; + const renderWhenNoUserOrNoSelectedUser = () => { + let message; + if (users.length === 1) { + message = "Please wait for users to join"; + } else if (selectedUser == null) { + message = "Please select a user to chat with"; + } + return ( + <div + style={{ + textAlign: "center", + }} + > + <h2>{message}</h2> + </div> + ); + }; + + return ( + <div className="chat-container"> + <div className="user-list"> + <h3>Users</h3> + <ul> + {users.map((u) => ( + <li + className={ + "user " + + (selectedUser && selectedUser.userID === u.userID + ? "selected" + : "") + } + onClick={() => handleOnSelectUser(u)} + > + <span className="name">{u.username}</span> + {u.connected ? ( + <span className="status logged-in">●</span> + ) : ( + <span className="status logged-off">●</span> + )} + {u.userID === currentUser.userID && <span> (You)</span>} + </li> + ))} + </ul> + </div> + <div className="chat-window"> + {users.length === 1 || selectedUser == null ? ( + renderWhenNoUserOrNoSelectedUser() + ) : ( + <> + <ul className="chat-messages"> + {currentChat.length > 0 && + currentChat.map((m) => ( + <li + className={ + "message " + + (m.from === currentUser.userID ? "sent" : "received") + } + > + <div className="wrapper"> + <span>{m.content}</span> + </div> + </li> + ))} + </ul> + <input + className="chat-input" + type="text" + placeholder="begin your chat" + value={newMsg} + onChange={(e) => setNewMsg(e.target.value)} + onKeyDown={handleNewMsgKeyDown} + /> + </> + )} + </div> + </div> + ); +} diff --git a/examples/react-private-messaging/src/SignIn.jsx b/examples/react-private-messaging/src/SignIn.jsx new file mode 100644 index 0000000000..4b5c2a9e70 --- /dev/null +++ b/examples/react-private-messaging/src/SignIn.jsx @@ -0,0 +1,91 @@ +import { + Avatar, + Box, + Button, + Checkbox, + Container, + CssBaseline, + FormControlLabel, + Grid, + Link, + Typography, + TextField, +} from "@mui/material"; +import FaceIcon from "@mui/icons-material/Face"; +import { useState } from "react"; +import "./App.css"; + +{ + /* <Container component={"main"} maxWidth="xs"> + <CssBaseline /> + <Box + sx={{ + marginTop: 8, + display: "flex", + flexDirection: "column", + alignItems: "center", + }} + > + <Avatar sx={{ m: 1, bgcolor: "secondary.main" }}> + <FaceIcon /> + </Avatar> + <Typography component="h1" variant="h5"> + Sign in + </Typography> + <Box component="form" onSubmit={handleSubmit} noValidate sx={{ mt: 1 }}> + <TextField + margin="normal" + required + fullWidth + id="username" + label="Username" + name="username" + autoFocus + onChange={(e) => setUsername(e.target.value)} + /> + + <Button + type="submit" + fullWidth + variant="contained" + sx={{ mt: 3, mb: 2 }} + > + Sign In + </Button> + </Box> + </Box> + </Container> */ +} + +export default function SignIn({ onSignIn }) { + const [username, setUsername] = useState(); + const handleSubmit = (e) => { + e.preventDefault(); + if (username && username.length > 3) { + onSignIn(username); + } + }; + + return ( + <div className="paper-container"> + <div className="paper"> + <h3 className="paper-header">Sign In</h3> + <form className="column-form" onSubmit={handleSubmit}> + <input + onChange={(e) => setUsername(e.target.value)} + className="formgroup-input" + id="username" + name="username" + type="text" + placeholder="Username" + required + /> + <span></span> + <button type="submit" className="formgroup-button"> + Register + </button> + </form> + </div> + </div> + ); +} diff --git a/examples/react-private-messaging/src/main.jsx b/examples/react-private-messaging/src/main.jsx new file mode 100644 index 0000000000..569fdf2fdd --- /dev/null +++ b/examples/react-private-messaging/src/main.jsx @@ -0,0 +1,9 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App.jsx"; + +ReactDOM.createRoot(document.getElementById("root")).render( + <React.StrictMode> + <App /> + </React.StrictMode> +); diff --git a/examples/react-private-messaging/src/socket.js b/examples/react-private-messaging/src/socket.js new file mode 100644 index 0000000000..5740208aeb --- /dev/null +++ b/examples/react-private-messaging/src/socket.js @@ -0,0 +1,10 @@ +import { io } from "socket.io-client"; + +const URL = + process.env.NODE_ENV === "production" ? undefined : "http://localhost:3000"; + +export const socket = io(URL, { + ackTimeout: 5000, + autoConnect: false, + retries: 3, +}); diff --git a/examples/react-private-messaging/vite.config.js b/examples/react-private-messaging/vite.config.js new file mode 100644 index 0000000000..8d70a422da --- /dev/null +++ b/examples/react-private-messaging/vite.config.js @@ -0,0 +1,10 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + server: { + port: 8080, + }, +}); From b1de41c88d1be948544e8fa2be4e870269a3fe12 Mon Sep 17 00:00:00 2001 From: qi <qi.c.zhang@outlook.com> Date: Fri, 22 Dec 2023 22:35:05 -0500 Subject: [PATCH 2/2] Added image for illustration and remove retries until offsets are implemented --- examples/react-private-messaging/README.md | 3 +++ examples/react-private-messaging/image.png | Bin 0 -> 90443 bytes examples/react-private-messaging/src/socket.js | 3 +-- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 examples/react-private-messaging/image.png diff --git a/examples/react-private-messaging/README.md b/examples/react-private-messaging/README.md index ac80695fc4..d8ac0bd0d6 100644 --- a/examples/react-private-messaging/README.md +++ b/examples/react-private-messaging/README.md @@ -18,3 +18,6 @@ npm install npm start ``` +Here's what the interface looks like + + diff --git a/examples/react-private-messaging/image.png b/examples/react-private-messaging/image.png new file mode 100644 index 0000000000000000000000000000000000000000..124e43934e896b2d63b4da921ff74f6e7c44e5ae GIT binary patch literal 90443 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%0D-^bi9xuqz~# z^Ejyr(>D37H{lv%p(;8>SFOpcIRA?A(Sm??P#VOjj@!FOAZEIubL3Q`hgkV(<MP}~ za^5Td!FAJ7)95C2BB*JGpO=cL@oYx&O%+)sJ~Vm2ka!bNS8GZxl~1?{S1*vpN4%|B zq?M|6F}*E*3YM0|O`~HaH}~3CW*~B0*qG<?X{Gf;asy=^41yQiy*qX#kA$)j;>rOO zJo;fiPGAiPS*18$k&3}<lh1$zl8<--d+sexjfmtwf}3P`*7uMR_8f!!`mWv!uTVl) z>(*qYahh*=X}d;|Y)xSNzcgggwmOxk&=nx3PXSNavZOh$XPprzj4g#TV@Sn0op9C9 zU^toPgK&RMjrO`<ZQuu(03<Oi>aHnVYXkPysmSFb?pnK;PDybg@~0tkimi`iS8%=k z3i#f30wS)B=&xZNLeX2`A9?@4@1$%wk%UZLBn{Z6;@`m)L43AXod(cp13UY@lAeK) zKsG&s0{X4nS)pbZRKZy;-3mC#d9FjH#@I+Br6av62`c~Ot@m7?iZ(f#iLVR^Xqx>a zDG_?qp6H524cSUjGn5DH0XjV(pF@WLPOAMR@DPN!+~<d9;|b;>J+<JpkHQ=V6B=+a z)9`kZHQ%}nSyfuT6YT0b47!&Q9417oD~<<7FvJmoM>+ik-}8m2FWoouENG)lFOYix zaY+C+THs+qKRh6!2!N{azG1I0a>(V8O^w!^^-$;qH?(~e!hdWavsy=D_Au($y}8y2 z#qqFDVZTfp^AFUPWkA0IP?*cD3cT0{^;7|$p9wzI>Ij%3Q$Ug!YRtN-y-Lv6E}?Gl zs`3yjx9or*ZS$jN^6O3=4X&RvKOiIChi`BXM0vPWU1!W@U3Q~y>bzuVj?NaEQP4S0 zu5(a-Ar;wkT8|RHQ228}ox$fniz~$WbX?n%6G$k}0^LoBYg29<Csp39bHf9>`I4r^ z`4Z8*{E7kz-)tOR6KFF;y$@KGOt<;QY4c00|Lt=-;{CL(SA=5rnW=z2i7TLrOwk1! z!z8?NZGrowdG_FYlVZh%#a4s^wTb?)dp&&P@a>IJk?<M*I33prM4;TA9$EWk04#p7 z#ic55_{9oxF4e!njoCSJ{|m+qC!d^_f!xbBDvB4H{-U|Mkq_T}<H@@x@`oMj!R1Jp z@1?YH_mk!MtP=rY^x~BuwKYxRshA%-)6ni*%A#&FcZe@87BHRTKMbC17k2o(uAQI1 zd2EFWoM0lzrm1M7k4i=3m^Q!h{r^yr9-MUxPYE(VsxlmEgcNjlHCD>G{1Hlf_({2v zbRbARqaf{El6&0_0RoYG1f1RpZdXFpm}-5&M&k2hXl=|Pw|^ohzN$AMzAhC!^G0mW z)S^NbQ{6Kc%(gHUgCnExkFc9jfuH|);TplKH)NHk4z<)5x!ZAMXAf9}6~z;D{3qDE zp~ES2ssT_#$;Ne8RU5>{j8dHXrV>*(ml?@-ADv_R^@pUO^SC>T4U<Oy-T<@smyO=K zS~nz*Qcx=(Ihi`uWik)D+r6H?yIuvrE`9*u!@;u@gv^Rq>2h>RTkBk^w`PpItbsCm z#8xf5S84G~YC!ihdw|$(c_~!Og5RYb6L@r?VKo>`6n|ybP6*Tt#?OI`1S4MaXoJ5` zO{rsTijdHbcCxAxc<=qMFl{GP&Ajv<<tuL>UOCmnU(`EL<MVsCN8nCORX{tPk27io z<@g2hBcSN>diObLROFwyVk9(_i*h&^)u&da0}k`Ivv~465sJ!%N*5xl$r0$N=_%S( zAOP%3eYE&Ohl*7}9LvVldIr5Iqd!iBbTkgzsx_@(c9y~dX#pL&&<(idhiel7O>e<D zQW=SPQ!`;&pjrEHju>B?8p9;@yBr2nLkob)uF7C)knsiJl~PTkv8ldrI=-`Tr;z!2 zFT2h#8i=p^CvQ)w2-Jv8;@PmJ-~ES?$GJ9~Zb74oBSP{ExUuuk#-pvviH;vyomeJU zqVnXe_b}j4mU?IY)Z|CRODc?jZnPA0GkenDYE(qXYg$e8$$ZVdGH6?J$qO(JU8+w7 zIs$8+D@88N0ksiuRR?Qy*s5=Pe=J#MMDT}YQ3j<*EO%1w_J`2WE~M?sdNM9vo;&BJ z6ToE`nf_qa)JcgtruiyZ3s+kV|9MFIB;GWu%j7e2vtVn#!hkSmlJspoY^a=`8HpBi zDYR{bxKO~KUp=D@2treH2isy?;W*~r+QiN^sP?Jt>3m<HMnK>|pK4Dt&!YifqnJxg z<f%nFR0_Kc8e@2uJo}ggvO#K>J7tv7yE=#tXpf&{i~IW~?<>AHqG%N)#2n&`S?b6{ z**Rx-v*ReN;=--XY}F69V{yfie^%8uNHTU5veaF(pZ#4;-9dogTbt6kCg><f&`o_l z>MbkR^5_JWc_b<D)S_m&uckNshD4@e)D+kLfTr^umeGTCuxYoU&d?<z<8vIqI;Q67 z9*JU<$i-O`kQ_fK|C+Bf<2qv6ES{NB0>8i|1HM-?mwtVVjzIMjAPK(*o%E3PEgU=b zkt;S*h*J|2)C=70`i*Y{1j`BI@JztTX5p_dHB`WIk@M`ui0;g8YIV%0!~ztqhwd@9 z8|z6noESRxO-<j(q~3d?JFcLCAJBweVuS2__M9ewO-Fy&{lA{le-;PjNtyeno`@46 z>h>^vC6u7{r+E5HompR^Nu{TfN*IA)zIqWv)&>VD`kTdES@de_o~DHti@Rtz-olOj z?!{GCjHe&J7(6jT321mL5gDN~xEXZZFtazd-!l^hxH%oc&E8#OdT_3wz-MDKdNN!= zz?3nDq`YowW!#e4b~m!=ORNam<GqKr9%R|$N&eJ*Dl6dRN)=j9{N5Ki1Bl&P;sU$* zSwj#xX{ZIAoCqnMbqh^Nj5?dWx3xdNq-k^-Ux^{JnN*WAu68dP=P3$1qUf1mU=d5i zUvxP@J#<Kemi*!oA9iJG2}3{1<ZPY%)s*?4+z28=1K5UV0=u$oew_>tezs77!?x`> zQ>#>`BqQWp0Z4IsNd!#Hmr7QGgA&bA+^~)*(8qZz#N51cHf@E252J#VFA-eb<)4b` zL%g3`lOkjDYsjMxroXV`vYDge%DCQET(s9wPKoGY7he^Ot&uND9*b_1@#|RzB4M-< z>@;X?Q!(8fIOc9<S^rCM>vgS*Q3UagS{nV`<eheuOcDYOcx#NTt06s73}?)b+bU!g z9weg<w95(UJlG$;(@R5|m9_qB`TY(%+$c@c4)*nBWn4bcbPW!uC3Y&017_*0@>MfY zC<B-<3NU3?r9N^Y)j+#$muxh*{tu&h*uO{f|MqC^A!^9v?fQ6G8j%uHL_ef`x&gk< zn*bXb-Um3_KnEGuHUN2+BNy0BvO)y(P=nxtSlg!MbuM?{tup;8iN-BH!MJ7&M6lfg zUwPSh=4&sC?svBvS|lTZ<K!>-S&k;}OUz2Wd-@3pyriTmiBZ084nqmx;H9A5Lx`#> z^I0GO9i+4fXJm5iKxEYGQKmMK<b_dBpvM!K@+)=iV;s->A=&z}x=l}k8o)Uth zqqSYeL){NnKa$!nC)PK?6_3^EjHpuS{GB1;96-!s)u-+^s$GaojWiczz>?(FlcEt- zv#bCM6$7cB*z&w8I?<3*vd0^g;WyKUE^@vOP<@81?&`R3SP-sA9PuK~gq0pcV#;LR zFT=<3??$CyK9KOra8QYvMzL3wjR6+@b~BEVqg2<lCW;svt50?a=s8T^SFg${TQmnl z?Ry;70;RbRos7wXA)wkHOwX9y68_4MJkaeD!wk&Ko8nKoG@<R`+$s`N3#>KM-uyVA z*ys8FT%>U{Ih8<GbrK7%0?uaA@y}%?w*s7Z$viL%{1^$V#?pFAsjPdcKMi+*){S{A zySz$p`&dPD$c*$Fp$~n|AX>SSW{+U@VM1yj#0f3CAx{AezTj3fHuHxV@uJs$=+f>_ zeI+zROyIr@%?xl|wnAgVZ{*OnpI3ezg}vEh8#fBML3=Z``W<C-v7$&a7BV1X>VFgO z)k3ngf-|Zc>KszwP65;DG;Mz5uU6<CK(?*~JiDv|Jg}68P6!$W0&f3q==yjm{GR@= z?AtN_R?+_lRP;;088vkbk#(FjRlD5Dc(u#}8avEh+X%aXDCePok!-)5T;3K#=d&Xp z(Q4*Zc`Nj}T((7eM`24wA*xJA2K{1=mkp(a<~#=@UxN=<&;4RV-e1D>>B+ZU^oJuc zArx<8z!Iinz3=yK5LjdGv}YC4qSnAA@1|d*Is<|9cK~$%nz!o`&ey;V@E%xfO&k%+ zJ%5zL{hgjL-0!xdZ!BbJVtTgfLdPXTR#Xa(>w#eSWLe1})QZhTv&+*n<oqL`X+}>9 zJU2e9Wh4uj1b`?X+xD<p|1!2+4)LhU%0yeBWK!CCIi)qIZZO@#Xh%)utkzc!S93cA zCZ~6h5A}Koe<vGV8RvlnCIRL?0G>V=WWpZOZ_@8Q?e9@y6a4_|LqpsoQHVEPxhE+T z)`zJB?u);M02Ll&M2pXBZ?{j@#Msh6K(5D6nQkwh0sf%vu5t6uJ39FvSYPu!IWb`h zBqes7TN_|&f`D2Z1=QNfg^+2cr6A(|2SV##CP3M9^mV5~7rt<bhgP`61Ps=s7!I;0 z^-)=P^qWGNDd3~3Ux>^Wq)lxtpO-c47OTIi|Ml>yllSAX`>iunb*sMc=*x&ZteY{` zZKj1vt<xXol_vs&(_$UrU?Px%RluV+&>9J#m;!OqK4SUxR)7lk)#w1iFx0=Mgmk!* zb1oas5*weC`HnX8zj9Pz$zX4ZW;#PF_*`L)D`YQ-!xsaYLX{_CBIGi8`SgF1$7B92 zkN=O!<5WXQ9y%T7ZpLzY^52}UagO;-)4x3eMgvUP6c)3<d|F_&UV9p+*eHpgx;;e_ zs0|gY2*zs{D3_+BglOZ;)G-5!iAuekXaY)Ntp4nuYBSG)6m_p`+m(<f&Wiw}W{GKX zHGFJF^>90o!wlS;Udr%x-qhoUm@h_AnVB*t(u+&E_Fuu%e1R{ep~9`j75h`8+F2pc z1L%@F6i}~nWbTl3yq4WF`eRH^I}A8FWU>b(_tKS+bU>d2B`U}0qFsKI&w}UB2cZ}b zhvPd#wH`{vkxtEGs}A&;NUI@w9m$FxESr(ka$65a4JNYTG37<=l;IbIi~U?+4UvyZ z<I#s)^vNIjt0NIYYYU<84sY~f1-WBHP;l0Y{OLSTvn$RG_$V5OTN{GtEZqV;xEuhQ zUg@1|pvF{d_y7#ws!1ZZR^yPse+0&wi&>%W>efIK-MsKNI0jO38^<hJMDNFQOrHXa z*A#HT78_t6fnMGDsWapRn_d&Vr%nB_=ti*Si~8f#c<M<67}3{?{6c#{$F{?s&8UXJ zeXQ4x3#l*b>&!25&Xb;XDrYf%S9#pKOD4-sDfX;b!k9AT{T9p-1LGD?sELb;qki{$ zMe}vSz;u3pD==r~q<Ft$nR7_Gh@`bCy|?Ayz2wqPeq$~Rub$zK+cZAOL@)AiQDAot zRjbLEVaom$TZmOB`X_)108Pag3h6k46H1c}ER6l7wmF64f7O^TTbk8<LJp+51>g`* z*!56qguvS>D>F=krL@cZLPWeOv!SJw5`;zQ7uM%Aw3aALkYv|@ZB4JGgmw77&;XMa zbi;9dy=vsdg7`kIG2-Y^&ZUsgg>|Uhaf!;L;{G96tdct1iGRvFDh5=mqy2kcn4grj zmEP$U1I`c1dihEdGSpggzJVeOuAQ=ov^+Fcw`2I}jH!FKNjqt^_!~U1M>~b-2uZAT zne7eUQ(K+Sp7r&smJ>8KE{Xrl4$7ICfvP%W;)<=OeFQ6a^^nI70Q19Znd=z%XdXnb zg;Nc*K}nX&S9=cE$Cq7QMV%DN2;Er|@L3l#z+1;$g72e`lYn5;;tK0xb==MG4+DhE ze<^)K5}Rzw-ibXI)FpZrkq6Ffn^=v)TFcwp#u2(c8(k6S3A`Bk3sTGNZq*2&-7wls zfCzEmCE}mDB?NVay`=37&~^{ygaLUg4tH_eNV41!BI^eKmb?Ea<ZijWv$q7s_#jjw zTf^Gye&QE<3rDM=1lZ>yR!D#pbwP2!JrMp$UtqeMm{%oNWMm$%Q86KDjG9)su2v<f zbCvgw&ho5>JS{U?PQaw%r3`b@qV0@+=KjCpy;~+KN7Vy?<3Y#mE5Qn8Is&CL4d+zI zZf1gF#TCN`kW2oRy#4PP`oAx4f0?1HfL+A)uK`-}l_@Cl9$hjTY{Vc6oxkGTBqt?C z<!O5w9ccG{Whio$`L<<doVed&N(OD~5(rMf>NiO_cI^CTCTY>U3ok`exu(wlkhs2b zI|KT$Rkt)KA_dwTBQvWy0j1iVAu(!OqtBF0(p7-6zXT}hC*GduMWuojMcZRh(F0QW zPSHec)hRv_M0PQBXI>W=z9%}W$()j0xu*kILY8lrGrvf_hlsHSt*pk2+(mQ(?p6`? z2W||TD@-xB6kG)|Mr`o=F(rMueAlLWR7M?Xo#e)BY{zSX5g=v7il;8<1<D%@cQGWr zL_SsYPwC0n)s=-xEC+2f`5$fQJS%%a3Gf-GLfs9~`!#?A%1Ij0PZ9TSj5}F1n3qbn zzVwiSqO5Tr|J};X);1LZRQdvBE*LpnqOt+K^_fD}A}Hqq>9;+hT<msFQ#W%zIx*5J zZ>pprXvN2+J5DOZ30&zs6|mN}FHAusUQnX}%vdyfOtA!dIW92?-qtI+tq*QRoL=5P zW&3Tt>JXgc*T?3+YrPNX#$p4q?CV$KH2n$Jz@lSTd$`=Yfles~(f{|PY!E}gP{`Sh z0;c7^N9g}qBl<s&(ELsVpuU{d$Xjmc;OnnoN7W}X_w!yeQ5mxT!8j=yo5uVHCl+lX z_e;o{Z)Kc*z&)%A2*7Ob5`g`74Ou);I}5<TKMQ9C;JO9R_1MsdQ3gHzvhj!d1Y92A zpqy&ocKv&L{=YFjPyg|pyfIGy|J?BGEi0waE(%t%V%hjJ-ZVN9|A-9kbz$}rmCP0w zFaxY+GCaYTIk@lqhrPFCLZ}uyx!lX9)-z-XNP62`-I_*J&)5A#z-6Olcd{_WJ>L+J z3h(Z0RC)Cf_At;!=0Gc^Z@#y_Wn%sEp!NNya4Rw8ft1iJ6LS0Whd3ms6(u(|a69wM zBy+aE#wj>$qmvVtQYgE(kj2mIyb;D=C}gfU+S({&3{oHRNmB!t6f%07Zv8`Dku!b3 zY`c-j_8H+67bbYH_6l~2>u}j~MUKcuxgljda@BcyeA#a$wf6xCqCW=rpz=owVcw0f z$RlRK=QD-2qWi>oaN7}Rw3%QK_**0*SWd!__L*4V1z}yqg9M-{s7@}(?)B{(rvdf7 zYJMWhvkzeaOrgi><NvzrCBNe_c?`bikn}q?apxFpD0O)>xk~bDWOvAWj_Mn|kZ|@B zG508KlF?&eqfQc4ftyNJ3rAX94Q#cu7;<!-TDI;XZ_4O?Y1t2;9dN@^B}_YP{L!I3 zyPrrRuFY`MfXO)un|EwQ#6|9tZcLHjT3xCl%p~*vV;$hW9{~x7<>tw+$|K*5Ouwi~ znv~)7-#oF{@s>f#v3r=kuT9z|H^!s;MUv0AFSG)ezIui=xHKxa+V(rc`w84<-iwlT zjhcI%R<vAtM>Bg;-lc1_+=dJzaf_DgsD)X4m+R3t3uSlY*vKV^C=Vu3knpL#)ayw? zt10G`X#Y`;N690v<#igiXHwJU1MB1wg;1mWv9^e!fKoaV;(2HW^sio~mkW|;bcJE> z!v1`58;kly{aQ_otxnxJC;_U~w1~DdQz=xO^Ti3guiYh>G2eOtmMbXaR^{VTP<=5* z58vUi)ay?7dwEJEW0|Y;b}Z0z>n$w>^`rxSx`NYRZZfR6Ndds98-;2epk+KLpPg{U z55COgQK0py9x!kSdqwUz#EBs{s9j-UZbiaSI1(HX8S`qgkH;x*a#QP-pzTe&v*x5o z&V_#M(>J$APKXi0ADey{_;F2W$yBmI)j&((Lz8B5`jTqiy1k};><gRBcKKj#R%bkq zJdi_$Dva>L7}#2qT>&hbd-`$Sl*`<=XU%Q|es^ro9-omXxQ9WVwDWdo@1_XveUt3? zIPBLgzb_sdFh1MEE=<#J(1SCFKJ$KzZ-O)o5cAJ>?LMePiC%qYztQvbg#D?{(|u6{ z_CORJD6kU^xywHf-M(;Mo2;0j*|>f{V6fj!F-xI;xxQHfrs<4r*4|X`NbQUWuMYnX z<+@SbTN69ezOGx-6EwM|%JQXg3R7!H!_#&IIZw-7R?XEriwrk9TNh>FOElW~ah}G% zfcJ;g@h)3?qBV@*zq`C{QM<U|V0Zhv46O}ovlPNon8|L;<#)Me>y>Hqj&>a)h1p;B zL6`malASz#-j)%Uk2E|YD0CiPm%<|*bvW4IwYClR=G~{APuI5fkG@LBq}cRxyhg6J z1u5|AzP){5XWf8CiDHLp1+qhAeQJ$m7-u8dAd|N_3_sF`_Ven#ur7mpGdb5SqF?#K z9iM@Zxe-cRze3)e9;5B!`7PXeUTKb9>tnrb(!hU%k#x09L|>C;@5UviuF2|kALp5l zI5lh2_(8kW^w%10IU9`NuPwm$Lh#RbM{n>`+=Rj%p=>xacpJSdzlQwgCB$DtFWMRG zRq;`>kI36#RGVPOvnwhjkb2B7FR0BpkWq@Jn>C)U_mONmb8`#z_9*DtW@ojl(Q`n4 zj<|N^lerHjCjZ6y5;!u6HQvt0U+oZmd*TxRg3zJMA8$K?pHN!c7FDp?WHu3Y#e2Df zs-?+o*nZbb+|+h^%#w1a*&2Q<M_7D>@0wlP4!zi_N331jrqXFdN)U+e-;CH-)q3`I zNX(2wF6NP^Szi<P%_DH;AyPpxF`c8(@Ei7TkjMKV@^iv-!UiMqSGV__A1Kp&bzvaV z(vNs`#BgWZqy0SPgRS5o_jJBa$K5)8@$9h1Tm%&gh->oP3JI1XRyFn_^7}Hgr=2u= zX@rqb<qSlw)U56*R<kTq$ui#6S~;U;cI$=Z{h=wU^~1X}c{l4%(A8-Uc8AsO2s|!T z4D6g;U-0{Of3J!x!RgDtXqW^kq;Ao`Gbiie4wMXo*Vi^Eoz*m|J-EJ2^veTOxUwIf z8K`DXbqRKFug<=d47)`8^aw-;SFQB;*VVV5TV*8}KVdsbC_lD6!rslZyn3)!5Pf-h zLR>i5Rk}|?n@61!FY5#vLgv!F`s=f(>}{n!m^J0O$qJ!&%0c$Lxn_NSu{BNhg0oxC zs-s5Kb0u5u%$L4-u*+C%AJ~+d;B`k-Fxo`B=~Ix74k3Kld28bQ#Vxbn9=|oA{KU77 zGv?e+jgKfdrYL8?ZobX^*}T$t{zImN;-;ouvtgrzljQ;^Xld+~f6&MGAB(`I(`{<I z%4820{bZr^RQJMdpQNi-$AfxkX{)<woxuZ(s=JfCmC>91)-I`z>!xXC^jZf;aJ{_{ zZk(-PW8eo)HGNbYNDpMJBEH!hecgR<p??PK*RJpCzOm`P!B_>YZNskeT+MBC)gKH4 zmjDzsF5ru%cHi>C`4pwUnb*=J{<QUu&nQ>v)2o}&&AwS^sBGs5*R>4ueaf2htoFVR z#eIrx#Zr|&Z&VT^RR+&UCG>vMex60ant;*usPP-wqq^8bb*q>?-iZ^c{&Azx_KIyM z!)DeUmu^XtrB;Vxb@WAOmqy0mCRD)O@>FC+xqkmE&koVo=+))m<3rP93C|+mU?X}P zj1cNZ+&2zu1Pv7^HpXVZsm-O1pUw9SL<~ym8uQG8*(A@7=zUJJUdOR-+81<XK@G~o zr867ORM}eFwVf=cDB&_MLoHl%vu6=ch&;(^^UBY#=%<$L=P6X^%?71eh$)P8mgTMI zyZsR#Z|qSs!rE57#v`wI6Ot`L*PaTpe(iSGj($<&5IX{=<^_x8DLk|=Sx(Kh_L&~O zKEez)Gdk<FS5_YTH`WVc_Va$`-4<vau)Di8V|oACwO1nCZ)LCvOhIn*Vlt(nENt0m z*qEzsM88$KH*l#b8|2uMQ{HzzN}6pEuXhdUucIQ&;;Oh?oYrCDZ9#^?H=pzB-(s;I zT#Ekj<9ttF6Z2_=A7ts8AEItHK8>)Q_FP#F@(<rjDJ9)ddldO9GUxNeSJVW>y^{O7 zO0*XjRa<Y=MEhtQnqOrWv-fe%ZlBO*9F`T~xGz3SSSZnv{z$0EPv7G75o35Po_H1S zRn*K_Q~(Dqa4jR<Fctl2Gx>Gr!9DQC2+|rsolSqx(gGJ0B$ZRnX-K1M8s2oUfQJh0 zH(8jiu6Xfy0K*^u0R_c1O7|Q>>!(Ej*qvd)6WJW!^oJ&HN%cs{`Jc9p6Bu=+5>Z#! zpm6Yp(9UGJBBXVF4k340efz46-;3n6s+ROO1=YQZWl(y-^4jk0C`#=WdfV;#)r-m* z*c+#?BQY<7BF3AZ!NhFnt97?RGoqrSbIt|X1(`sr3H2Z*lsez;k%h#~{)8Y)+)F6p zVlw>q+qrH7FO3((xwj^|$+11Hq@&hYTxi+wg+1qZ?<!iN!gWhGR_uvpln=P>vx;&5 zt}QVjE;>G=CLqqzIS5T}4w8NcqW3Or-&CqFRrE{5AlNsTAeD@5cp=XOCEZHB9Te4g z&<2z@<jvc!b@wS}nBFZK=IaQ**{jx8AJSudD|71Wk-z0-Ds`*I3S*A&SxS|Lvd-Pa zD3%{Mt)d&vI6vrmT)f8N<fj3`CbXVoKPSFkP;Y8=)%s$Ni@M3hxVjT<aq79t3*5J6 z$GLOR3o~3+LclOzVC+MR2`zL}oLPrh)(!pnxXY_=JGb}CLWZzgp@@(_Rl$b;VR&&n zMMJo+=M(&4`QfU;QpBq|rcK#|3S4#GnwT{PvRJu}hb`Jyy94}X%*gn~*K-}Z*SS&a zGSFA<Of+;b+G%~Dl}i7>SGbw#5fPCWYF^<NJaZtW&?1D{74NV3QCZCM*C;hr*$<3C zNtT%9E?37@A;F*A!M~_`<MCJaX;<u8SaV(Fdf$mSkb2T5Z!YHuG<^T2?R|%G=IeVY z!-mRdRX{Jde7il3ksvz;Z#?CJ+f!zgNee&2>DB~pbFW8;o8j4ZsM@OsEvs~TE-<bj zO*@Kr>ehsV(KUJ6ApY>&@|!MIqYZk)ZKdt6ieN^QjD1FIyslusQ~}+Cx7#ee7xx;) zlnukL1<aAkZD}p-DBYL~=@+lQwXgVg-Jt$>P<5z#cJxsDdkv33f5bBL#>C|&9;^-i z>*<HTtw!zEWE-B~y~|x*9p3)quGV@&$zY{%dw|o&Rc*xvZ}!b@75Uw~TCwh+=c_<{ z2iQZ6>E%`Rn==^tHticNt(x+#3IgBaa(DXoD_acrUQBOP2v$Ib`;P?4kj;h5dY_0k zp<6*GQM~B-aHZGf&>w82x>&2$a>Nq<JJ>57(W);#zZ%sJE30vn?l^HN-wd|52GJqw zcuBevo9zmqSMA=2Ph0IxQuT^)U1@m2#%oi1$Dbi?-`?_@gHq2Igy*GrXEk$G!}6;# z-V6XP2iFHg)OvVyh!l_iJWe6I?QPXjT&tg&b~x-Lrt1^ar@+IcVzN*DOUJo*_NK># zP%mr(@72!|;Bt&%yD0gwYYhBBt7^T8RXqJVjbZ5z7eYZGBJMddBeFmw;qv|g$(FUB z+@7(V(JfSHE9un4f4DYsS%%4)lsB0B%kc7smZ}f)tM_lZW(5B=&arCMa!@hFUP$xN z_ky{#cj^lw{6GuQTj#!iT4~q1C%)cmTP>|~HDenX(fFCRlgcGCpO1w%1GFShW1kT$ z26<;NbHeu4gw>ODEhgG^{m;X0pmpE<IVVD;{$f*To*9RdHBpJAzkCmoH0FM5MU_4> z{gZIr@+O+BSaRUhX?!mZ>onwI4MQ<|C_>fcUF!x(nM*(T9y&7;B7-a@dwe9T+HbG% zBAA9DuLX@-(vRd2J-lxSRb5j+1K-lKE#h^jUO`gXTRph<xr_&cF%v6r53C|!i&O%^ acDKgv*bCX_%RXpy<dEaRvI7@?|9=3h|A6}d literal 0 HcmV?d00001 diff --git a/examples/react-private-messaging/src/socket.js b/examples/react-private-messaging/src/socket.js index 5740208aeb..e7b6c920a2 100644 --- a/examples/react-private-messaging/src/socket.js +++ b/examples/react-private-messaging/src/socket.js @@ -5,6 +5,5 @@ const URL = export const socket = io(URL, { ackTimeout: 5000, - autoConnect: false, - retries: 3, + autoConnect: false, });