我试图创建一个多人聊天网络应用程序,当一个用户加入一个房间,我需要发送消息给其他用户,该用户已经加入,但由于某种原因,该消息正在发送给当前用户谁加入了房间,以及我用BullsInGroup,以确保它不会被发送到当前用户.
the log message when first joined
当我刷新页面时,我得到No client method with the name 'userjoined' found in signalR
错误在我的控制台
log message after some refresh
RoomHub.cs
// ChatHub.cs
using System.Text.Json;
using GuessMySketch.Data;
using Microsoft.AspNetCore.SignalR;
public class RoomHub : Hub
{
private readonly AppDbContext _context;
public RoomHub(AppDbContext context)
{
_context = context;
}
public async Task SendMessage(string roomId, string message)
{
await Clients.OthersInGroup(roomId).SendAsync("ReceiveMessage", message);
}
public async Task SendCanvasData(Coordinate originalPosition, Coordinate newPosition, string activeColor, string roomId)
{
await Clients.OthersInGroup(roomId).SendAsync("ReceiveCanvasData", new CanvasData { originalPosition = originalPosition, newPosition = newPosition, activeColor = activeColor });
}
public async Task ClearData(string roomId)
{
await Clients.OthersInGroup(roomId).SendAsync("ClearCanvas");
}
public async Task NextRound(string roomId)
{
await Clients.Group(roomId).SendAsync("ClearCanvas");
}
public override async Task OnConnectedAsync()
{
var httpContext = Context.GetHttpContext();
var roomId = httpContext.Request.Cookies["room"].ToString();
var username = httpContext.Request.Cookies["user"].ToString();
Console.WriteLine(username);
await Groups.AddToGroupAsync(Context.ConnectionId, roomId);
await Clients.OthersInGroup(roomId).SendAsync("UserJoined", username);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception? exception)
{
// await Groups.RemoveFromGroupAsync(Context.ConnectionId, roomId);
// Perform actions when a user disconnects
await base.OnDisconnectedAsync(exception);
}
}
public class Coordinate
{
public float x { get; set; }
public float y { get; set; }
}
public class CanvasData
{
public Coordinate originalPosition { get; set; } = null!;
public Coordinate newPosition { get; set; } = null!;
public string activeColor { get; set; } = null!;
}
Program.cs
using Newtonsoft.Json;
using GuessMySketch.Data;
using GuessMySketch.DTO;
using GuessMySketch.Models;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
{
builder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithOrigins("http://localhost:3000");
}));
builder.Services.AddScoped<IRoomRepo, RoomRepo>();
builder.Services.AddSignalR();
builder.Services.AddControllers();
builder.Services.AddDbContext<AppDbContext>(opt => opt.UseNpgsql(builder.Configuration.GetConnectionString("WebApiDatabase")));
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseCors("CorsPolicy");
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<RoomHub>("/room", options =>
{
options.Transports = HttpTransportType.WebSockets;
});
});
app.MapPost("/createRoom", async (HttpContext context, IRoomRepo repo, [FromBody] CreateRoomDto createRoomDto) =>
{
SessionReadDto session = await repo.CreateRoom(createRoomDto.name);
if (session != null && session.Data != null)
{
// Set the JSON string as a cookie value
context.Response.Cookies.Append("room", session.Data.Code, new CookieOptions { Expires = DateTime.Now.AddHours(24), Secure = true, HttpOnly = true, SameSite = SameSiteMode.None });
context.Response.Cookies.Append("user", session.Data.Username.ToString(), new CookieOptions { Expires = DateTime.Now.AddHours(24), Secure = true, HttpOnly = true, SameSite = SameSiteMode.None });
return Results.Created($"/users/{session.Data.Code}", session.Data.Code);
}
else if (session != null && session.Message != null)
{
return Results.BadRequest(new { error = session.Message });
}
return Results.BadRequest(new { error = "something went wrong" });
});
app.MapPost("/joinRoom", async (HttpContext context, IRoomRepo repo, [FromBody] JoinRoomDto joinRoomDto) =>
{
SessionReadDto session = await repo.JoinRoom(joinRoomDto);
if (session != null && session.Data != null)
{
// Set the JSON string as a cookie value
context.Response.Cookies.Append("room", session.Data.Code, new CookieOptions { Expires = DateTime.Now.AddHours(24), Secure = true, HttpOnly = true, SameSite = SameSiteMode.None });
context.Response.Cookies.Append("user", session.Data.Username.ToString(), new CookieOptions { Expires = DateTime.Now.AddHours(24), Secure = true, HttpOnly = true, SameSite = SameSiteMode.None });
return Results.Created($"/users/{session.Data.Code}", session.Data.Code);
}
else if (session != null && session.Message != null)
{
return Results.BadRequest(new { error = session.Message });
}
return Results.BadRequest(new { error = "something went wrong" });
});
app.UseAuthorization();
app.MapControllers();
app.Run();
Room.jsx:
const [connection, setConnection] = useState(null)
useEffect(() => {
async function makeConnection() {
const socketConnection = new HubConnectionBuilder()
.configureLogging(LogLevel.Debug)
.withUrl('http://localhost:5028/room', {
skipNegotiation: true,
transport: HttpTransportType.WebSockets,
withCredentials: true,
})
.build()
await socketConnection.start()
setConnection(socketConnection)
}
makeConnection()
}, [])
connection &&
connection.on('UserJoined', (message) => {
console.log(message)
})
如果有任何问题,在我的设置,请让我知道,因为我已经尝试调试了一段时间
我尝试使用其他方法,如GroupExcept和控制台记录connectionId
1条答案
按热度按时间qzwqbdag1#
我弄清楚了问题所在,原来我试图用我在react中设置的Web套接字进行多个连接。
我把它改成了下面的样子,一切正常: