| <!DOCTYPE html> |
| <html lang="fr"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Client WebSocket Simple</title> |
| <style> |
| body { |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; |
| margin: 40px; |
| background-color: #f0f2f5; |
| } |
| .container { |
| max-width: 600px; |
| margin: auto; |
| padding: 20px; |
| background-color: #fff; |
| border-radius: 8px; |
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); |
| } |
| #status { |
| padding: 10px; |
| border-radius: 5px; |
| font-weight: bold; |
| margin-bottom: 15px; |
| } |
| .connected { |
| background-color: #e6ffed; |
| color: #2f6f43; |
| } |
| .disconnected { |
| background-color: #ffeef0; |
| color: #c53030; |
| } |
| #logs { |
| list-style-type: none; |
| padding: 0; |
| margin-top: 20px; |
| background-color: #f7f7f7; |
| border: 1px solid #ddd; |
| border-radius: 5px; |
| height: 200px; |
| overflow-y: scroll; |
| padding: 10px; |
| } |
| #logs li { |
| padding: 5px; |
| border-bottom: 1px solid #eee; |
| } |
| </style> |
| </head> |
| <body> |
|
|
| <div class="container"> |
| <h2>Client WebSocket pour API Mock</h2> |
| <div id="status" class="disconnected">Déconnecté</div> |
| |
| <div style="margin-bottom: 20px;"> |
| <label for="apiKey" style="display: block; margin-bottom: 5px; font-weight: bold;">Clé API :</label> |
| <input type="password" id="apiKey" placeholder="Entrez votre clé API..." style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px;"> |
| <small style="color: #666; font-size: 12px;">La clé est stockée uniquement dans votre navigateur pour cette session.</small> |
| </div> |
| |
| <h3>Logs de Communication :</h3> |
| <ul id="logs"> |
| <li>En attente de connexion...</li> |
| </ul> |
| </div> |
|
|
| <script> |
| const statusDiv = document.getElementById('status'); |
| const logsList = document.getElementById('logs'); |
| let ws; |
| |
| function addLog(message) { |
| const li = document.createElement('li'); |
| li.textContent = `[${new Date().toLocaleTimeString()}] ${message}`; |
| logsList.appendChild(li); |
| logsList.scrollTop = logsList.scrollHeight; |
| } |
| |
| |
| async function callOpenAI(prompt) { |
| console.log('prompt:', prompt) |
| |
| |
| const apiKey = document.getElementById('apiKey').value.trim(); |
| if (!apiKey) { |
| throw new Error('Clé API manquante. Veuillez la saisir dans le champ prévu.'); |
| } |
| |
| try { |
| const response = await fetch('https://llm.synapse.thalescloud.io/v1/chat/completions', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| 'Authorization': `Bearer ${apiKey}` |
| }, |
| body: JSON.stringify({ |
| model: 'gemini-2.5-pro', |
| messages: [ |
| { |
| role: 'user', |
| content: prompt |
| } |
| ], |
| temperature: 0.7 |
| }) |
| }); |
| |
| console.log('response:', response) |
| if (!response.ok) { |
| throw new Error(`OpenAI API error: ${response.status}`); |
| } |
| |
| const data = await response.json(); |
| console.log('data:', data) |
| return data.choices[0].message.content.trim(); |
| } catch (error) { |
| console.error('Error calling OpenAI:', error); |
| throw error; |
| } |
| } |
| |
| function connect() { |
| |
| const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; |
| const wsUrl = `${protocol}//${window.location.host}/ws`; |
| ws = new WebSocket(wsUrl); |
| |
| ws.onopen = function() { |
| statusDiv.textContent = 'Connecté'; |
| statusDiv.className = 'connected'; |
| addLog('Connexion WebSocket établie.'); |
| }; |
| |
| |
| ws.onmessage = async function(event) { |
| const messageFromServer = event.data; |
| console.log(`Message reçu du serveur : "${messageFromServer}"`) |
| addLog(`Message reçu du serveur : "${messageFromServer}"`); |
| |
| try { |
| |
| if (ws.readyState !== WebSocket.OPEN) { |
| addLog('Erreur: WebSocket fermé, impossible de répondre'); |
| return; |
| } |
| |
| addLog('Appel API en cours...'); |
| |
| |
| const responsePhrase = await callOpenAI(messageFromServer); |
| |
| |
| if (ws.readyState === WebSocket.OPEN) { |
| addLog(`Envoi de la réponse automatique : "${responsePhrase}"`); |
| ws.send(responsePhrase); |
| } else { |
| addLog('Erreur: WebSocket fermé pendant l\'appel API'); |
| } |
| |
| } catch (error) { |
| console.error('Erreur lors de l\'appel API:', error); |
| addLog(`Erreur lors de l'appel API : ${error.message}`); |
| |
| |
| if (ws.readyState === WebSocket.OPEN) { |
| ws.send(`Erreur: ${error.message}`); |
| } |
| } |
| }; |
| |
| ws.onclose = function() { |
| statusDiv.textContent = 'Déconnecté'; |
| statusDiv.className = 'disconnected'; |
| addLog('Connexion WebSocket fermée. Tentative de reconnexion dans 3 secondes...'); |
| |
| setTimeout(connect, 3000); |
| }; |
| |
| ws.onerror = function(error) { |
| addLog('Erreur WebSocket.'); |
| console.error('WebSocket Error:', error); |
| ws.close(); |
| }; |
| } |
| |
| |
| connect(); |
| </script> |
|
|
| </body> |
| </html> |