How to make persistent connection using Websocket and a Delphi Socket server?

Asked

Viewed 608 times

2

I’m trying to create communication via Websocket with a Delphi socket server,

1st Step, readystate 0 - Server receives Websocket header.

Step 2, readystate 3 - Go to disconnected.

Javascript:

var host = 'ws://10.1.1.10:8100'; // SET THIS TO YOUR SERVER
socketWebservice = new WebSocket(host);

socketWebservice.onopen = function(msg) {
  socketWebservice.send('LOGON');
  alert('entrou');
  //setIntSocketSend = setInterval('contSendSocket()', 119000); //confere o Login a cada 4m:58s
};
socketWebservice.onmessage = function(msg) {
  on_socket_get(msg.data);
};
socketWebservice.onclose = function(msg) {
  //            clearInterval(setIntSocketSend);
  console.log(msg);
};

Delphi uses the component Tserversocket.

Server Code:

unit uServidor;

interface

uses System.Win.ScktComp, Vcl.StdCtrls, Vcl.Controls, System.Classes, Vcl.Forms,
     System.SysUtils;

type
  TForm1 = class(TForm)
    ServerSocket1: TServerSocket;
    ListBox1: TListBox;
    Label1: TLabel;
    Button1: TButton;
    EdtPorta: TEdit;
    Label2: TLabel;
    BtnConectar: TButton;
    ckTodos: TCheckBox;
    EdtMensagem: TMemo;
    procedure BtnConectarClick(Sender: TObject);
    procedure ServerSocket1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure Button1Click(Sender: TObject);
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
  private
    procedure Reconectar;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.BtnConectarClick(Sender: TObject);
begin
  ServerSocket1.Port   := StrToInt(EdtPorta.Text);
  try
    ServerSocket1.Active := true;
    BtnConectar.Caption  := 'Conectado';
    BtnConectar.Enabled  := false;
  except
    raise;
  end;
end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  I : Integer;
begin
  ListBox1.Items.Clear;
  for I := 0 to Pred(ServerSocket1.Socket.ActiveConnections) do
    ListBox1.Items.Add('['+ServerSocket1.Socket.Connections[I].RemoteAddress+']');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  I : Integer;
begin
  if ckTodos.Checked then
    for I := 0 to Pred(ListBox1.Items.Count) do
      ServerSocket1.Socket.Connections[I].SendText(EdtMensagem.Lines.Text)
  else
    ServerSocket1.Socket.Connections[ListBox1.ItemIndex].SendText(EdtMensagem.Lines.Text);
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  EdtMensagem.TEXT := Socket.ReceiveText;
end;

procedure TForm1.Reconectar;
begin
  ServerSocket1.Active := false;
  ServerSocket1.Active := true;
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  I : Integer;
  Endereco : String;
begin
  for I := 0 to Pred(ListBox1.Items.Count) do
  begin
    Endereco := '['+Socket.RemoteAddress+']';
    if Endereco = ListBox1.Items.Strings[I] then
    begin
      ListBox1.Items.Strings[I] := ListBox1.Items.Strings[I] + ' - DESCONECTADO';
      break;
    end;
  end;
end;

end.
  • 1

    Good morning. Can you please specify more clearly what your question is? How far did you get? Are you facing any problems? Which version of Delphi you’re using?

  • I use the version of Delphi xe4, for connecting the Tserversocket component. 1. Active the server for port "8100". 2. I try to connect through Websocket in the port "8100", I see the "readyState" of Websocket it is in the "0 - CONNECTING". 3. In sevirdor I get the header of the Websocket connection. 4. In Websocket it continues "0 - CONNECTING" for a few seconds and soon after it goes to "3 - CLOSED", it does not go to "readyState" "1 - OPEN".

  • Are these ports open in the firewall? The server code would help us in this matter.

  • It’s not firewall, I posted the server code.

  • What can help is to see what error is occurring on the connection. Try to implement the following code in Websocket let $connectionError = document.getElementById("connection-error");

setTimeout( () => {
 if (ws.readyState !== 1) {
 $connectionError.classList.add( "show" );
 }
}, 100 ); The code has been extracted from the link [http://stackoverflow.com/questions/13546424/how-to-wait-for-a-websockets-readystate-to-change]

  • It didn’t work, this is just to show the error message, and it keeps coming status 0 and 3

  • I don’t know much about delphy but, websocket, as far as I know, is a layer on top of http and, from what little I understand of the code, it seems to me that you are using a normal socketserver. This is confirmed by client-side behavior: It enters into Connecting, however, cannot complete http negotiation so disconnects.

Show 2 more comments

1 answer

1


The problem of TServerSocket is that he’s very limited!

I currently use Socket.IO a solution I found in github.

Using his own javascript posted here I was able to make the communication:

Running the Server:

  Server := TIdWebsocketServer.Create(Self);
  Server.DefaultPort := 8200;
  Server.SocketIO.OnEvent(C_CLIENT_EVENT,

  procedure(const ASocket: ISocketIOContext; const aArgument: TSuperArray; const aCallback: ISocketIOCallback)
  begin
    //show request (threadsafe)
    ShowMessageInMainthread('REQUEST: ' + aArgument[0].AsJSon);
    //send callback (only if specified!)
    if aCallback <> nil then
      aCallback.SendResponse( SO(['succes', True]).AsJSon );
  end);

  Server.Active      := True;

Texting:

server.SendMessageToAll('Enviado do Delphi via Socket!');
  • So the problem was in my component, I swear it was in js, I tested here is spun, thanks!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.