#1 2015-11-12 12:48:53

Roberto Schneiders
Member
From: Santa Catarina, Brazil
Registered: 2012-09-19
Posts: 127
Website

WebSocket Pub-Sub with channels?

I'm trying to implement a publish-subscribe messaging system with mORMot websockets. I need something like (pusher) channels.

I want to use a unique mormot server to send messages to all clients, so, when a client subscribe to a message/event, it should be only for a determined channel/client. When a notification is sent, it is only for a specific client.

My interfaces look like this:

  INotificationCallback = interface(IInvokable)
    ['{F5D956A4-AE70-4F47-AECC-40E2AB6AC0B4}']
    procedure NotifyRefresh(const message: string);
  end;
  NotificationCallbackArray = array of INotificationCallback;

  INotificationService = interface(IServiceWithCallbackReleased)
    ['{C92DCBEA-C680-40BD-8D9C-3E6F2ED9C9CF}']
    procedure Subscribe(const client: string; const callback: INotificationCallback);
    procedure Refresh(const client, message: string);
  end;

I'm using a dictionary to store the callbacks:

fConnected: TDictionary<string, NotificationCallbackArray>;
...
procedure TNotificationService.Subscribe(const client: string; const callback: INotificationCallback);
begin
  if not fConnected.ContainsKey(client) then
    fConnected.Add(client, []);

  InterfaceArrayAdd(fConnected[client], callback);
end;

The problem is the CallbackReleased method:

  procedure CallbackReleased(const callback: IInvokable; const interfaceName: RawUTF8);

It doesn't provide any information that allow me to identify and release the correct callback.

Any ideas of how to solve this?

Last edited by Roberto Schneiders (2015-11-12 12:51:01)

Offline

#2 2015-11-12 13:13:44

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

Re: WebSocket Pub-Sub with channels?

Why not just check for interfaceName='INotificationCallback' then delete the callback: IInvokable from all matching entry in fConnected[]?

Or not use a dictionary, but an array of records containing the client string and the INotificationCallback entry.

Offline

#3 2015-11-12 13:19:13

Roberto Schneiders
Member
From: Santa Catarina, Brazil
Registered: 2012-09-19
Posts: 127
Website

Re: WebSocket Pub-Sub with channels?

ab wrote:

Why not just check for interfaceName='INotificationCallback' then delete the callback: IInvokable from all matching entry in fConnected[]?

that will work, but, I will have more than a thousand channels with potentialy more than 5k callbacks, it would be slow, don't you think? A hashlist would be much more efficient.

ab wrote:

Or not use a dictionary, but an array of records containing the client string and the INotificationCallback entry.

Not sure, but will end up in the same problem, I think.

Offline

#4 2015-11-12 14:43:24

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

Re: WebSocket Pub-Sub with channels?

If you are just looping around callback pointers, even 5,000 pointers may be fast to browse, in practice...

But why not define your own UnSubscribe(const client: string; const callback: INotificationCallback) method?

Offline

#5 2015-11-12 15:33:04

Roberto Schneiders
Member
From: Santa Catarina, Brazil
Registered: 2012-09-19
Posts: 127
Website

Re: WebSocket Pub-Sub with channels?

I can try that. AFAIK, the `CallbackReleased` method is used and handled internally by the framework, you are suggesting that I handle manually that behavior with this new method?

Offline

#6 2015-11-12 17:25:42

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

Re: WebSocket Pub-Sub with channels?

`CallbackReleased` method is used and handled internally by the framework only if your callback implementation class inherit from TInterfacedCallback.

Offline

Board footer

Powered by FluxBB