Java : Système de Chat Multi-Utilisateurs avec Base de Données

Ce projet реализует un système de discustion en temps réel multi-utilisateurs utilisant une base de données. Les utilisateurs peuvent se connecter via un client, rejoindre une salle de conversation et échanger des messages en direct. Le système prend en charge l'inscription, la connexion, les discussions de groupe et les messages privés. Tous les échanges sont stockés dans une base de données pour garantir leur pérennité. La salle supporte plusieurs utilisateurs simultanément connectés et permet de consulter l'historique, envoyer des images et des émoticônes. #### Caractéristiques principales :

  1. Gestion des utilisateurs : Inscription, connexion et modification de mot de passe.
  2. Discussion de groupe et privée : Communication collective ou échanges一对一 avec un utilisateur spécifique.
  3. Stockage des messagees : Enregistrement en temps réel dans la base de données avec possibiilté de consultation historique.
  4. Images et'émoticônes : Support pour l'envoi de médias enrichissant l'interaction.
  5. Multi-utilisateurs : Plusieurs utilisateurs peuvent être connectés simultanément pour une communication en temps réel.

Stack technique :

  • Frontend : Java Swing (application de bureau)
  • Backend : Programmation Java Socket (connexions TCP)
  • Base de données : MySQL (stockage des informations utilisateurs et des messages)
  • Pool de threads : Gestion de plusieurs connexions clientes

Conception de la base de données :

1. Table utilisateurs : Stocke les identifiants de connexion.

CREATE TABLE utilisateurs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    pseudo VARCHAR(50) UNIQUE NOT NULL,
    motdepasse VARCHAR(50) NOT NULL
);

2. Table messages : Conserve l'historique des échanges.

CREATE TABLE messages (
    id INT AUTO_INCREMENT PRIMARY KEY,
    expediteur VARCHAR(50) NOT NULL,
    destinataire VARCHAR(50),
    contenu TEXT NOT NULL,
    horodatage DATETIME DEFAULT CURRENT_TIMESTAMP
);

Implémentation Java :

1. Classe Utilisateur (Utilisateur.java)
public class Utilisateur {
    private String pseudo;
    private String motdepasse;

    public Utilisateur(String pseudo, String motdepasse) {
        this.pseudo = pseudo;
        this.motdepasse = motdepasse;
    }

    public String obtenirPseudo() {
        return pseudo;
    }

    public void definirPseudo(String pseudo) {
        this.pseudo = pseudo;
    }

    public String obtenirMotDePasse() {
        return motdepasse;
    }

    public void definirMotDePasse(String motdepasse) {
        this.motdepasse = motdepasse;
    }
}

2. Serveur (ServeurDiscussion.java)
import java.io.*;
import java.net.*;
import java.util.*;
import java.sql.*;

public class ServeurDiscussion {
    private static final int PORT_ECOUTE = 54321;
    private static Set<PrintWriter> clientsConnectes = new HashSet<>();
    private static Connection connexionBD;

    public static void main(String[] args) {
        try {
            connexionBD = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/bddiscussion", "root", "motdepasse");
            System.out.println("Serveur démarré sur le port " + PORT_ECOUTE);
            ServerSocket socketServeur = new ServerSocket(PORT_ECOUTE);

            while (true) {
                new GestionnaireClient(socketServeur.accept()).start();
            }
        } catch (IOException | SQLException erreur) {
            erreur.printStackTrace();
        }
    }

    private static class GestionnaireClient extends Thread {
        private Socket socketClient;
        private PrintWriter emission;
        private BufferedReader reception;
        private String nomUtilisateur;

        public GestionnaireClient(Socket socket) {
            this.socketClient = socket;
        }

        @Override
        public void run() {
            try {
                reception = new BufferedReader(
                    new InputStreamReader(socketClient.getInputStream()));
                emission = new PrintWriter(
                    socketClient.getOutputStream(), true);

                emission.println("Identifiant : ");
                String identifiant = reception.readLine();
                emission.println("Mot de passe : ");
                String mdp = reception.readLine();

                if (verifierIdentifiants(identifiant, mdp)) {
                    this.nomUtilisateur = identifiant;
                    emission.println("Connexion réussie !");

                    synchronized (clientsConnectes) {
                        clientsConnectes.add(emission);
                    }

                    String messageRecu;
                    while ((messageRecu = reception.readLine()) != null) {
                        System.out.println(nomUtilisateur + " : " + messageRecu);
                        enregistrerMessage(nomUtilisateur, messageRecu);
                        diffuserMessage(nomUtilisateur + " : " + messageRecu);
                    }
                } else {
                    emission.println("Identifiants invalides. Veuillez réessayer.");
                }
            } catch (IOException erreur) {
                erreur.printStackTrace();
            } finally {
                fermerConnexion();
            }
        }

        private boolean verifierIdentifiants(String pseudo, String mdp) throws SQLException {
            String sql = "SELECT * FROM utilisateurs WHERE pseudo = ? AND motdepasse = ?";
            try (PreparedStatement ps = connexionBD.prepareStatement(sql)) {
                ps.setString(1, pseudo);
                ps.setString(2, mdp);
                ResultSet resultat = ps.executeQuery();
                return resultat.next();
            }
        }

        private void enregistrerMessage(String expediteur, String contenu) throws SQLException {
            String sql = "INSERT INTO messages (expediteur, destinataire, contenu) VALUES (?, ?, ?)";
            try (PreparedStatement ps = connexionBD.prepareStatement(sql)) {
                ps.setString(1, expediteur);
                ps.setString(2, "groupe");
                ps.setString(3, contenu);
                ps.executeUpdate();
            }
        }

        private void diffuserMessage(String texte) {
            synchronized (clientsConnectes) {
                for (PrintWriter writer : clientsConnectes) {
                    writer.println(texte);
                }
            }
        }

        private void fermerConnexion() {
            try {
                if (emission != null) {
                    synchronized (clientsConnectes) {
                        clientsConnectes.remove(emission);
                    }
                }
                if (socketClient != null) {
                    socketClient.close();
                }
            } catch (IOException erreur) {
                erreur.printStackTrace();
            }
        }
    }
}

3. Client (ClientDiscussion.java)
import java.io.*;
import java.net.*;
import java.util.Scanner;

public class ClientDiscussion {
    private static final String ADRESSE_SERVEUR = "localhost";
    private static final int PORT_SERVEUR = 54321;
    private static Socket socketConnexion;
    private static PrintWriter sortie;
    private static BufferedReader entre;
    private static Scanner saisie = new Scanner(System.in);

    public static void main(String[] args) {
        try {
            socketConnexion = new Socket(ADRESSE_SERVEUR, PORT_SERVEUR);
            entre = new BufferedReader(
                new InputStreamReader(socketConnexion.getInputStream()));
            sortie = new PrintWriter(
                socketConnexion.getOutputStream(), true);

            System.out.print(entre.readLine());
            String identifiant = saisie.nextLine();
            sortie.println(identifiant);

            System.out.print(entre.readLine());
            String motdepasse = saisie.nextLine();
            sortie.println(motdepasse);

            new ThreadReception().start();

            while (true) {
                String message = saisie.nextLine();
                sortie.println(message);
            }
        } catch (IOException erreur) {
            erreur.printStackTrace();
        }
    }

    private static class ThreadReception extends Thread {
        @Override
        public void run() {
            try {
                String message;
                while ((message = entre.readLine()) != null) {
                    System.out.println(message);
                }
            } catch (IOException erreur) {
                erreur.printStackTrace();
            }
        }
    }
}

Mode d'emploi :

Présentation des fonctionnalités :

Ce système de discussion multi-utilisateurs avec base de données utilise les sockets pour la communication entre clients et serveur. Les utilisateurs peuvent se connecter, envoyer des messages, consulter l'historique, le tout avec support des discussions de groupe et privées. Les échanges sont conservés dans la base de données pour consultation ultérieure.

Étapes d'utilisation :
  1. Configuration de la base de données :
    • Créer une base de données nommée bddiscussion
    • Créer les tables utilisateurs et messages
  2. Lancer le serveur : Exécuter ServeurDiscussion.java - le serveur attend les connexions
  3. Lancer le client : Exécuter ClientDiscussion.java - l'utilisateur saisit ses identifiants pour accéder au chat
  4. Stockage des messages : Tous les échanges sont sauvegardés dans la table messages avec l'expéditeur, le destinataire (groupe pour les discusiones collectives), le contenu et l'horodatage
  5. Envoi de messages : Le client saisit du texte pour communiquer avec les autres utilisateurs en ligne
Exemple de sortie :
Identifiant : 
utilisateur1
Mot de passe : 
mdp123
Connexion réussie !
utilisateur1 : Bonjour à tous !
utilisateur2 : Salut utilisateur1 !

Cas d'usage :
  • Chat interne d'entreprise : Communication temps réel pour les équipes avec support multi-utilisateurs
  • Plateforme sociale : Module de messagerie pour un réseau social de petite échelle
  • Éducation en ligne : Interaction entre enseignants et étudiants via une salle de discussion

Ce projet démontre comment implémenter en Java un système de discussion en temps réel avec support de base de données, adapté aux applications nécessitant la persistancedes messages et la prise en charge de plusieurs utilisateurs concurrents.

Étiquettes: Java Socket MySQL JDBC Swing

Publié le 17 juillet à 23h34