You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ChatHub.cs 4.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using Diligent.WebAPI.Data.Entities;
  2. using Diligent.WebAPI.Host.DTOs.Notification;
  3. using Diligent.WebAPI.Host.DTOs.Chat;
  4. using Diligent.WebAPI.Host.Mediator.Chat.Commands;
  5. using Diligent.WebAPI.Host.Mediator.Messages.Commands;
  6. using Diligent.WebAPI.Host.Mediator.Notifications.Commands;
  7. using MediatR;
  8. using Microsoft.AspNetCore.Authorization;
  9. using Microsoft.AspNetCore.SignalR;
  10. using Diligent.WebAPI.Host.Middlewares;
  11. namespace Diligent.WebAPI.Host.Hubs
  12. {
  13. public class ChatHub : Hub<IChatClient>
  14. {
  15. private readonly IDictionary<string, UserConnection> _connections;
  16. private readonly IMediator _mediator;
  17. public ChatHub(IDictionary<string, UserConnection> connections,IMediator mediator)
  18. {
  19. _connections = connections;
  20. _mediator = mediator;
  21. }
  22. [HubMethodName("SendMessageToGroup")]
  23. [AuthorizationHubFilter(Roles = "Customer,Support")]
  24. public async Task SendMessageToGroup(ChatMessage message)
  25. {
  26. // Find user's room and send message to everyone
  27. // All other users will receive notification
  28. if (_connections.TryGetValue(message.ConnId, out UserConnection room))
  29. {
  30. await Clients.Group(room.RoomId).ReceiveMessage(new ChatMessage { UserId = room.UserId, User = room.UserId, Message = message.Message, RoomId = room.RoomId });
  31. await _mediator.Send(new AddMessageCommand(room.RoomId, new Message { Content = message.Message, SenderId = message.UserId, Username = room.Username }));
  32. // Find other users in room and save notification in database
  33. foreach (KeyValuePair<string, UserConnection> conn in _connections)
  34. {
  35. if (conn.Value.RoomId == room.RoomId && conn.Key != message.ConnId)
  36. {
  37. await _mediator.Send(new AddNotificationCommand(new NotificationSaveDTO { RoomId = room.RoomId, ReceiverId = conn.Value.UserId }));
  38. }
  39. }
  40. await Clients.OthersInGroup(room.RoomId).ReceiveNotifications(room.UserId, room.RoomId);
  41. }
  42. }
  43. [HubMethodName("JoinRoom")]
  44. [AuthorizationHubFilter(Roles = "Customer,Support")]
  45. public async Task JoinRoom(UserConnection userConnection)
  46. {
  47. // Check is user in requested room
  48. var result = _connections.Where(x => x.Value.UserId == userConnection.UserId && x.Value.RoomId == userConnection.RoomId).FirstOrDefault();
  49. // If user is not in room, add him
  50. // Return message "User has joined room" to all users in room
  51. if (result.Value == null)
  52. {
  53. await Groups.AddToGroupAsync(Context.ConnectionId, userConnection.RoomId);
  54. _connections[Context.ConnectionId] = userConnection;
  55. await Clients.Group(userConnection.RoomId).ReceiveMessage(new ChatMessage { UserId = userConnection.UserId, User = userConnection.UserId, RoomId = userConnection.RoomId, Message = $"{userConnection.Username} has joined room", ConnId = Context.ConnectionId });
  56. }
  57. else
  58. {
  59. await _mediator.Send(new DeleteNotificationCommand(new NotificationDeleteDTO { UserId = userConnection.UserId, RoomId = userConnection.RoomId }));
  60. }
  61. }
  62. [HubMethodName("LeaveRoom")]
  63. [AuthorizationHubFilter(Roles = "Customer,Support")]
  64. public async Task LeaveRoom(LeaveChatRoomDTO connection)
  65. {
  66. if (_connections.TryGetValue(connection.ConnId, out UserConnection room))
  67. {
  68. // Find user connection in connections dictionary and delete it
  69. _connections.Remove(Context.ConnectionId);
  70. await Clients.OthersInGroup(room.RoomId).ReceiveMessage(new ChatMessage { UserId = room.UserId, User = room.UserId, Message = $"{room.Username} has left room", RoomId = room.RoomId });
  71. await _mediator.Send(new RemoveUserFromGroupCommand(room.RoomId, room.UserId));
  72. }
  73. }
  74. [HubMethodName("SeeWhoIsTyping")]
  75. public async Task SeeWhoIsTyping(TypingInvokeMessage message)
  76. {
  77. // Find user's room and send message to everyone
  78. if (_connections.TryGetValue(message.ConnId, out UserConnection room))
  79. {
  80. // send the typing info to all in group except the caller
  81. await Clients.GroupExcept(message.RoomId, message.ConnId).ViewTyping(new TypingMessage { RoomId = room.RoomId, Message = message.Message });
  82. }
  83. }
  84. }
  85. }