#1 2015-09-05 16:38:50

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 337

Websocket notification from server to web client

Hi ab, I am using websocket in an application where the client is a web page and the server is a Delphi application (based on sample 31 echo server), the web client start the communication and the server responds.

My problem is that the server need send notification to web client and I don't know how send this with no current request from client side.

Is this possible ? with any example I would be grateful.

Thanks in advance.

EMartin.


Esteban

Offline

#2 2015-09-06 11:52:50

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,706
Website

Re: Websocket notification from server to web client

You can just call the SendFrame() method of the TWebSocketProtocolChat/TWebSocketProtocol class.
It is thread-safe, so could be called from any server thread, to notify the client.

Online

#3 2015-09-06 13:59:45

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 337

Re: Websocket notification from server to web client

I tried that, but how I access to the instance of the TWebSocketProtocolChat and to the first parameter of SendFrame THttpServerResp ?.

Thanks..


Esteban

Offline

#4 2015-09-07 14:02:44

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 337

Re: Websocket notification from server to web client

I solved this saving reference from TWebSocketProtocolChat and THttpServerResp:

  // protocol class implementation
  TCCAgentWSProtocol = class(TWebSocketProtocolChat)
  protected
    procedure ProcessFrame(Sender: THttpServerResp; const Frame: TWebSocketFrame);
  public
    CCAgentWS: TCCAgentWS; // my class using websocket protocol class
  end;

  // ProcessFrame implementation
procedure TCCAgentWSProtocol.ProcessFrame(Sender: THttpServerResp; const Frame: TWebSocketFrame);
begin
  case Frame.opcode of
    focContinuation:
    begin
      CCAgentWS.fWSProtocol := Self;
      CCAgentWS.fWSHttpServerResp := Sender;
    end;
    focConnectionClose:
    begin
      CCAgentWS.fWSProtocol := Nil;
      CCAgentWS.fWSHttpServerResp := Nil;
    end;
    ...
  end;
end;

It is not a mORMot solution but "it is what it is".

Thanks.


Esteban

Offline

#5 2015-09-09 02:46:36

warleyalex
Member
From: Sete Lagoas-MG, Brasil
Registered: 2013-01-20
Posts: 250

Re: Websocket notification from server to web client

I have a connections list that contains a list with all clients connections. I've created a OnAfterAddConnection event to capture Connection ID/Sock ID.

Every time a Client establishes a WebSocket connection, this connection is identified by a ConnectionID, and a sock ID, so I think I could use this info to send a message to a single client, but unfortunately I couldn't find a way.

IP               Connection ID     Sock ID
------------------------------------------
127.0.0.1         1                     800
127.0.0.1         2                     820
127.0.0.1         3                     824
-------------------------------------------
It also would be nice to have a OnBeforeRemoveConnection to get the ConnectionID/SockID. Every time a WebSocket connection is dropped, this event is fired, to refresh the grid, for instance...

Does anyone have any suggestion how to:
How to broadcast: sends a message to all connected clients?
How to use SendFrame to send a message to a single client?
How to use SendFrame to disconnect a client?

Offline

#6 2016-06-21 19:39:22

rclaros
Member
Registered: 2016-06-21
Posts: 8

Re: Websocket notification from server to web client

Hello EMartin,

You could share your complete solution ?

I do not understand is what your class " TCCAgentWS " ...

I appreciate all the guidance you can provide .


EMartin wrote:

I solved this saving reference from TWebSocketProtocolChat and THttpServerResp:

  // protocol class implementation
  TCCAgentWSProtocol = class(TWebSocketProtocolChat)
  protected
    procedure ProcessFrame(Sender: THttpServerResp; const Frame: TWebSocketFrame);
  public
    CCAgentWS: TCCAgentWS; // my class using websocket protocol class
  end;

  // ProcessFrame implementation
procedure TCCAgentWSProtocol.ProcessFrame(Sender: THttpServerResp; const Frame: TWebSocketFrame);
begin
  case Frame.opcode of
    focContinuation:
    begin
      CCAgentWS.fWSProtocol := Self;
      CCAgentWS.fWSHttpServerResp := Sender;
    end;
    focConnectionClose:
    begin
      CCAgentWS.fWSProtocol := Nil;
      CCAgentWS.fWSHttpServerResp := Nil;
    end;
    ...
  end;
end;

It is not a mORMot solution but "it is what it is".

Thanks.

Offline

#7 2016-06-22 19:11:03

oz
Member
Registered: 2015-09-02
Posts: 98

Re: Websocket notification from server to web client

Imho you are trying to solve that problem on the wrong application tier. TWebSocketProtocolChat.ProcessFrame is very low level. That's the reason why you are facing that problem at all.
Taking the chat service as example, there is:

procedure TChatService.Join(const pseudo: string; const callback: IChatCallback);

Put the callback parameter together with session params you can retrieve from global threadvar ServiceContext in some kind of simple data object/record. Store that object/record to any kind of list/array instead of "fConnected: array of IChatCallback". You can identify single sessions by searching the array/list now. The found data record/object has a direct reference to the IChatCallback. You have direct access to its functions for this single client connection.

Offline

#8 2021-11-17 19:45:07

cgsousa21
Member
Registered: 2021-11-07
Posts: 4

Re: Websocket notification from server to web client

ab wrote:

You can just call the SendFrame() method of the TWebSocketProtocolChat/TWebSocketProtocol class.
It is thread-safe, so could be called from any server thread, to notify the client.

Hello AB,

I'm trying to use it like this:

type
  //simple chatting protocol
  TSimpleChatProtocol = class(TWebSocketProtocolChat)
  private
    fParent: TSimpleChatServer;
  protected
    procedure echoFrame(Sender: THttpServerResp; const Frame: TWebSocketFrame);
    constructor newSimpleChatProtocol(aParent: TSimpleChatServer; const aName: RawUTF8);
  end;

  TSimpleChatServer = class
  private
    fPort: SockString;
    fServer: TWebSocketServer;
    fProtocol: TSimpleChatProtocol;
  ...

...
function TSimpleChatServer.closeConnetionOfClient(
  aClient: THttpServerResp): Boolean;
var
  frm: TWebSocketFrame;
begin
  FrameInit(focConnectionClose, '', '', frm);
  result :=fProtocol.SendFrame(aClient, frm);
end;
...

No effect is caused, any suggestions?

Last edited by cgsousa21 (2021-11-17 19:49:30)

Offline

#9 2021-11-17 20:13:07

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,706
Website

Re: Websocket notification from server to web client

focConnectionClose is a specific kind of frame.

It is already sent by the framework when you close the connection on any end.

Online

Board footer

Powered by FluxBB