Метод работает не по плану

165
12 ноября 2021, 14:00

Всем здравствуйте, и так, есть чат переписки в приложении ASP.NET Core + Angular 8, суть проблемы в том, что когда переписываются между собой 2 пользователя, то все идет как надо, но если первый пользователь отправляет сообщение второму пользователю, а второй пользователь в этот момент находится в чате с третьим, то он все равно видит сообщение от первого пользователя... Надеюсь вы поняли эту цепочку. Как бы логика программы понятна, ведь сообщения от первого пользователя направлены второму, и по этому они появляются, но как сделать так, чтобы сообщения ограничивались одним чатом, т.е. первый пользователь пишет второму, а второй пока не зайдет в чат к первому, не будет получать сообщения? Бежим по коду: Сам чат на сервере:

public class ChatHub : Hub
    {   
        [Authorize]
        public async Task SendToAll(string name, string message, string to)
        {
            var userName = Context.User.Identity.Name;
            if (Context.UserIdentifier != to) // если получатель и текущий пользователь не совпадают
                await Clients.User(userName).SendAsync("Receive", name, message);
            await Clients.User(to).SendAsync("Receive", name, message);
        }
    }

Провайдер:

public class CustomUserIdProvider : IUserIdProvider
    {
        public virtual string GetUserId(HubConnectionContext connection)
        {
            return connection.User?.Identity.Name;
            // или так
            //return connection.User?.FindFirst(ClaimTypes.Name)?.Value;
        }
    }

Метод конфигурации стартапа

public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IUserIdProvider, CustomUserIdProvider>();
            services.AddSignalR();
            services.AddCors(options =>
            {
                options.AddPolicy("EnableCORS", builder =>
                {
                    builder.                    
                    AllowAnyOrigin().
                    AllowAnyHeader().
                    AllowAnyMethod().
                    WithOrigins("http://localhost:4200").
                    AllowCredentials();
                });
            });
            services.AddScoped<DBUserContext>();
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = "http://localhost:5000",
                    ValidAudience = "http://localhost:5000",
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@345"))
                };
                options.Events = new JwtBearerEvents
                {
                    OnMessageReceived = context =>
                    {
                        var accessToken = context.Request.Query["access_token"];
                        // если запрос направлен хабу
                        var path = context.HttpContext.Request.Path;
                        if (!string.IsNullOrEmpty(accessToken) &&
                             (path.StartsWithSegments("/chat")))
                        {
                            // получаем токен из строки запроса
                            context.Token = accessToken;
                        }
                        return Task.CompletedTask;
                    }
                };
            });

Компонент в ангуляре:

export class ChatComponent implements OnInit {
  constructor(private http: HttpClient, activeRoute: ActivatedRoute) {
    this.id = Number.parseInt(activeRoute.snapshot.params["id"]);
  }
  private _hubConnection: HubConnection;
  user: User;
  id: number;
  userForMessage: User;
  message:string = '';
  messages: string[] = [];
  bool: boolean = false;

  public sendMessage(): void {
    this._hubConnection
      .invoke('SendToAll', this.user.userName, this.message, this.userForMessage.userName)
      .then(() => this.message = '')
      .catch(err => console.error(err));
    this.save();
  }
  ngOnInit() {
    //this.nick = window.prompt('Your name:', 'John');
    let token = localStorage.getItem("jwt");
    //Получаем юзера, которому отправляем сообщение
    this.http.get(`http://localhost:5000/api/user/getuserformessage/${this.id}`
     ).subscribe((response: User) => {
       this.userForMessage = response;       
      }, err => {
        console.log(err)
        });
    //Юзер который отправляет сообщение
    this.http.get("http://localhost:5000/api/customers/getidenti", {
      headers: new HttpHeaders({
        "Authorization": "Bearer " + token,
        "Content-Type": "application/json"
      })
    }).subscribe((response: User) => {
      this.user = response;
      this.getmessages();
    }, err => {
      console.log(err)
    });
    let hubUrl = 'http://localhost:5000/chat';
    this._hubConnection = new signalR.HubConnectionBuilder()
      .withUrl(hubUrl, { accessTokenFactory: () => token })      
      .build();
    this._hubConnection
      .start()
      .then(() => console.log('Connection started!'))
      .catch(err => console.log('Error while establishing connection :('));
    this._hubConnection.on('Receive', (nick: string, receivedMessage: string) => {
      const text = `${nick}: ${receivedMessage}`;
      this.messages.push(text);
    });

  }
  public save() {
    let token = localStorage.getItem("jwt");
    this.http.get(`http://localhost:5000/api/messages/sevemessage/${this.id}/${this.message}`, {
      headers: new HttpHeaders({
        "Authorization": "Bearer " + token,
        "Content-Type": "application/json"
      })
    }).subscribe(err => {
      console.log(err)
      });    
  }
  public getmessages() {
    let token = localStorage.getItem("jwt");
    this.http.get(`http://localhost:5000/api/messages/GetMessages/${this.user.id}/${this.userForMessage.id}`, {
      headers: new HttpHeaders({
        "Authorization": "Bearer " + token,
        "Content-Type": "application/json"
      })
    }).subscribe((response: string[]) => {
      this.messages = response;
    }, err => {
      console.log(err)
    });
  }
}

И HTML Страница компонента

<div id="main-container" style="text-align:center">

  <div class="container">
    <h2 *ngIf="user">Hello {{user.userName}}!</h2>
    <form (ngSubmit)="sendMessage()" #chatForm="ngForm">
      <div>
        <label for="message">Message</label>
        <input type="text" id="message" name="message" [(ngModel)]="message" required>
      </div>
      <button type="submit" id="sendmessage" [disabled]="!chatForm.valid">
        Send
      </button>
    </form>
  </div>
  <div class="container" *ngIf="messages.length > 0">
    <div *ngFor="let message of messages">
      <span>{{message}}</span>
    </div>
  </div>
</div>
<div class="form-group">
  <input type="button" value="getmessages" (click)="getmessages()" class="btn btn-success" />
</div>

уже и базу настроил, и все подключил, а сделать так, чтобы переписка шла только в своем чате не получается:(

Answer 1

Установил условие, что если отправитель не является тем - кому я сам пишу сообщение или просто к кому вошел в чат, то отправленное мне сообщение не появляется на экране - this.userForMessage.userName == nick , но чтобы отправитель видел, что сообщение отправилось, и оно действительно отправилось пользователю и записалось в базу данных, я добавляю - || this.user.userName==nick В целом это выглядит так:

this._hubConnection.on('Receive', (dateTime: string, nick: string, receivedMessage: string) => {
      if (this.userForMessage.userName == nick || this.user.userName==nick) {
        const text = `${dateTime}: ${nick}: ${receivedMessage}`;
        this.messages.push(text);
      }      
    }); 

В итоге все работает так, как и хотел, захожу первым пользователем в чат ко второму, вторым к третьему. Первым пишу сообщение, у второго тишина, захожу вторым пользователем к первому, вижу отправленное ранее сообщение (это с условием, если у вас как и у меня настроено сохранение сообщений в базе данных итп) вот и все!

READ ALSO
Получить значение из Combobox, который внутри DataGrid WPF MVVM

Получить значение из Combobox, который внутри DataGrid WPF MVVM

Есть DataGrid, в ней несколько колонок, одна из них с ComboboxСписок для Combobox подгружаю из внешнего файла

335
Выполнить JS код в C#

Выполнить JS код в C#

Подскажите, пожалуйста, следующий момент

81
Добавить поддержку .fb2 в wordpress

Добавить поддержку .fb2 в wordpress

Собственно говоря как добавить поддержку форматаfb2 я пробовал добавить вот такой код в functions

104