facil.io - Native Pub/Sub

The facil.io framework offers a native Pub/Sub implementation which can be found in the "services" folder.

This Pub/Sub implementation covers the whole process cluster and it can be easily scaled by using Redis (which isn't required except for horizontal scaling).

Connection based vs. non-connection based Pub/Sub

The Websockets extension allows for connection based subscription in adition to the regular Pub/Sub subscriptions.

When using connection based subscription, the connection's on_close callback will automatically unsubscribes from any existing subscriptions.

This allows messages to be be either forwarded directly to the client or handled by a server-side callback.

An example for this approach can be seen in the chatroom example using the websocket_subscribe function. The same function could have been used with a server-side callback.

A non-connection based Pub/Sub allows a local event to fire whenever a message arrives.

This event allows the server to react to certain channels, allowing remotely published events (by clients or through Redis) to invoke server routines.

This approach uses the pubsub_subscribe function directly rather than a connection related function.

Connecting Redis as a Pub/Sub Service

A built-in Redis engine is bundled with facil.io (it can be removed safely by deleting the folder).

It's simple to add Redis for multi-machine clustering by creating a Redis engine and setting it as the default engine.

i.e.:

int main(void) {
  PUBSUB_DEFAULT_ENGINE =
      redis_engine_create(/** Redis server's address */
                              .address = "localhost", .ping_interval = 2, );
  /* code */
  facil_run(/* settings */);
  redis_engine_destroy(PUBSUB_DEFAULT_ENGINE);
  return 0;
}

Connecting a custom Pub/Sub Service

It's possible. The documentation is available within the header file pubsub.h (using pubsub_engine_s).

Notice, that the on_subscribe will be called for all the channels in the process cluster, so it's possible to connect to the external pub/sub service from a single process (minimizing network traffic) and to publish to the whole cluster.

Also, be aware that messages arrive at least once. When using pattern matching, messages might arrive far more than once (i.e., if the service sends two copies, one for the channel and one for the pattern, the cluster might receive four copies, due to internal pattern matching).

Also, see known issues for lost messages when connection is disrupted (this might be pub/sub service specific).

Details and Limitations:

It's possible to manually send commands to the Redis client and overcome this issue, but disconnections will require resetting the database.