Criando um Chat Simples em Delphi

Classificado em Computação

Escrito em em português com um tamanho de 9,11 KB.

1ª Etapa: Configurando a Interface

Para começar, vamos criar a interface do chat. Adicione os seguintes componentes ao seu formulário:

  • TMemo: Nomeie como "Quadro" (para exibir as mensagens).
  • TMemo: Nomeie como "Status" (para informações de conexão).
  • TGroupBox: Nomeie como "C_Comandos".
  • TEdit: Dentro de "C_Comandos", nomeie como "C_Texto" (para digitar mensagens).
  • TEdit: Nomeie como "Host" (para o endereço do servidor).
  • TEdit: Nomeie como "Apelido".
  • TButton: Nomeie como "Conectar".
  • TButton: Nomeie como "Servir".
  • 2 TLabel: Com os captions "Servidor" e "Apelido".
  • TClientSocket: Nomeie como "S_Cliente".
  • TServerSocket: Nomeie como "S_Server".

Renomeie o Form1 para "ChatFal".

Organize os componentes conforme as imagens fornecidas no tutorial original.

2ª Etapa: Programando o Chat (Parte 1)

a) Evento FormCreate:

Clique duas vezes no formulário e adicione o seguinte código:

procedure TChatFal.FormCreate(Sender: TObject);
begin
  Quadro.Text := ''; // Limpa o quadro de mensagens
end;

Explicação: Ao iniciar, o conteúdo do componente "Quadro" é limpo.

b) Evento OnKeyDown do componente C_Texto:

Crie a seguinte procedure:

procedure C_TextoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

E implemente-a da seguinte forma:

procedure TChatFal.C_TextoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if Key = VK_Return then // Se a tecla pressionada for Enter
  begin
    S_Cliente.Socket.SendText(C_Texto.Text + '::::' + Apelido.Text); // Envia a mensagem
    C_Texto.Text := ''; // Limpa o campo de texto
  end;
end;

Explicação: Se a tecla Enter for pressionada, o texto digitado em "C_Texto" é enviado ao servidor, concatenado com o apelido, usando "::::" como separador. Em seguida, o campo de texto é limpo.

c) Evento OnClick do botão "Conectar":

procedure TChatFal.ConectarClick(Sender: TObject);
begin
  if S_Cliente.Active then
  begin
    S_Cliente.Active := False; // Desconecta
    Conectar.Caption := 'Conectar';
  end
  else
  begin
    S_Cliente.Host := Host.Text; // Define o host
    S_Cliente.Active := True; // Conecta
  end;
end;

Explicação: Verifica se o cliente já está conectado. Se sim, desconecta; caso contrário, conecta ao servidor especificado em "Host".

3ª Etapa: Eventos do Lado Cliente

Declare os seguintes procedimentos:

procedure S_ClienteConnect(Sender: TObject; Socket: TCustomWinSocket);
procedure S_ClienteDisconnect(Sender: TObject; Socket: TCustomWinSocket);
procedure S_ClienteError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure S_ClienteRead(Sender: TObject; Socket: TcustomWinSocket);

Evento OnConnect:

procedure TChatFal.S_ClienteConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Status.Lines.Add('Cliente ::> Conectado a: ' + S_Cliente.Host);
  Conectar.Caption := 'Desconectar';
  Apelido.Enabled := False;
  S_Cliente.Socket.SendText('NICK::::' + Apelido.Text); // Envia o apelido ao servidor
end;

Explicação: Executado após uma conexão bem-sucedida. Exibe uma mensagem no "Status", altera o texto do botão "Conectar" e envia o apelido ao servidor.

Evento OnDisconnect:

procedure TChatFal.S_ClienteDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Status.Lines.Add('Cliente ::> Desconectado ');
  Conectar.Caption := 'Conectar';
  Apelido.Enabled := True;
end;

Explicação: Executado quando a conexão é encerrada. Exibe mensagem e restaura o botão.

Evento OnError:

procedure TChatFal.S_ClienteError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  Status.Lines.Add('Cliente ::> ERRO ao tentar conectar a: ' + S_Cliente.Host);
end;

Explicação: Exibe mensagem de erro no "Status".

Evento OnRead:

procedure TChatFal.S_ClienteRead(Sender: TObject; Socket: TCustomWinSocket);
begin
  Quadro.Lines.Add(Socket.ReceiveText); // Adiciona a mensagem recebida ao quadro
end;

Explicação: Recebe dados do servidor e os exibe no componente "Quadro".

Configurando as propriedades do TClientSocket (S_Cliente):

  • No Object Inspector, defina Active como FALSE.
  • Defina Port como 666 (ou outra porta de sua escolha).
  • Na aba Events, configure os eventos conforme a imagem do tutorial.

4ª Etapa: Lado Servidor

Evento OnClick do botão "Servir":

procedure TChatFal.ServirClick(Sender: TObject);
begin
  if S_Server.Active = True then
  begin
    S_Server.Active := False;
    Status.Lines.Add('Servidor ::> Servidor Desligado!');
    Servir.Caption := 'Iniciar Servidor';
    S_Cliente.Active := False;
    Host.Enabled := True;
    Conectar.Enabled := True;
  end
  else
  begin
    S_Server.Active := True;
    Servir.Caption := 'Parar Servidor';
    Host.Enabled := False;
    Conectar.Enabled := False;
    S_Cliente.Host := '127.0.0.1'; // Conecta o cliente ao servidor local
    S_Cliente.Active := True;
  end;
end;

Explicação: Inicia ou para o servidor. Ao iniciar, conecta automaticamente um cliente local (127.0.0.1).

Declare os procedimentos dos eventos do S_Server:

procedure S_ServerListen(Sender: TObject; Socket: TCustomWinSocket);
procedure S_ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket);
procedure S_ServerClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
procedure S_ServerClientRead(Sender: TObject; Socket: TcustomWinSocket);

Evento OnListen:

procedure TChatFal.S_ServerListen(Sender: TObject; Socket: TCustomWinSocket);
begin
  Status.Lines.Add('Servidor ::> Servidor Ligado!');
end;

Explicação: Indica que o servidor foi iniciado.

Evento OnClientConnect:

procedure TChatFal.S_ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Status.Lines.Add('Servidor ::> Usuário Conectado => ' + Socket.RemoteAddress);
end;

Explicação: Informa sobre novas conexões.

Evento OnClientDisconnect:

procedure TChatFal.S_ServerClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Status.Lines.Add('Servidor ::> Usuário Desconectado => ' + Socket.RemoteAddress);
end;

Explicação: Informa sobre desconexões.

Evento OnClientRead (o mais importante):

procedure TChatFal.S_ServerClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  texto: array[0..1] of string;
  temptexto: string;
  Index: integer;
begin
  temptexto := Socket.ReceiveText; // Recebe os dados
  // Divide a mensagem usando o separador '::::'
  texto[0] := Copy(temptexto, 1, Pos('::::', temptexto) - 1);
  texto[1] := Copy(temptexto, Pos('::::', temptexto) + Length('::::'), Length(temptexto));

  if texto[0] = 'NICK' then // Mensagem de entrada
  begin
    with S_Server.Socket do
    begin
      for Index := 0 to ActiveConnections - 1 do
      begin
        Connections[Index].SendText(texto[1] + ' entrou na sala: '); // Envia para todos
      end;
    end;
  end
  else // Mensagem normal
  begin
    with S_Server.Socket do
    begin
      for Index := 0 to ActiveConnections - 1 do
      begin
        Connections[Index].SendText('(' + texto[1] + ') escreveu: ' + texto[0]); // Envia para todos
      end;
    end;
    Status.Lines.Add('Servidor ::> ' + texto[1] + ' (' + Socket.RemoteAddress + ') escreveu: ' + texto[0]); // Log no servidor
  end;
end;

Explicação: Recebe dados, separa a mensagem do apelido, e retransmite para todos os clientes conectados. Se a mensagem começar com "NICK", é tratada como uma mensagem de entrada.

Configurando as propriedades do TServerSocket (S_Server):

  • Active = False
  • Port = 666 (ou a mesma porta usada no cliente)
  • Configure os eventos no Object Inspector conforme o tutorial.

Testando o Chat

Compile o programa e execute várias instâncias. Em uma instância, inicie o servidor. Nas outras, conecte-se ao servidor (usando 127.0.0.1 como endereço, se estiver testando localmente).

Agora você deve conseguir enviar mensagens entre as instâncias do chat.

Entradas relacionadas: