将 SignalR Server 上传到 Windows Server IIS

问题描述 投票:0回答:1

我使用 SignalR 作为实时技术,使用 .NET 6.0 完成了通知服务。我需要将此后端上传到 Windows Server,以便我可以尝试该项目,但是,当我上传时,我遇到了一些错误。

我已在 IIS 上启用 Web 套接字

这是我的 web.config:

    <?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="/Connect" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\NotificationService.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
  </location>
</configuration>

如您所见,我已将 SignalR Hub 的路径(/Connect)添加到 web.config 中。 我已经安装了 SDK,并且还从服务器管理器启用了 Web 套接字功能。

我将在下面与您分享后端的代码:

这是我的程序.cs:

//JWT Bearer
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
    o.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidAudience = builder.Configuration["Jwt:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("siudhg987IJHASDhaisd7ASDihasdjkqUIHasd123098345ASOIDU"))
    };
    o.TokenValidationParameters = new TokenValidationParameters
    {
     
        IssuerSigningKey = new SymmetricSecurityKey
            (Encoding.UTF8.GetBytes(builder.Configuration["secreatKey"])),
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = false,
        ValidateIssuerSigningKey = true
    };

    o.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            var accessToken = context.Request.Query["access_token"];

            // If the request is for our hub...
            var path = context.HttpContext.Request.Path;
            if (!string.IsNullOrEmpty(accessToken) &&
                (path.StartsWithSegments("/Connect"))) // Change "/Connect" to your hub route
            {
                // Read the token from the query string
                context.Token = accessToken;
            }
            return Task.CompletedTask;
        }
    };
});
//Rabbit
builder.Services.AddScoped<IRabbitConnection, RabbitConnection>();
//SignalR
builder.Services.AddSignalR();
builder.Services.AddSignalR(opt => { opt.HandshakeTimeout = TimeSpan.MaxValue; });
builder.Services.AddSingleton<INotificationServiceRepository, NotificationServiceRepository>();
builder.Services.AddSingleton<IUserConnectionManager, UserConnectionManager>();
builder.Services.AddSingleton<INotificationStore,MemoryNotificationStore>();
builder.Services.AddSingleton<NotificationMemoryStorage>();

builder.Services.AddScoped<INotificationServiceRepository, NotificationServiceRepository>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseCors();
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseWebSockets(); ;
//Ruta para conectarse al servidor de ws
app.MapHub<NotificationHub>("/Connect");

app.UseAuthorization();

app.MapControllers();

app.Run();

这是我的中心:

  public class NotificationHub : Hub<INotificationHub>
    {
        private readonly IUserConnectionManager _userConnectionManager;
        private readonly INotificationStore _notificationStore;

        public NotificationHub(IUserConnectionManager userConnectionManager, INotificationStore notificationStore)
        {
            _userConnectionManager = userConnectionManager;
            _notificationStore = notificationStore;
        }

        //<------------------------------------------------------------------------------->

        public override async Task OnConnectedAsync()
        {
            var token = Context.GetHttpContext().Request.Headers["access_token"];

            if (!string.IsNullOrEmpty(token))
            {
                var result = await UserConnectionAsync(token);
                await Clients.Client(Context.ConnectionId).ConnectionResponse(result.response);

                if (result.succesfulConnection)
                {
                    await SendStoredNotifications(result.userId);
                }
                else
                {
                    var response = new ServerResponse
                    {
                        status = "Rejected",
                        message = "Error en la autorizacion"
                    };
                    await Clients.Client(Context.ConnectionId).ConnectionResponse(response);
                    Context.Abort();
                }
            }
            else
            {
                var response = new ServerResponse
                {
                    status = "Rejected",
                    message = "Token no proporcionado"
                };
                await Clients.Client(Context.ConnectionId).ConnectionResponse(response);
                Context.Abort();
            }
        }

        //<------------------------------------------------------------------------------->
        private async Task<(bool succesfulConnection, ServerResponse response, string userId)> UserConnectionAsync(string token)
        {
            var handler = new JwtSecurityTokenHandler();
            var jsonToken = handler.ReadToken(token) as JwtSecurityToken;

            if (jsonToken != null)
            {
                string userId = jsonToken.Claims.FirstOrDefault(claim => claim.Type == "email" || claim.Type == "uid")?.Value;
                var response = new ServerResponse();
                if (!string.IsNullOrEmpty(userId))
                {
                    await GetConnectionId(userId);
                    response.status = "Accepted";
                    response.message = "Conexion Exitosa";
                    return (true, response, userId);
                }
                else
                {
                    response.status = "Rejected";
                    response.message = "Error en la autorizacion";
                    return (false, response, null);
                }
            }
            else
            {
                var response = new ServerResponse
                {
                    status = "Rejected",
                    message = "Error en la autorizacion"
                };
                return (false, response, null);
            }
        }

        //<------------------------------------------------------------------------------->

        private async Task SendStoredNotifications(string userId)
        {
            if (!string.IsNullOrEmpty(userId))
            {
                var notifications = _notificationStore.RetrieveNotifications(userId);

                foreach (var notification in notifications)
                {
                    await Clients.Client(Context.ConnectionId).SendNotification(notification);
                }

                _notificationStore.ClearNotifications(userId);
            }
        }

        //<------------------------------------------------------------------------------->
        public async Task<string> GetConnectionId(string userId)
        {
            _userConnectionManager.KeppUserConnection(userId, Context.ConnectionId);
            return Context.ConnectionId;
        }

        //<------------------------------------------------------------------------------->

        public override async Task OnDisconnectedAsync(Exception? exception)
        {
            var connectionId = Context.ConnectionId;
            _userConnectionManager.RemoveUserConnection(connectionId);
            await base.OnDisconnectedAsync(exception);
        }

        //<------------------------------------------------------------------------------->

        public async Task MessageCheck(NotificationRequestModel request)
        {
            //meter validaciones
            switch (request.Target.Device)
            {
                case "Admin":
                    if (request.Target.User.Contains("*"))
                    {
                        SendNotificationToAllUsers(request.Notification);
                    }
                    else
                    {
                        SendNotificationToSpecificUser(request.Notification, request.Target.User);
                    }
                    break;
               
            }
        }

        //<------------------------------------------------------------------------------------->

        public async Task SendNotificationToAllUsers(NotificationModel message)
        {
            var allUserIds = _userConnectionManager.GetAllUserIds();
            foreach (var userId in allUserIds)
            {
                var connectionsIds = _userConnectionManager.GetUserConnections(userId);
                if (connectionsIds.Any())
                {
                    foreach (var connectionId in connectionsIds)
                    {
                        await Clients.Client(connectionId).SendNotification(message);
                    }
                }
                else
                {
                    _notificationStore.StoreNotification(userId, message);
                }
            }
        }

        //<------------------------------------------------------------------------------->

        public async Task SendNotificationToSpecificUser(NotificationModel message, List<string> target)
        {
            foreach (var userId in target)
            {
                var connectionIds = _userConnectionManager.GetUserConnections(userId);
                if (connectionIds.Count() > 0)
                {
                    foreach (var connectionId in connectionIds)
                    {
                        await Clients.Client(connectionId).SendNotification(message);
                    }
                }
                else
                {
                    _notificationStore.StoreNotification(userId, message);
                }
            }
        }

        //<------------------------------------------------------------------------------->
    }

我对代码表示歉意。

在我的 launchsettings.json 中,我激活了 IIS Express:

"IIS Express": {
   "commandName": "IISExpress",
   "launchBrowser": true,
   "launchUrl": "swagger",
   "environmentVariables": {
     "ASPNETCORE_ENVIRONMENT": "Development"
   }

我也尝试通过邮递员连接: HTTP:

WS:

我做错了什么或者我错过了什么? 老实说,我不知道我在做什么。

.net iis signalr signalr-hub windows-server
1个回答
0
投票

请不要使用

/Connect

app.MapHub<NotificationHub>("/Connect");

我们可以使用其他词语,如

MainHub
Test1
等等。

app.MapHub<NotificationHub>("/MainHub");
app.MapHub<NotificationHub>("/Test1");
© www.soinside.com 2019 - 2024. All rights reserved.