diff --git a/nginx.conf b/nginx.conf index a83844e..d3751d3 100644 --- a/nginx.conf +++ b/nginx.conf @@ -21,4 +21,6 @@ proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 86400; + proxy_send_timeout 86400; } diff --git a/server.js b/server.js index 1bac2de..74ebb87 100644 --- a/server.js +++ b/server.js @@ -33,7 +33,13 @@ wss.on('connection', (ws) => { console.log('Client connected'); ws.on('message', (message) => { - console.log('Received:', Buffer.from(message).toString()); + const msg = Buffer.from(message).toString(); + if (msg === '{"type":"ping"}') { + // Respond to ping to keep connection alive + ws.send(JSON.stringify({ type: 'pong' })); + } else { + console.log('Received:', msg); + } }); ws.on('error', (error) => { diff --git a/src/App.js b/src/App.js index 036c244..0c0fd29 100644 --- a/src/App.js +++ b/src/App.js @@ -1,20 +1,26 @@ -import React, { useState, useEffect } from 'react'; +import React from 'react'; -function App() { - const [counter, setCounter] = useState(0); - const [ws, setWs] = useState(null); +class App extends React.Component { + constructor(props) { + super(props); + this.state = { + counter: 0, + ws: null, + }; + this.pingInterval = null; + } - useEffect(() => { + componentDidMount() { // Fetch initial counter value fetch('/api/counter') .then(response => response.json()) - .then(data => setCounter(data.value)) + .then(data => this.setState({ counter: data.value })) .catch(error => console.error('Error fetching counter:', error)); // Connect to WebSocket - use dynamic URL based on current location const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const websocket = new WebSocket(`${protocol}//${window.location.host}/counter-ws`); - setWs(websocket); + this.setState({ ws: websocket }); websocket.onopen = () => { console.log('WebSocket connected'); @@ -27,7 +33,10 @@ function App() { websocket.onmessage = (event) => { const data = JSON.parse(event.data); if (data.type === 'counter-update') { - setCounter(data.value); + this.setState({ counter: data.value }); + } else if (data.type === 'pong') { + // Pong received, connection is alive + console.log('Pong received'); } }; @@ -35,36 +44,50 @@ function App() { console.log('WebSocket disconnected', 'Code:', event.code, 'Reason:', event.reason); }; - return () => { - websocket.close(); - }; - }, []); + // Send ping every 30 seconds to keep connection alive + this.pingInterval = setInterval(() => { + if (websocket.readyState === WebSocket.OPEN) { + websocket.send(JSON.stringify({ type: 'ping' })); + } + }, 30000); + } - const incrementCounter = () => { + componentWillUnmount() { + if (this.pingInterval) { + clearInterval(this.pingInterval); + } + if (this.state.ws) { + this.state.ws.close(); + } + } + + incrementCounter = () => { fetch('/api/counter/increment', { method: 'POST', }) .then(response => response.json()) .then(data => { - setCounter(data.value); + this.setState({ counter: data.value }); // Broadcast update via WebSocket - if (ws && ws.readyState === WebSocket.OPEN) { - ws.send(JSON.stringify({ type: 'counter-update', value: data.value })); + if (this.state.ws && this.state.ws.readyState === WebSocket.OPEN) { + this.state.ws.send(JSON.stringify({ type: 'counter-update', value: data.value })); } }) .catch(error => console.error('Error incrementing counter:', error)); }; - return ( -
Open this page in multiple tabs to see real-time syncing!
-Open this page in multiple tabs to see real-time syncing!
+