/** * infc_session_proxy_join_user: * @proxy: A #InfcSessionProxy. * @params: Construction properties for the InfUser (or derived) object. * @n_params: Number of parameters. * @error: Location to store error information. * * Requests a user join for a user with the given properties (which must not * include ID and status since these are initially set by the server). * * Return Value: A #InfcUserRequest object that may be used to get notified * when the request succeeds or fails. **/ InfcUserRequest* infc_session_proxy_join_user(InfcSessionProxy* proxy, const GParameter* params, guint n_params, GError** error) { InfcSessionProxyPrivate* priv; InfSessionClass* session_class; InfSessionStatus status; InfcRequest* request; xmlNodePtr xml; g_return_val_if_fail(INFC_IS_SESSION_PROXY(proxy), NULL); g_return_val_if_fail(params != NULL || n_params == 0, NULL); priv = INFC_SESSION_PROXY_PRIVATE(proxy); g_return_val_if_fail(priv->session != NULL, NULL); session_class = INF_SESSION_GET_CLASS(priv->session); /* Make sure we are subscribed */ g_object_get(G_OBJECT(priv->session), "status", &status, NULL); g_return_val_if_fail(status == INF_SESSION_RUNNING, NULL); g_return_val_if_fail(priv->connection != NULL, NULL); /* TODO: Check params locally */ request = infc_request_manager_add_request( priv->request_manager, INFC_TYPE_USER_REQUEST, "user-join", NULL ); xml = infc_session_proxy_request_to_xml(INFC_REQUEST(request)); g_assert(session_class->set_xml_user_props != NULL); session_class->set_xml_user_props(priv->session, params, n_params, xml); inf_connection_manager_group_send_to_connection( priv->subscription_group, priv->connection, xml ); return INFC_USER_REQUEST(request); }
/** * infc_session_proxy_get_group: * @proxy: A #InfcSessionProxy. * * Returns the group with all subscribed connections to the session, or %NULL * if the session is not subscribed. * * Returns: A #InfConnectionManagerGroup, or %NULL. **/ InfConnectionManagerGroup* infc_session_proxy_get_subscription_group(InfcSessionProxy* proxy) { g_return_val_if_fail(INFC_IS_SESSION_PROXY(proxy), NULL); return INFC_SESSION_PROXY_PRIVATE(proxy)->subscription_group; }
/** * infc_session_proxy_get_connection: * @proxy: A #InfcSessionProxy. * * Returns the connection that is used to transmit requests to the publisher * of the session, or %NULL if the session is not subscribed. * * Returns: A #InfXmlConnection, or %NULL. **/ InfXmlConnection* infc_session_proxy_get_connection(InfcSessionProxy* proxy) { g_return_val_if_fail(INFC_IS_SESSION_PROXY(proxy), NULL); return INFC_SESSION_PROXY_PRIVATE(proxy)->connection; }
/** * infc_session_proxy_set_connection: * @proxy: A #InfcSessionProxy. * @group: A #InfConnectionManagerGroup of subscribed connections. Ignored if * @connection is %NULL. * @connection: A #InfXmlConnection. * * Sets the subscription connection for the given session. The subscription * connection is the connection through which session requests are transmitted * during subscription. * * The subscription connection might be set even if the session is in * SYNCHRONIZING state in which case the session is immediately subscribed * after synchronization. Note that no attempt is made to tell the other end * about the subscription. * * When the subscription connection is being closed or replaced (by a * subsequent call to this function), all pending requests are dropped and * all users are set to be unavailable, but the session will not be closed, * so it may be reused by setting another subscription connection. However, * the session might not be synchronized again, but it is fully okay to close * the session by hand (using inf_session_close) and create a new session * that is synchronized. **/ void infc_session_proxy_set_connection(InfcSessionProxy* proxy, InfConnectionManagerGroup* group, InfXmlConnection* connection) { InfcSessionProxyPrivate* priv; xmlNodePtr xml; g_return_if_fail(INFC_IS_SESSION_PROXY(proxy)); g_return_if_fail(connection == NULL || INF_IS_XML_CONNECTION(connection)); g_return_if_fail( (group == NULL && connection == NULL) || (group != NULL && connection != NULL) ); priv = INFC_SESSION_PROXY_PRIVATE(proxy); g_return_if_fail(priv->session != NULL); g_object_freeze_notify(G_OBJECT(proxy)); g_object_freeze_notify(G_OBJECT(priv->session)); if(priv->connection != NULL) { /* Unsubscribe from running session. Always send the unsubscribe request * because synchronizations are not cancelled through this call. */ xml = xmlNewNode(NULL, (const xmlChar*)"session-unsubscribe"); inf_connection_manager_group_send_to_connection( priv->subscription_group, priv->connection, xml ); /* Note that this would cause a notify on the connection property, but * notifications have been freezed until the end of this function call. * Same with the subscription-group property of priv->session. */ infc_session_proxy_release_connection(proxy); } priv->connection = connection; if(connection != NULL) { priv->connection = connection; g_object_ref(G_OBJECT(connection)); g_signal_connect( G_OBJECT(connection), "notify::status", G_CALLBACK(infc_session_proxy_connection_notify_status_cb), proxy ); /* Set new group */ priv->subscription_group = group; inf_connection_manager_group_ref(priv->subscription_group); } inf_session_set_subscription_group(priv->session, priv->subscription_group); g_object_notify(G_OBJECT(proxy), "connection"); g_object_notify(G_OBJECT(proxy), "subscription-group"); g_object_thaw_notify(G_OBJECT(priv->session)); g_object_thaw_notify(G_OBJECT(proxy)); }
void Gobby::UserJoinCommands::on_document_removed(InfBrowser* browser, const InfBrowserIter* iter, InfSessionProxy* proxy, Folder& folder, SessionView& view) { g_assert(proxy != NULL); UserJoinMap::iterator user_iter = m_user_join_map.find(proxy); // If the user join was successful the session is no longer in the map if(user_iter != m_user_join_map.end()) { delete user_iter->second; m_user_join_map.erase(user_iter); } else { // The user has removed the document. What we do now depends // on whether we are hosting the document or whether we are a // client. If we are a client we reset the connection of the // session proxy, which basically leads to us being // unsubscribed from the document. If we are hosting the // document, we do not want to unsubscribe from it, since // other users might still be connected. We therefore only // remove the local user from the session. If there are indeed // no other clients, then InfdDirectory will take care of // unsubscribing the session 60s after it became idle. if(INFD_IS_SESSION_PROXY(proxy)) { InfUser* user = view.get_active_user(); if(user != NULL) { InfSession* session; g_object_get(G_OBJECT(proxy), "session", &session, NULL); inf_session_set_user_status( session, user, INF_USER_UNAVAILABLE); g_object_unref(session); // TODO: set_active_user should go to // SessionView base: // TODO: The libinftextgtk objects should // reset the active user automatically when it // becomes unavailable. TextSessionView* text_view = dynamic_cast<TextSessionView*>(&view); if(text_view) text_view->set_active_user(NULL); ChatSessionView* chat_view = dynamic_cast<ChatSessionView*>(&view); if(chat_view) chat_view->set_active_user(NULL); } } else if(INFC_IS_SESSION_PROXY(proxy)) { infc_session_proxy_set_connection( INFC_SESSION_PROXY(proxy), NULL, NULL, 0); } } }