public async Task Upload(string userId, string connectionId, string roomName, string file, string contentType, Stream stream) { UploadResult result; ChatMessage message; try { result = await _processor.HandleUpload(file, contentType, stream, stream.Length); if (result == null) { string messageContent = String.Format(LanguageResources.UploadFailed, Path.GetFileName(file)); _hubContext.Clients.Client(connectionId).postMessage(messageContent, "error", roomName); return; } else if (result.UploadTooLarge) { string messageContent = String.Format(LanguageResources.UploadTooLarge, Path.GetFileName(file), (result.MaxUploadSize / 1048576f).ToString("0.00")); _hubContext.Clients.Client(connectionId).postMessage(messageContent, "error", roomName); return; } // Add the message to the persistent chat message = _service.AddMessage(userId, roomName, result.Url); // Keep track of this attachment _service.AddAttachment(message, file, contentType, stream.Length, result); } catch (Exception ex) { string messageContent = String.Format(LanguageResources.UploadFailedException, Path.GetFileName(file), ex.Message); _hubContext.Clients.Client(connectionId).postMessage(messageContent, "error", roomName); return; } var messageViewModel = new MessageViewModel(message); // Notify all clients for the uploaded url _hubContext.Clients.Group(roomName).addMessage(messageViewModel, roomName); _resourceProcessor.ProcessUrls(new[] { result.Url }, _hubContext.Clients, roomName, message.Id); }
public async Task Upload(string userId, string connectionId, string roomName, string file, string contentType, Stream stream) { if (stream.Length > _settings.MaxFileUploadBytes) { _hubContext.Clients.Client(connectionId).postMessage("Unable to upload " + Path.GetFileName(file) + " because it exceeded the maximum size allowed.", "error", roomName); return; } UploadResult result; ChatMessage message; try { result = await _processor.HandleUpload(file, contentType, stream); if (result == null) { _hubContext.Clients.Client(connectionId).postMessage("Failed to upload " + Path.GetFileName(file) + ".", "error", roomName); return; } // Add the message to the persistent chat message = _service.AddMessage(userId, roomName, result.Url); // Keep track of this attachment _service.AddAttachment(message, file, contentType, stream.Length, result); } catch (Exception ex) { _hubContext.Clients.Client(connectionId).postMessage("Failed to upload " + Path.GetFileName(file) + ". " + ex.Message, "error", roomName); return; } var messageViewModel = new MessageViewModel(message); // Notify all clients for the uploaded url _hubContext.Clients.Group(roomName).addMessage(messageViewModel, roomName); _resourceProcessor.ProcessUrls(new[] { result.Url }, _hubContext.Clients, roomName, message.Id); }
public bool Send(ClientMessage message) { bool outOfSync = OutOfSync; SetVersion(); // Sanitize the content (strip and bad html out) message.Content = HttpUtility.HtmlEncode(message.Content); // See if this is a valid command (starts with /) if (TryHandleCommand(message.Content, message.Room)) { return outOfSync; } string id = GetUserId(); ChatUser user = _repository.VerifyUserId(id); ChatRoom room = _repository.VerifyUserRoom(_cache, user, message.Room); // REVIEW: Is it better to use _repository.VerifyRoom(message.Room, mustBeOpen: false) // here? if (room.Closed) { throw new InvalidOperationException(String.Format("You cannot post messages to '{0}'. The room is closed.", message.Room)); } // Update activity *after* ensuring the user, this forces them to be active UpdateActivity(user, room); HashSet<string> links; var messageText = ParseChatMessageText(message.Content, out links); ChatMessage chatMessage = _service.AddMessage(user, room, message.Id, messageText); var messageViewModel = new MessageViewModel(chatMessage); Clients[room.Name].addMessage(messageViewModel, room.Name); _repository.CommitChanges(); string clientMessageId = chatMessage.Id; // Update the id on the message chatMessage.Id = Guid.NewGuid().ToString("d"); _repository.CommitChanges(); if (!links.Any()) { return outOfSync; } ProcessUrls(links, room.Name, clientMessageId, chatMessage.Id); return outOfSync; }
public bool Send(ClientMessage message) { bool outOfSync = OutOfSync; SetVersion(); // See if this is a valid command (starts with /) if (TryHandleCommand(message.Content, message.Room)) { return outOfSync; } var userId = Context.User.Identity.Name; ChatUser user = _repository.VerifyUserId(userId); ChatRoom room = _repository.VerifyUserRoom(_cache, user, message.Room); // REVIEW: Is it better to use _repository.VerifyRoom(message.Room, mustBeOpen: false) // here? if (room.Closed) { throw new InvalidOperationException(String.Format("You cannot post messages to '{0}'. The room is closed.", message.Room)); } // Update activity *after* ensuring the user, this forces them to be active UpdateActivity(user, room); ChatMessage chatMessage = _service.AddMessage(user, room, message.Id, message.Content); var messageViewModel = new MessageViewModel(chatMessage); Clients.Group(room.Name).addMessage(messageViewModel, room.Name); _repository.CommitChanges(); string clientMessageId = chatMessage.Id; // Update the id on the message chatMessage.Id = Guid.NewGuid().ToString("d"); _repository.CommitChanges(); var urls = UrlExtractor.ExtractUrls(chatMessage.Content); if (urls.Count > 0) { ProcessUrls(urls, room.Name, clientMessageId, message.Id); } return outOfSync; }
public void Send(string content) { // If the client and server are out of sync then tell the client to refresh if (OutOfSync) { throw new InvalidOperationException("Chat was just updated, please refresh you browser"); } // Sanitize the content (strip and bad html out) content = HttpUtility.HtmlEncode(content); // See if this is a valid command (starts with /) if (TryHandleCommand(content)) { return; } string roomName = Caller.activeRoom; string id = Caller.id; ChatUser user = _repository.VerifyUserId(id); ChatRoom room = _repository.VerifyUserRoom(user, roomName); // Update activity *after* ensuring the user, this forces them to be active UpdateActivity(user, room); HashSet<string> links; var messageText = ParseChatMessageText(content, out links); ChatMessage chatMessage = _service.AddMessage(user, room, messageText); var messageViewModel = new MessageViewModel(chatMessage); Clients[room.Name].addMessage(messageViewModel, room.Name); _repository.CommitChanges(); if (!links.Any()) { return; } ProcessUrls(links, room, chatMessage); }
public bool Send(ClientMessage message) { bool outOfSync = OutOfSync; SetVersion(); // Sanitize the content (strip and bad html out) message.Content = HttpUtility.HtmlEncode(message.Content); // See if this is a valid command (starts with /) if (TryHandleCommand(message.Content, message.Room)) { return outOfSync; } string id = Caller.id; ChatUser user = _repository.VerifyUserId(id); ChatRoom room = _repository.VerifyUserRoom(user, message.Room); // Update activity *after* ensuring the user, this forces them to be active UpdateActivity(user, room); HashSet<string> links; var messageText = ParseChatMessageText(message.Content, out links); ChatMessage chatMessage = _service.AddMessage(user, room, message.Id, messageText); var messageViewModel = new MessageViewModel(chatMessage); Clients[room.Name].addMessage(messageViewModel, room.Name); _repository.CommitChanges(); string clientMessageId = chatMessage.Id; // Update the id on the message chatMessage.Id = Guid.NewGuid().ToString("d"); _repository.CommitChanges(); if (!links.Any()) { return outOfSync; } ProcessUrls(links, room.Name, clientMessageId, chatMessage.Id); return outOfSync; }
public bool Send(ClientMessage clientMessage) { CheckStatus(); // See if this is a valid command (starts with /) if (TryHandleCommand(clientMessage.Content, clientMessage.Room)) { return true; } var userId = Context.User.Identity.Name; ChatUser user = _repository.VerifyUserId(userId); ChatRoom room = _repository.VerifyUserRoom(_cache, user, clientMessage.Room); if (room == null || (room.Private && !user.AllowedRooms.Contains(room))) { return false; } // REVIEW: Is it better to use _repository.VerifyRoom(message.Room, mustBeOpen: false) // here? if (room.Closed) { throw new InvalidOperationException(String.Format("You cannot post messages to '{0}'. The room is closed.", clientMessage.Room)); } // Update activity *after* ensuring the user, this forces them to be active UpdateActivity(user, room); // Create a true unique id and save the message to the db string id = Guid.NewGuid().ToString("d"); ChatMessage chatMessage = _service.AddMessage(user, room, id, clientMessage.Content); _repository.CommitChanges(); var messageViewModel = new MessageViewModel(chatMessage); if (clientMessage.Id == null) { // If the client didn't generate an id for the message then just // send it to everyone. The assumption is that the client has some ui // that it wanted to update immediately showing the message and // then when the actual message is roundtripped it would "solidify it". Clients.Group(room.Name).addMessage(messageViewModel, room.Name); } else { // If the client did set an id then we need to give everyone the real id first Clients.OthersInGroup(room.Name).addMessage(messageViewModel, room.Name); // Now tell the caller to replace the message Clients.Caller.replaceMessage(clientMessage.Id, messageViewModel, room.Name); } // Add mentions AddMentions(chatMessage); var urls = UrlExtractor.ExtractUrls(chatMessage.Content); if (urls.Count > 0) { _resourceProcessor.ProcessUrls(urls, Clients, room.Name, chatMessage.Id); } return true; }
public bool Send(ClientMessage clientMessage) { CheckStatus(); // reject it if it's too long if (_settings.MaxMessageLength > 0 && clientMessage.Content.Length > _settings.MaxMessageLength) { throw new HubException(String.Format(LanguageResources.SendMessageTooLong, _settings.MaxMessageLength)); } // See if this is a valid command (starts with /) if (TryHandleCommand(clientMessage.Content, clientMessage.Room)) { return true; } var userId = Context.User.GetUserId(); var user = _repository.VerifyUserId(userId); var room = _repository.VerifyUserRoom(_cache, user, clientMessage.Room); var roomUserData = _repository.GetRoomUserData(user, room); if (room == null || (room.Private && !user.AllowedRooms.Contains(room))) { return false; } // REVIEW: Is it better to use the extension method room.EnsureOpen here? if (room.Closed) { throw new HubException(String.Format(LanguageResources.SendMessageRoomClosed, clientMessage.Room)); } if (roomUserData.IsMuted) { throw new InvalidOperationException(String.Format("You cannot post messages to '{0}'. You have been muted.", clientMessage.Room)); } // Update activity *after* ensuring the user, this forces them to be active UpdateActivity(user, room); string id = clientMessage.Id; ChatMessage chatMessage = _repository.GetMessageById(id); if (chatMessage == null) { // Create a true unique id and save the message to the db id = Guid.NewGuid().ToString("d"); chatMessage = _service.AddMessage(user, room, id, clientMessage.Content); _repository.CommitChanges(); } else if (chatMessage.User == user) { chatMessage.Content = clientMessage.Content; chatMessage.HtmlContent = null; chatMessage.Edited = DateTimeOffset.UtcNow; _repository.Update(chatMessage); _repository.CommitChanges(); } else { throw new InvalidOperationException(String.Format("You cannot edit a message you do not own.")); } var messageViewModel = new MessageViewModel(chatMessage); if (clientMessage.Id == null) { // If the client didn't generate an id for the message then just // send it to everyone. The assumption is that the client has some ui // that it wanted to update immediately showing the message and // then when the actual message is roundtripped it would "solidify it". Clients.Group(room.Name).addMessage(messageViewModel, room.Name); } else { // If the client did set an id then we need to give everyone the real id first Clients.OthersInGroup(room.Name).addMessage(messageViewModel, room.Name); // Now tell the caller to replace the message Clients.Caller.replaceMessage(clientMessage.Id, messageViewModel, room.Name); } // Add mentions AddMentions(chatMessage); var urls = UrlExtractor.ExtractUrls(chatMessage.Content); if (urls.Count > 0) { _resourceProcessor.ProcessUrls(urls, Clients, room.Name, chatMessage.Id); } return true; }