RAD Studio create a simple real-time multi-platform chat application in RAD Studio with SignalR

emailx45

Местный
Регистрация
5 Май 2008
Сообщения
3,571
Реакции
2,438
Credits
573
create a simple real-time multi-platform chat application in RAD Studio with SignalR
[SHOWTOGROUPS=4,20]
In this tutorial, you’ll learn how to create a simple real-time multi-platform chat application in RAD Studio using Devart SecureBridge component called TScHubConnection, which implements the functionality of a SignalR client.

SignalR is a client/server communication protocol that adds real-time functionality to desktop and web apps. The server will be able to push content to connected clients as soon as it becomes available without waiting for the client to request data. SignalR client libraries have been implemented in many languages, but the Delphi community lacked such a library, so we at Devart decided to implement a SignalR client in SecureBridge, a security component library for Delphi.

Besides SecureBridge, Devart offers a wide range of software solutions such as reliable Delphi data access components for popular databases and cloud sources and advanced Delphi ORM tool EntityDAC.

Start by creating a new multi-device application. Our form will have a few panels, one at the top and one at the bottom. Also add a TMemo component, which is our main chat area where messages are displayed. Add a TSplitter component to the form, which will allow users to resize the panels at runtime. Add a TListBox to display a list of users to chat with.

Add TLabel components for the username and message fields, and a TEdit component, which will contain the name of the user that we’re currently chatting with.

Next, add a TEdit component that will hold our username. Add another TEdit component where we’ll type our message.

Add a button that connects to the server and a button for sending our messages. Finally, place the TScHubConnection component on the form. Now we can start coding the application logic.

Switch to the unit view and declare public methods DoMessageReceipt, DoUserConnected, and DoUserDisconnected for receiving messages, establishing a connection and dropping the connection to the server. We’ll also declare private methods FillUserNameList, FillMessageList, Connect, Disconnect, and IsConnected, which are explained further.

Код:
type
  TfmChatForm = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    meChat: TMemo;
    Splitter1: TSplitter;
    lbUserName: TListBox;
    lbNickName: TLabel;
    lbMessage: TLabel;
    edNickName: TEdit;
    edMessage: TEdit;
    btConnect: TButton;
    btSend: TButton;
    SignalRClient: TScHubConnection;
    procedure FormDestroy(Sender: TObject);
    procedure btConnectClick(Sender: TObject);
    procedure btSendClick(Sender: TObject);
    procedure edNickNameKeyDown(Sender: TObject; var Key: Word;
      var KeyChar: Char; Shift: TShiftState);
    procedure edMessageKeyDown(Sender: TObject; var Key: Word;
      var KeyChar: Char; Shift: TShiftState);
  private
    { Private declarations }
    procedure FillUserNameList(const Values: array of Variant);
    procedure FillMessageList(const Values: array of Variant);
    procedure Connect;
    procedure Disconnect;
    function IsConnected: boolean;
  public
    { Public declarations }
    procedure DoMessageReceipt(Sender: TObject; const Values: array of Variant);
    procedure DoUserConnected(Sender: TObject; const Values: array of Variant);
    procedure DoUserDisconnected(Sender: TObject; const Values: array of Variant);
  end;
var
  fmChatForm: TfmChatForm;

Add System.JSON to the uses clause since we’re going to use JSON to send and receive messages from the server.

Implement the FillUserNameList method that parses a JSON array received from the server and updates the list of connected users in the TListBox component on the form.

Код:
procedure TfmChatForm.FillUserNameList(const Values: array of Variant);
var
  Value, UserNameValue: TJSONValue;
begin
  lbUserName.Items.Clear;
  Value := TJSONObject.ParseJSONValue(Values[0]);
  try
    if Value is TJSONArray then
      for UserNameValue in TJSONArray(Value) do
        lbUserName.Items.Add(UserNameValue.GetValue<string>());
  finally
    Value.Free;
  end;
end;

Now let’s write the code for the FillMessageList method. It parses a JSON array and updates the list of messages in the TMemo component.

Код:
procedure TfmChatForm.FillMessageList(const Values: array of Variant);
var
  Value, MessageValue: TJSONValue;
begin
  Value := TJSONObject.ParseJSONValue(Values[1]);
  try
    if Value is TJSONArray then
      for MessageValue in TJSONArray(Value) do
        if MessageValue is TJSONObject then
          meChat.Lines.Add(TJSONObject(MessageValue).Values['Item1'].Value + ' ' +
            TJSONObject(MessageValue).Values['Item2'].Value + ': ' + TJSONObject(MessageValue).Values['Item3'].Value);
  finally
    Value.Free;
  end;
end;

In the DoUserConnected event handler, we invoke the FillUserNameList and FillMessageList methods.

Код:
procedure TfmChatForm.FillUserNameList(const Values: array of Variant);
var
  Value, UserNameValue: TJSONValue;
begin
  lbUserName.Items.Clear;
  Value := TJSONObject.ParseJSONValue(Values[0]);
  try
    if Value is TJSONArray then
      for UserNameValue in TJSONArray(Value) do
        lbUserName.Items.Add(UserNameValue.GetValue<string>());
  finally
    Value.Free;
  end;
end;

The DoMessageReceipt event handler displays new messages in the chat area.

Код:
procedure TfmChatForm.DoMessageReceipt(Sender: TObject;
  const Values: array of Variant);
begin
  meChat.Lines.Add(Values[0] + ' ' + Values[1] + ': ' + Values[2])
end;

The DoUserDisconnected event handler invokes the FillUserNameList method to update the list of connected users when we disconnect from the server.
Код:
procedure TfmChatForm.DoUserDisconnected(Sender: TObject;
  const Values: array of Variant);
begin
  FillUserNameList(Values);
end;

The Connect method invokes the Start, Register, and Send methods of the TScHubConnection component. The Start method establishes a connection to the server, the Register method registers a handler that will be invoked when the hub method with the specified method name is invoked, and the Send method invokes a hub method on the server using the specified method name and arguments. The text property of the btConnect button changes to Disconnect after the connection has been successfully established.
Код:
procedure TfmChatForm.Connect;
begin
  SignalRClient.Register('Send', DoMessageReceipt, [varString, varString, varString]);
  SignalRClient.Register('Connected', DoUserConnected, [varString, varString]);
  SignalRClient.Register('Disconnected', DoUserDisconnected, [varString]);
  SignalRClient.Start;
  SignalRClient.Send('Connected', [edNickName.Text]);
  btConnect.Text := 'Disconnect';
  edNickName.Enabled := False;
  edMessage.Enabled := True;
  btSend.Enabled := True;
end;

The Disconnect method invokes the Send and Stop methods of SecureBridge. The Stop method drops the connection to the server. The text value of the btConnect button is changed to Connect and the username list is cleared.
Код:
procedure TfmChatForm.Disconnect;
begin
  SignalRClient.Send('Disconnected', [edNickName.Text]);
  SignalRClient.Stop;
  btConnect.Text := 'Connect';
  edNickName.Enabled  := True;
  edMessage.Enabled := False;
  btSend.Enabled := False;
  lbUserName.Items.Clear;
  meChat.Lines.Clear;
end;

The IsConnected method stores the state of the connection to the server.
Код:
function TfmChatForm.IsConnected: boolean;
begin
  Result := SignalRClient.State = hcsConnected;
end;

Implement the OnDestroy event handler that drops an active connection to the server before destroying the form when we close our application.
Код:
procedure TfmChatForm.FormDestroy(Sender: TObject);
begin
  if IsConnected then
    Disconnect;
end;

Now let’s implement the btConnectClick event handler that is triggered when we click the button. It checks whether the client is connected to the server: if the IsConnected function returns True, the client drops the connection to the server by executing the Disconnect method; in case of False, the event handler triggers the execution of the Connect method to establish a connection to the server. Also, it checks whether we’ve specified our username in the NickName field.
Код:
procedure TfmChatForm.btConnectClick(Sender: TObject);
begin
  if IsConnected then begin
    Disconnect;
    Exit;
  end;
  if edNickName.Text = then begin
    meChat.Lines.Add('Error: no user specified!');
  end;
  try
    Connect;
  except
    on E: Exception do
      meChat.Lines.Add('Error: ' + E.Message);
  end;
end;

Let’s write some code for the OnClick event listener for our btSend button to notify the server and other connected users that we’ve written a message. The handler invokes the Send method that sends our text message and username to the server and then clears the message field by assigning an empty string to it.
Код:
procedure TfmChatForm.btSendClick(Sender: TObject);
begin
  try
    SignalRClient.Send('Send', [edNickName.Text, edMessage.Text]);
  finally
    edMessage.Text := ;
  end;
end;

Finally, assign the server address to the URL property of the TScHubConnection component on the form.

Now you can build your app for various platforms.

1590951914229.png

SecureBridge also offers Delphi clients and servers for SSH, SSL, HTTP/HTTPS, WebSocket, and other protocols. Visit the Devart site for more details on SecureBridge and other Delphi component libraries.
[/SHOWTOGROUPS]