I seems that the "connection.invoke" is used to invoke the method in the Hub of SignalR server while the JoinRoom is an ordinary action method of ASP.NET MVC. Does it work? I guess that you do not need SignalR. If so, why don't you use fetch or jQuery ajax to call the server-side method from client?
Can't JoinRoom by Id
Hi, I am a student working on a school project, I am new to this, It is my first time doing NextJs with TypeScript, I also researched but did not see any working solution. I really do not know where the problem is. I would very much appreciate if there are any solutions.
I have a method JoinRoom, but It seems can not invoke or something, I use NextJs for Frontend, and everything works fine. but not the joinRoom. I don't know if the problem was on the data or anything, I tried but did not come up to anything. If anything missing, just let me know I will provide it asap.
here JoinRoom method:
public async Task JoinRoom(MessageViewModel model, string userId)
{
_logger.LogInformation("User {User} attempting to join room {RoomName}", model.FullName, model.RoomName);
try
{
var room = await _context.Rooms.FirstOrDefaultAsync(r => r.Name == model.RoomName);
if (room == null)
{
_logger.LogWarning("Room {RoomName} does not exist", model.RoomName);
throw new ArgumentException("Room does not exist");
}
var user = await _context.Users.FirstOrDefaultAsync(u => u.Id == userId);
if (user == null)
{
_logger.LogWarning("User not found: {UserId}", userId);
throw new ArgumentException("User not found");
}
room.RoomUsers.Add(new RoomUser
{
RoomId = room.RoomId,
Id = user.Id,
IsMember = true,
FullName = user.FullName,
});
await _context.SaveChangesAsync();
await Groups.AddToGroupAsync(Context.ConnectionId, model.RoomName);
await Clients.Group(model.RoomName).SendAsync("UserJoined", user.FullName);
_logger.LogInformation("User {User} successfully joined room {RoomName}", model.FullName, model.RoomName);
}
catch (ArgumentException ex)
{
_logger.LogWarning(ex, "Validation error while joining room {RoomName}", model.RoomName);
await Clients.Caller.SendAsync("JoinRoomError", "Validation error: " + ex.Message);
}
catch (DbUpdateException dbEx)
{
_logger.LogError(dbEx, "Database error while joining room {RoomName}", model.RoomName);
await Clients.Caller.SendAsync("JoinRoomError", "Database error: " + dbEx.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error while joining room {RoomName}", model.RoomName);
await Clients.Caller.SendAsync("JoinRoomError", "Unexpected error: " + ex.Message);
}
}
here Model, and ViewModel are related:
using System.ComponentModel.DataAnnotations.Schema;
namespace ChatApp_BE.Models;
public class RoomUser
{
public string Id { get; set; } = string.Empty;
public int RoomId { get; set; }
public string FullName { get; set; } = string.Empty;
public bool IsMember { get; set; }
[ForeignKey("RoomId")]
public virtual Room Room { get; set; } = null!;
[ForeignKey("Id")]
public virtual ApplicationUser User { get; set; } = null!;
}
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ChatApp_BE.Models
{
public class Room
{
[Key]
public int RoomId { get; set; }
public string? Name { get; set; } = null!;
public string? CreatedBy { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public string? Id { get; set; } = string.Empty; // UserId
[ForeignKey("Id")]
public virtual ApplicationUser? User { get; set; }
public virtual ICollection<Message> Messages { get; set; } = new List<Message>();
public virtual ICollection<RoomUser> RoomUsers { get; set; } = new List<RoomUser>();
}
}
public class RoomViewModel
{
public int RoomId { get; set; }
public string? RoomName { get; set; }
public string? CreatedBy { get; set; }
public string? UserId { get; set; } // Add UserId field
public List<RoleUserViewModel>? Members { get; set; }
}
here the joinRoom method in FE:
const handleJoinRoom = async () => {
const userId = localStorage.getItem("USER_ID");
const fullName = localStorage.getItem("FULL_NAME");
if (joinRoomId !== null && connection && userId && fullName) {
try {
await connection.invoke("JoinRoom", {
RoomId: joinRoomId,
FullName: fullName,
UserId: userId,
IsMember: true,
});
toast.success("Joined room successfully!", {
duration: 5000,
position: "top-right",
action: {
label: "X",
onClick: () => toast.dismiss(),
},
});
setJoinRoomId(null);
setIsJoinModalOpen(false);
} catch (error) {
toast.error("Failed to join room.", {
duration: 5000,
position: "top-right",
action: {
label: "X",
onClick: () => toast.dismiss(),
},
});
console.error("SignalR JoinRoom Error: ", error);
}
}
};