/// <summary> /// Inserts a chat user. /// </summary> /// <param name="chatRoom">The chat room which contains the user.</param> /// <param name="chatUser">The chat user to add.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual Task AddUserAsync(ChatRoomInfo chatRoom, ChatUserInfo chatUser, CancellationToken cancellationToken) { ThrowIfDisposed(); if (chatRoom == null) { throw new ArgumentNullException("chatRoom"); } if (chatUser == null) { throw new ArgumentNullException("chatUser"); } chatUser.RoomId = chatRoom.Id; var users = s_users.Get(chatRoom.Id) as ConcurrentDictionary <string, ChatUserInfo>; if (users == null) { users = new ConcurrentDictionary <string, ChatUserInfo>(); } if (users.TryAdd(chatUser.UserName, chatUser)) { s_users.Set(chatRoom.Id, users, DateTimeOffset.MaxValue); } return(Task.FromResult(0)); }
/// <summary> /// Removes a connection from the given chat user. /// </summary> /// <param name="connectionId">The connection to remove.</param> /// <param name="chatUser">The chat user.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual Task RemoveConnectionFromUserAsync(string connectionId, ChatUserInfo chatUser, CancellationToken cancellationToken) { ThrowIfDisposed(); if (string.IsNullOrEmpty(connectionId)) { throw new ArgumentNullException("connectionId"); } if (chatUser == null) { throw new ArgumentNullException("chatUser"); } var roomKey = chatUser.RoomId; var roomConnectionIds = s_roomConnections.Get(roomKey) as ImmutableHashSet <string>; if (roomConnectionIds != null) { roomConnectionIds = roomConnectionIds.Remove(connectionId); s_roomConnections.Set(roomKey, roomConnectionIds, DateTimeOffset.MaxValue); } var roomUserKey = chatUser.RoomId + chatUser.UserName; var userConnectionIds = s_userConnections.Get(roomUserKey) as ImmutableHashSet <string>; if (userConnectionIds != null) { userConnectionIds = userConnectionIds.Remove(connectionId); s_userConnections.Set(roomUserKey, userConnectionIds, DateTimeOffset.MaxValue); } s_connections.Remove(connectionId); return(Task.FromResult(0)); }
/// <summary> /// Adds a connection ID to the given chat room. /// </summary> /// <param name="connectionId">The connection to add.</param> /// <param name="chatUser">The chat room.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual Task AddConnectionToUserAsync(string connectionId, ChatUserInfo chatUser, CancellationToken cancellationToken) { ThrowIfDisposed(); if (string.IsNullOrEmpty(connectionId)) { throw new ArgumentNullException("connectionId"); } if (chatUser == null) { throw new ArgumentNullException("chatUser"); } var roomKey = chatUser.RoomId; var roomUserKey = chatUser.RoomId + chatUser.UserName; var roomConnectionIds = s_roomConnections.Get(roomKey) as ImmutableHashSet <string>; var userConnectionIds = s_userConnections.Get(roomUserKey) as ImmutableHashSet <string>; roomConnectionIds = roomConnectionIds != null?roomConnectionIds.Add(connectionId) : ImmutableHashSet.Create(connectionId); userConnectionIds = userConnectionIds != null?userConnectionIds.Add(connectionId) : ImmutableHashSet.Create(connectionId); // Add the connection to the global connection cache, the room connection cache, // and the user connection cache because the memory cache does not support AppFabric-style tagging // This is used by the GetConnectionByIdAsync method because SignalR Hub's OnDisconnected event // can only work with a ConnectionID s_connections.Set(connectionId, new ChatConnection { RoomId = chatUser.RoomId, UserName = chatUser.UserName }, DateTimeOffset.MaxValue); s_roomConnections.Set(roomKey, roomConnectionIds, DateTimeOffset.MaxValue); s_userConnections.Set(roomUserKey, userConnectionIds, DateTimeOffset.MaxValue); return(Task.FromResult(0)); }
/// <summary> /// Gets all the Connection IDs for the given chat user. /// </summary> /// <param name="chatUser">The chat user.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual Task <IList <string> > GetConnectionsByUserAsync(ChatUserInfo chatUser, CancellationToken cancellationToken) { ThrowIfDisposed(); var userConnectionStore = GetUserConnectionStore(); if (chatUser == null) { throw new ArgumentNullException("chatUser"); } return(userConnectionStore.GetConnectionsByUserAsync(chatUser, cancellationToken)); }
/// <summary> /// Gets all the connections for the given chat user. /// </summary> /// <param name="chatUser">The chat room.</param> /// <param name="userName">The user name.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual Task <IList <string> > GetConnectionsByUserAsync(ChatUserInfo chatUser, CancellationToken cancellationToken) { ThrowIfDisposed(); if (chatUser == null) { throw new ArgumentNullException("chatUser"); } var connections = s_userConnections.Get(chatUser.RoomId + chatUser.UserName) as ImmutableHashSet <string>; if (connections != null) { return(Task.FromResult <IList <string> >(connections.ToList())); } return(Task.FromResult <IList <string> >(new List <string>())); }
/// <summary> /// Removes a chat user. /// </summary> /// <param name="chatRoom">The chat site which contains the user.</param> /// <param name="chatUser">The chat user to remove.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual async Task RemoveUserAsync(ChatRoomInfo chatRoom, ChatUserInfo chatUser, CancellationToken cancellationToken) { ThrowIfDisposed(); var userStore = GetUserStore(); if (chatRoom == null) { throw new ArgumentNullException("chatRoom"); } if (chatUser == null) { throw new ArgumentNullException("chatUser"); } await userStore.RemoveUserAsync(chatRoom, chatUser, cancellationToken); await UpdateAsync(chatRoom, cancellationToken); }
/// <summary> /// Gets a collection of event notifications with the given values. /// </summary> /// <param name="projectId">The project which owns the events occured.</param> /// <param name="clientId">The client who is the actor.</param> /// <param name="offset">The index of the page of results to return. Use 1 to indicate the first page.</param> /// <param name="limit">The size of the page of results to return. <paramref name="pageIndex" /> is non-zero-based.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual async Task <IList <ChatMessageInfo> > GetMessagesAsync(int projectId, string clientId, int offset, int limit, CancellationToken cancellationToken) { ThrowIfDisposed(); var manager = GetLogManager(); if (string.IsNullOrEmpty(clientId)) { throw new ArgumentNullException("clientId"); } var chatMessages = new List <ChatMessageInfo>(); var logMessages = await manager.FindAllMessagesAsync(projectId, clientId, offset, limit, cancellationToken); foreach (var logMessage in logMessages) { if (logMessage.CustomUri == null) { continue; } ChatUserInfo from; bool admin = false; if (logMessage.CustomUri != null) { admin = logMessage.CustomUri.EndsWith(">>", StringComparison.Ordinal); } if (logMessage.Contact != null) { from = new ChatUserInfo { ContactId = logMessage.Contact.Id, UserName = logMessage.Contact.Email.Address, NickName = logMessage.Contact.NickName, Admin = admin }; } else { from = new ChatUserInfo { UserName = clientId, NickName = clientId, Admin = admin }; } chatMessages.Add(new ChatMessageInfo { From = from, Message = logMessage.Message, CreatedDate = logMessage.StartDate }); } return(chatMessages); }
/// <summary> /// Gets or adds a new user to the given room. /// </summary> /// <param name="room">The room.</param> /// <param name="userName">The user name.</param> /// <param name="nickName">The nick name.</param> /// <param name="ipAddress">The IP address.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// The chat user. /// </returns> private async Task <ChatUserInfo> GetOrAddRoomUserAsync(ChatRoomInfo room, string userName, string ipAddress, CancellationToken cancellationToken = default(CancellationToken)) { int? contactId = null; string nickName = null; if (!string.IsNullOrEmpty(userName)) { var contact = await ChatManager.GetContactByUserNameAsync(room, userName, cancellationToken); if (contact != null) { contactId = contact.Id; userName = contact.Email.Address; nickName = contact.NickName ?? contact.Email.Name ?? contact.FirstName ?? contact.LastName; } } if (string.IsNullOrEmpty(userName)) { userName = ChatManager.GenerateClientId(ipAddress); nickName = nickName ?? userName; } var user = await ChatManager.GetUserByUserNameAsync(room, userName, cancellationToken); if (user == null) { user = new ChatUserInfo { ContactId = contactId, ClientId = ChatManager.GenerateClientId(ipAddress), IPAddress = ipAddress, UserName = userName, NickName = nickName }; await ChatManager.AddUserAsync(room, user, cancellationToken); } return(user); }
/// <summary> /// Removes a Connection ID from the given chat user. /// </summary> /// <param name="connectionId">The Connection ID to remove.</param> /// <param name="chatUser">The chat user.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual async Task RemoveConnectionFromUserAsync(string connectionId, ChatUserInfo chatUser, CancellationToken cancellationToken) { ThrowIfDisposed(); var userConnectionStore = GetUserConnectionStore(); if (chatUser == null) { throw new ArgumentNullException("chatUser"); } if (string.IsNullOrEmpty(connectionId)) { throw new ArgumentNullException("connectionId"); } var chatRoom = await FindByIdAsync(chatUser.RoomId, cancellationToken); if (chatRoom == null) { throw new InvalidOperationException("The chat room was not found."); } await userConnectionStore.RemoveConnectionFromUserAsync(connectionId, chatUser, cancellationToken); await UpdateAsync(chatRoom, cancellationToken); }