Связь в реальном времени с SignalR не работает в размещенном проекте ядра Angular 7 dotnet - PullRequest
0 голосов
/ 07 февраля 2019

Когда я запускаю этот проект на локальном хосте, он работает правильно. Но в размещенной среде он не работает. Я размещал этот проект на сервере Linux.

На стороне клиента я использовал @ aspnet / signalr":" ^ 1.0.4 " библиотека. На стороне сервера я использовал Microsoft.AspNetCore.SignalR 1.0.1 .

В размещенном сайте, иногда сообщение, отправленное после клиента, будетполучите его через несколько минут.

Вот код на стороне клиента

const WAIT_UNTIL_ASPNETCORE_IS_READY_DELAY_IN_MS = 2000;
@Injectable({
  providedIn: 'root'
})
export class HubconnectionService {
  _hubConnection: HubConnection;
  baseUrl = environment.apiUrl;
  retryRounds = 0;
  notificationsCount: number;
  notificationsCount$ = new Subject<number>();
  notifications: Notification;
  constructor(private alertify: AlertifyService) {
    this.notificationsCount = 0;
  }

  public startConnection() {
    setTimeout(() => {
      const usr: User = JSON.parse(localStorage.getItem('user'));
      this._hubConnection = new HubConnectionBuilder()
        .withUrl(this.baseUrl + 'hub?uid=' + usr.id)
        .build();
      this._hubConnection.start().then(() => {
        console.log('Hub connection started');
        this.registerOnServerEvents();
      }).catch(err => {
        this.alertify.error('Connection extablishment failed');
        console.log(err);
      });
    }, WAIT_UNTIL_ASPNETCORE_IS_READY_DELAY_IN_MS);

  }

  private registerOnServerEvents(): void {
    this._hubConnection.on('messageReceived', (username: string, message: string) => {
      this.alertify.message(username + ':' + message);
    });

    this._hubConnection.onclose(error => {
      this.retryRounds = this.retryRounds + 1;
      if (this.retryRounds <= 5) {
        setTimeout(() => {
          this.startConnection();
        }, 2000);
      }

    });

    this._hubConnection.on('notificationReceived', (noti: Notification) => {
      this.notificationsCount = this.notificationsCount + 1;
      this.notificationsCount$.next(this.notificationsCount);
      localStorage.setItem('notifications', JSON.stringify(noti));
      this.notifications = JSON.parse(localStorage.getItem('notifications'));
    });
  }

  public sendNewMessage(userId: string, message: string) {
    this._hubConnection.send('NewMessage', userId, message).catch(error => {
      console.log(error);
    });
  }

  public discconectConnection() {
    if (this._hubConnection) {
      this._hubConnection.send('Logout').catch(error => {
        console.log(error);
      });
      this.retryRounds = 0;
    } else {
      this.retryRounds = this.retryRounds + 1;
      if (this.retryRounds <= 5) {
        this.startConnection();
        setTimeout(() => {
          this.discconectConnection();
        }, 3000);
      }
    }

  }

  public sendNotification(adderId: string, toUserId: string, type: NotificationTypes) {
    if (this._hubConnection) {
      this.retryRounds = 0;
      this._hubConnection.send('SendNotification', adderId, toUserId, type).catch(error => {
        console.log(error);
      });
    } else {
      this.retryRounds = this.retryRounds + 1;
      if (this.retryRounds <= 5) {
        this.startConnection();
        setTimeout(() => {
          this.sendNotification(adderId, toUserId, type);
        }, 3000);
      }

    }

  }

  public clearNotificationCount() {
    this.notificationsCount$.next(0);
  }

Вот код файла StartUp.cs

public void ConfigureServices(IServiceCollection services)
        {
                 .....
                services.AddSignalR();
        }

  public void Configure(IApplicationBuilder app, IHostingEnvironment env,     Seed seeder, ILoggerFactory loggerFactory)
        {
              app.UseSignalR(routes =>
                  {
                      routes.MapHub<MessageHub>("/hub");
                  });
        }

Вот класс MessageHub.csкод

public class MessageHub : Hub
    {
        private readonly DataContext _context;
        static List<UserConnection> uList = new List<UserConnection>();
        public MessageHub(DataContext context)
        {
            _context = context;
        }

        public override async Task OnConnectedAsync()
        {

            var httpContext = Context.GetHttpContext();
            var uId = httpContext.Request.Query["uid"];
            var user = uList.FirstOrDefault(u => u.UserId == uId[0]);
            if (user != null)
            {
                user.ConnectionID = Context.ConnectionId;
            }
            else
            {
                var us = new UserConnection();
                us.UserId = uId[0];
                us.ConnectionID = Context.ConnectionId;
                uList.Add(us);
            }
             var logoutInUser = await _context.Users.FirstOrDefaultAsync(u => u.Id == Guid.Parse(uId));
                logoutInUser.LastActive = DateTime.Now;
                await _context.SaveChangesAsync();
            await base.OnConnectedAsync();
        }

        public override async Task OnDisconnectedAsync(Exception exception)
        {

            var user = uList.FirstOrDefault(u => u.ConnectionID == Context.ConnectionId);
            if (user != null)
            {
                uList.Remove(user);
                var logoutUser = await _context.Users.FirstOrDefaultAsync(u => u.Id == Guid.Parse(user.UserId));
                logoutUser.LastActive = DateTime.Now;
                await _context.SaveChangesAsync();
            }
            await base.OnDisconnectedAsync(exception);
        }

        public async Task NewMessage(string userId, string message)
        {
            var user = uList.FirstOrDefault(u => u.UserId == userId);
            if (user != null)
            {
                await Clients.Client(user.ConnectionID).SendAsync("messageReceived", userId, message);
            }

        }

        public async Task Logout()
        {
            var user = uList.FirstOrDefault(u => u.ConnectionID == Context.ConnectionId);
            if (user != null)
            {
                uList.Remove(user);
                var logoutUser = await _context.Users.FirstOrDefaultAsync(u => u.Id == Guid.Parse(user.UserId));
                logoutUser.LastActive = DateTime.Now;
                await _context.SaveChangesAsync();
            }

        }

        public async Task SendNotification(string adderId, string toSendUserId, NotificationTypes type)
        {
            var user = uList.FirstOrDefault(u => u.UserId == toSendUserId);
            var notificationDetails = await (from usr in _context.Users
                                     join photo in _context.Photos on usr.Id equals photo.UserId
                                     where usr.Id == Guid.Parse(adderId) && photo.IsMain == true
                                     select new Notification
                                     {
                                         UserId = usr.Id.ToString(),
                                         Username = usr.FirstName,
                                         PhotoUrl = photo.Url,
                                         Type = type
                                     }).FirstOrDefaultAsync();
            if (user != null && notificationDetails != null)
            {
                await Clients.Client(user.ConnectionID).SendAsync("notificationReceived", notificationDetails);
            }
        }

    }

Пожалуйста, помогите мне решить эту проблему.

...