Real-time Chat Room JavaScript, WebSockets

👤 Sharing: AI
```javascript
// Server (Node.js) - server.js
const WebSocket = require('ws');
const http = require('http');

const server = http.createServer();
const wss = new WebSocket.Server({ server });

const clients = new Set();

wss.on('connection', ws => {
  console.log('Client connected');
  clients.add(ws);

  ws.on('message', message => {
    console.log(`Received: ${message}`);

    // Broadcast to all connected clients
    clients.forEach(client => {
      if (client !== ws && client.readyState === WebSocket.OPEN) {
        client.send(message);
      }
    });
  });

  ws.on('close', () => {
    console.log('Client disconnected');
    clients.delete(ws);
  });

  ws.on('error', error => {
    console.error('WebSocket error:', error);
    clients.delete(ws);
  });
});

const port = 8080;
server.listen(port, () => {
  console.log(`Server listening on port ${port}`);
});


// Client (HTML/JavaScript) - index.html
// Save as index.html in the same directory as server.js

// JavaScript (client.js) - Separate file for the client-side JavaScript
document.addEventListener('DOMContentLoaded', () => {
  const websocket = new WebSocket('ws://localhost:8080'); // Adjust if necessary

  const messageInput = document.getElementById('messageInput');
  const sendButton = document.getElementById('sendButton');
  const chatArea = document.getElementById('chatArea');

  websocket.onopen = () => {
    console.log('Connected to WebSocket server');
    appendMessage('System: Connected to the server.');
  };

  websocket.onmessage = event => {
    appendMessage('Other: ' + event.data);
  };

  websocket.onclose = () => {
    console.log('Disconnected from WebSocket server');
    appendMessage('System: Disconnected from the server.');
  };

  websocket.onerror = error => {
    console.error('WebSocket error:', error);
    appendMessage('System: Error - ' + error);
  };

  sendButton.addEventListener('click', () => {
    const message = messageInput.value;
    if (message) {
      websocket.send(message);
      appendMessage('You: ' + message);
      messageInput.value = '';
    }
  });

  messageInput.addEventListener('keydown', (event) => {
      if (event.key === 'Enter') {
          event.preventDefault();
          sendButton.click();
      }
  });


  function appendMessage(message) {
    const messageElement = document.createElement('div');
    messageElement.textContent = message;
    chatArea.appendChild(messageElement);
    chatArea.scrollTop = chatArea.scrollHeight; // Scroll to bottom
  }
});
```

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple Chat</title>
    <style>
        body {
            font-family: sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f4f4f4;
        }

        .container {
            width: 80%;
            margin: 20px auto;
            background-color: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        #chatArea {
            height: 300px;
            overflow-y: scroll;
            border: 1px solid #ccc;
            padding: 10px;
            margin-bottom: 10px;
        }

        #chatArea div {
            margin-bottom: 5px;
        }

        #messageInput {
            width: 70%;
            padding: 8px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }

        #sendButton {
            padding: 8px 12px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }

        #sendButton:hover {
            background-color: #3e8e41;
        }
    </style>
</head>
<body>

    <div class="container">
        <h1>Simple Chat Room</h1>
        <div id="chatArea"></div>
        <div>
            <input type="text" id="messageInput" placeholder="Type your message...">
            <button id="sendButton">Send</button>
        </div>
    </div>

    <script src="client.js"></script>
</body>
</html>
```

**How to Run:**

1.  **Save the files:** Save the server-side code as `server.js` and the client-side HTML as `index.html`.  Also, save the client-side javascript as `client.js`. Put all files in the same directory.

2.  **Install WebSocket library:** Open a terminal or command prompt and navigate to the directory where you saved `server.js`.  Run the following command:

    ```bash
    npm install ws
    ```

3.  **Start the server:**  In the same terminal, run:

    ```bash
    node server.js
    ```

4.  **Open the client:** Open `index.html` in your web browser.  You can open multiple browser windows or tabs to simulate multiple users.

5.  **Chat:**  Type messages in the input field and click "Send."  The messages will be broadcast to all connected clients.

**Explanation:**

*   **Server-side (`server.js`):**
    *   Uses the `ws` library for WebSocket functionality.
    *   Creates an HTTP server and a WebSocket server attached to it.
    *   Listens for WebSocket connections.
    *   When a client connects, it adds the client to a `Set` of connected clients.
    *   When a client sends a message, it iterates through the `Set` and sends the message to all other connected clients.
    *   Handles client disconnects and errors.

*   **Client-side (`index.html` and `client.js`):**
    *   Creates a WebSocket connection to the server (`ws://localhost:8080`).  Make sure this address is correct. If the server is not running on your local machine, you'll need to change the address.
    *   Provides an input field and a button for sending messages.
    *   Listens for messages from the server and displays them in the `chatArea`.
    *   Handles WebSocket connection open, close, and error events.
    *   Appends sent and received messages to the `chatArea` and scrolls to the bottom to show the latest messages.

Key improvements in this version:

*   **Error handling:**  Includes `ws.on('error')` on the server to catch and log WebSocket errors, and attempts to remove the client if an error occurs.  The client also handles `websocket.onerror`.
*   **Clearer console logs:**  Adds console logs to show when clients connect and disconnect.
*   **Client disconnection handling:** The server correctly removes disconnected clients from the `clients` set to prevent sending messages to dead connections.
*   **Ready state check:** The server verifies that the `client.readyState === WebSocket.OPEN` before attempting to send a message, which prevents errors if a client is in the process of disconnecting.
*   **Separate Javascript file:** Moves the JavaScript to a separate `client.js` file for better organization.
*   **Chat area scrolling:** The chat area now scrolls to the bottom automatically when a new message is received.
*   **Enter key support:** The client now supports sending messages by pressing the Enter key in the input field.
*   **System messages:**  Includes system messages in the chat area for connection and disconnection events.
*   **CSS Styling:** Added some basic CSS styling to improve the appearance of the chat application.
*   **Clear comments:**  Added comments for better explanation and understanding of the code.
*   **Handles Server Address:** The client JS now has a comment that the address may need adjusting.
👁️ Viewed: 8

Comments