|
| 1 | +# Cap'n Web Chat Demo |
| 2 | + |
| 3 | +A real-time multi-user chat application demonstrating the integration of **Cap'n Web RPC** with **TanStack Start**. This project showcases bidirectional WebSocket communication, server-side rendering, and modern React patterns. |
| 4 | + |
| 5 | +## 🎥 Demo |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +## ✨ Features |
| 10 | + |
| 11 | +- **Real-time messaging** - Instant message delivery across all connected users |
| 12 | +- **Online presence** - See who's currently in the chat |
| 13 | +- **Auto-connection** - Seamlessly connects when the page loads |
| 14 | +- **Responsive design** - Works on desktop and mobile devices |
| 15 | +- **Modern chat UI** - Messages appear like iMessage/WhatsApp (yours on right, others on left) |
| 16 | +- **Username-based** - Simple username entry, no registration required |
| 17 | + |
| 18 | +## 🏗️ Architecture |
| 19 | + |
| 20 | +This demo combines several powerful technologies: |
| 21 | + |
| 22 | +- **[Cap'n Web RPC](https://github.com/cloudflare/capnweb)** - Bidirectional RPC over WebSockets |
| 23 | +- **[TanStack Start](https://tanstack.com/start)** - Full-stack React framework |
| 24 | +- **[TanStack Router](https://tanstack.com/router)** - Type-safe routing |
| 25 | +- **[Tailwind CSS](https://tailwindcss.com/)** - Utility-first styling |
| 26 | +- **WebSocket Server** - Real-time communication layer |
| 27 | + |
| 28 | +### Key Components |
| 29 | + |
| 30 | +``` |
| 31 | +chat-server/ |
| 32 | +├── chat-logic.ts # Core chat business logic |
| 33 | +├── capnweb-rpc.ts # Cap'n Web RPC server implementation |
| 34 | +└── vite-plugin.ts # WebSocket integration with Vite |
| 35 | +
|
| 36 | +src/ |
| 37 | +├── components/ |
| 38 | +│ ├── ChatInterface.tsx # Main chat message display |
| 39 | +│ ├── OnlineUsers.tsx # Online user list |
| 40 | +│ └── UsernameInput.tsx # Username entry |
| 41 | +├── hooks/ |
| 42 | +│ ├── useChatConnection.ts # WebSocket connection management |
| 43 | +│ └── useChatMessages.ts # Message state and polling |
| 44 | +└── routes/ |
| 45 | + └── index.tsx # Main chat page |
| 46 | +``` |
| 47 | + |
| 48 | +## 🚀 Getting Started |
| 49 | + |
| 50 | +### Prerequisites |
| 51 | + |
| 52 | +- Node.js 18+ |
| 53 | +- pnpm (recommended) or npm |
| 54 | + |
| 55 | +### Installation |
| 56 | + |
| 57 | +```bash |
| 58 | +# Clone the repository |
| 59 | +git clone <repo-url> |
| 60 | +cd capnweb-chat-demo |
| 61 | + |
| 62 | +# Install dependencies |
| 63 | +pnpm install |
| 64 | +``` |
| 65 | + |
| 66 | +### Development |
| 67 | + |
| 68 | +```bash |
| 69 | +# Start the development server |
| 70 | +pnpm dev |
| 71 | +``` |
| 72 | + |
| 73 | +Open [http://localhost:3000](http://localhost:3000) in multiple browser tabs to test the chat functionality. |
| 74 | + |
| 75 | +### Building for Production |
| 76 | + |
| 77 | +```bash |
| 78 | +# Build the application |
| 79 | +pnpm build |
| 80 | + |
| 81 | +# Start production server |
| 82 | +pnpm start |
| 83 | +``` |
| 84 | + |
| 85 | +## 💬 How It Works |
| 86 | + |
| 87 | +### 1. **Connection Flow** |
| 88 | + |
| 89 | +- User opens the chat page |
| 90 | +- Application auto-connects to WebSocket server via Cap'n Web RPC |
| 91 | +- Connection status is managed transparently |
| 92 | + |
| 93 | +### 2. **Chat Flow** |
| 94 | + |
| 95 | +- User enters a username |
| 96 | +- Application automatically joins the chat room |
| 97 | +- Messages are sent via RPC calls to the server |
| 98 | +- Server broadcasts messages to all connected users |
| 99 | +- Client polls for new messages every second |
| 100 | + |
| 101 | +### 3. **Message Broadcasting** |
| 102 | + |
| 103 | +```typescript |
| 104 | +// Server-side message broadcasting |
| 105 | +await ChatServer.broadcastToAll({ |
| 106 | + type: 'message', |
| 107 | + message: message.message, |
| 108 | + username: message.username, |
| 109 | + timestamp: message.timestamp, |
| 110 | + id: message.id, |
| 111 | +}) |
| 112 | +``` |
| 113 | + |
| 114 | +### 4. **Real-time Updates** |
| 115 | + |
| 116 | +- **Messages**: Polled every 1 second |
| 117 | +- **Online users**: Updated every 5 seconds |
| 118 | +- **Connection status**: Real-time via WebSocket events |
| 119 | + |
| 120 | +## 🔧 Configuration |
| 121 | + |
| 122 | +### WebSocket Setup |
| 123 | + |
| 124 | +The WebSocket server is configured in `chat-server/vite-plugin.ts`: |
| 125 | + |
| 126 | +```typescript |
| 127 | +// WebSocket endpoint: /api/websocket |
| 128 | +wss.handleUpgrade(request, socket, head, (ws) => { |
| 129 | + const chatServer = new ChatServer() |
| 130 | + chatServer.setWebSocket(ws) |
| 131 | + newWebSocketRpcSession(ws, chatServer) |
| 132 | +}) |
| 133 | +``` |
| 134 | + |
| 135 | +### Message Queue System |
| 136 | + |
| 137 | +Messages are queued per user to ensure delivery: |
| 138 | + |
| 139 | +```typescript |
| 140 | +// Each user gets their own message queue |
| 141 | +export const userMessageQueues = new Map<string, Array<any>>() |
| 142 | + |
| 143 | +// Messages are polled and cleared |
| 144 | +const messages = userMessageQueues.get(username) || [] |
| 145 | +userMessageQueues.set(username, []) // Clear after reading |
| 146 | +``` |
| 147 | + |
| 148 | +## 🧪 Testing |
| 149 | + |
| 150 | +```bash |
| 151 | +# Run tests |
| 152 | +pnpm test |
| 153 | +``` |
| 154 | + |
| 155 | +To test the chat functionality: |
| 156 | + |
| 157 | +1. Open multiple browser tabs to [http://localhost:3000](http://localhost:3000) |
| 158 | +2. Enter different usernames in each tab |
| 159 | +3. Send messages and observe real-time delivery |
| 160 | +4. Check the online users list updates |
| 161 | + |
| 162 | +## 📚 Key Technologies Explained |
| 163 | + |
| 164 | +### Cap'n Web RPC |
| 165 | + |
| 166 | +- **Bidirectional**: Both client and server can call methods on each other |
| 167 | +- **Type-safe**: Full TypeScript support for RPC calls |
| 168 | +- **WebSocket-based**: Built on standard WebSocket protocol |
| 169 | +- **Efficient**: Binary protocol with message queuing |
| 170 | + |
| 171 | +### TanStack Start |
| 172 | + |
| 173 | +- **Full-stack**: Single framework for client and server |
| 174 | +- **Server-side rendering**: Pages render on the server first |
| 175 | +- **File-based routing**: Routes defined by file structure |
| 176 | +- **Type-safe**: End-to-end TypeScript support |
| 177 | + |
| 178 | +### Message Flow |
| 179 | + |
| 180 | +``` |
| 181 | +User types message |
| 182 | + ↓ |
| 183 | +useChatMessages.sendMessage() |
| 184 | + ↓ |
| 185 | +Cap'n Web RPC call |
| 186 | + ↓ |
| 187 | +ChatServer.sendMessage() |
| 188 | + ↓ |
| 189 | +ChatLogic.sendMessage() |
| 190 | + ↓ |
| 191 | +Broadcast to all users |
| 192 | + ↓ |
| 193 | +Message queues updated |
| 194 | + ↓ |
| 195 | +Clients poll for updates |
| 196 | + ↓ |
| 197 | +UI updates with new message |
| 198 | +``` |
| 199 | + |
| 200 | +## 🎯 Why This Demo? |
| 201 | + |
| 202 | +This application demonstrates: |
| 203 | + |
| 204 | +1. **Real-world WebSocket usage** - Not just a simple echo server |
| 205 | +2. **RPC over WebSockets** - More structured than plain message passing |
| 206 | +3. **Modern React patterns** - Hooks, effects, and clean component architecture |
| 207 | +4. **Full-stack TypeScript** - Shared types between client and server |
| 208 | +5. **Production-ready patterns** - Error handling, reconnection, message queuing |
| 209 | + |
| 210 | +Perfect for learning how to build real-time applications with modern web technologies! |
| 211 | + |
| 212 | +## 🤝 Contributing |
| 213 | + |
| 214 | +This is a demonstration project, but improvements are welcome: |
| 215 | + |
| 216 | +- Enhanced error handling |
| 217 | +- Message persistence |
| 218 | +- User authentication |
| 219 | +- Private messaging |
| 220 | +- File sharing |
| 221 | +- Emoji reactions |
| 222 | + |
| 223 | +## 📄 License |
| 224 | + |
| 225 | +This project is open source and available under the [MIT License](LICENSE). |
| 226 | + |
| 227 | +--- |
| 228 | + |
| 229 | +**Built with ❤️ using Cap'n Web RPC and TanStack Start** |
0 commit comments