+void ctxClientEventListenerRemove(struct AFB_clientCtx *clientCtx, struct afb_event_listener listener)
+{
+ remove_listener(clientCtx != NULL ? &clientCtx->listeners : &sessions.listeners, listener);
+}
+
+static int send(struct afb_event_listener_list *head, const char *event, struct json_object *object)
+{
+ struct afb_event_listener_list *iter;
+ int result;
+
+ result = 0;
+ iter = head;
+ while (iter != NULL) {
+ if (iter->listener.itf->expects == NULL || iter->listener.itf->expects(iter->listener.closure, event)) {
+ iter->listener.itf->send(iter->listener.closure, event, json_object_get(object));
+ result++;
+ }
+ iter = iter->next;
+ }
+
+ return result;
+}
+
+int ctxClientEventSend(struct AFB_clientCtx *clientCtx, const char *event, struct json_object *object)
+{
+ long idx;
+ time_t now;
+ int result;
+
+ now = NOW;
+ if (clientCtx != NULL) {
+ result = ctxIsActive(clientCtx, now) ? send(clientCtx->listeners, event, object) : 0;
+ } else {
+ result = send(sessions.listeners, event, object);
+ for (idx=0; idx < sessions.max; idx++) {
+ clientCtx = ctxClientAddRef(sessions.store[idx]);
+ if (clientCtx != NULL && ctxIsActive(clientCtx, now)) {
+ clientCtx = ctxClientAddRef(clientCtx);
+ result += send(clientCtx->listeners, event, object);
+ }
+ ctxClientUnref(clientCtx);
+ }
+ }
+ return result;
+}
+
+const char *ctxClientGetUuid (struct AFB_clientCtx *clientCtx)
+{