无法接收来自Ng-Chat组的消息

时间:2019-02-26 22:03:47

标签: c# angular

我已经实现了ng-chat https://github.com/rpaschoal/ng-chat(SignalR)。

我有3个用户:User1,User2和User3

如果我从User1向User2发送消息,则User2可以很好地接收该消息,但是如果我创建了一个组(与User1,我打开了User2的聊天室,然后添加了User3),则使用用户(User2和User3)创建了一个新组)。

因此,当我通过新聊天发送消息时,用户(User2和User3)没有收到任何消息

这是我的SingalR集线器:

using AdvansysOficina.Api._Core.Infraestructura;
using AdvansysOficina.Api.Generales.Servicios.UsuarioNs;
using Microsoft.AspNetCore.SignalR;
using NgChatSignalR.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AdvansysOficina.Api.Desarrollo.Servicios.ConversacionPuntoNs.HubNs
{
public class ConversacionHub : Hub
{
    private static List<ParticipantResponseViewModel> AllConnectedParticipants { get; set; } = new List<ParticipantResponseViewModel>();
    private static List<ParticipantResponseViewModel> DisconnectedParticipants { get; set; } = new List<ParticipantResponseViewModel>();
    private readonly object ParticipantsConnectionLock = new object();

    private ISesion _sesion;
    private IUsuarioServicio _usuarioServicio;

    public ConversacionHub(ISesion sesion, IUsuarioServicio usuarioServicio)
    {
        _sesion = sesion;
        _usuarioServicio = usuarioServicio;
    }

    public static IEnumerable<ParticipantResponseViewModel> ConnectedParticipants(string currentUserId)
    {
        return AllConnectedParticipants
            .Where(x => x.Participant.Id != currentUserId);
    }

    public void Join(string userName, dynamic grupo)
    {
        lock (ParticipantsConnectionLock)
        {
            AllConnectedParticipants.Add(new ParticipantResponseViewModel()
            {
                Metadata = new ParticipantMetadataViewModel()
                {
                    TotalUnreadMessages = 0
                },
                Participant = new ChatParticipantViewModel()
                {
                    DisplayName = userName,
                    Id = Context.ConnectionId,
                }
            });


            // This will be used as the user's unique ID to be used on ng-chat as the connected user.
            // You should most likely use another ID on your application
            //Clients.Caller.SendAsync("generatedUserId", Context.ConnectionId);

            Clients.Caller.SendAsync("generatedUserId", Context.ConnectionId);

            Clients.All.SendAsync("friendsListChanged", AllConnectedParticipants);
        }
    }

    public void SendMessage(MessageViewModel message)
    {

        var sender = AllConnectedParticipants.Find(x => x.Participant.Id == message.FromId);

        if (sender != null)
        {
            Clients.Client(message.ToId).SendAsync("messageReceived", sender.Participant, message);
        }
    }

    public override Task OnDisconnectedAsync(Exception exception)
    {
        lock (ParticipantsConnectionLock)
        {
            var connectionIndex = AllConnectedParticipants.FindIndex(x => x.Participant.Id == Context.ConnectionId);

            if (connectionIndex >= 0)
            {
                var participant = AllConnectedParticipants.ElementAt(connectionIndex);

                AllConnectedParticipants.Remove(participant);
                DisconnectedParticipants.Add(participant);

                Clients.All.SendAsync("friendsListChanged", AllConnectedParticipants);
            }

            return base.OnDisconnectedAsync(exception);
        }
    }

    public override Task OnConnectedAsync()
    {
        lock (ParticipantsConnectionLock)
        {
            var connectionIndex = DisconnectedParticipants.FindIndex(x => x.Participant.Id == Context.ConnectionId);

            if (connectionIndex >= 0)
            {
                var participant = DisconnectedParticipants.ElementAt(connectionIndex);

                DisconnectedParticipants.Remove(participant);
                AllConnectedParticipants.Add(participant);

                Clients.All.SendAsync("friendsListChanged", AllConnectedParticipants);
            }

            return base.OnConnectedAsync();
        }
    }
}
}

我的signalR适配器(角度)

import { ChatAdapter, Message, ParticipantResponse, Group, IChatController } from 'ng-chat';
import { map, catchError } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';

import * as signalR from '@aspnet/signalr';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { AlertasHelper } from '../../../shared/helpers/alertas.helper';
import { PushNotificationHelper } from './notifications/push-notification';

export class SignalRAdapter extends ChatAdapter {
  public static serverBaseUrl  =  'http://192.168.16.51:5021/'; // if running locally
  public userId: string;
  private grrupo;
  private hubConnection: signalR.HubConnection;


  constructor(private username: string, private http: HttpClient, private notification: PushNotificationHelper
    ) {
    super();

    this.initializeConnection();
  }

  private initializeConnection(): void {
    this.hubConnection = new signalR.HubConnectionBuilder()
      .withUrl(`${SignalRAdapter.serverBaseUrl}chat`, { transport: signalR.HttpTransportType.LongPolling })
      .build();

    this.hubConnection
      .start()
      .then(() => {
        this.joinRoom();

        this.initializeListeners();
      })
      .catch(err => console.log(`Error while starting SignalR connection: ${err}`));
  }

  private initializeListeners(): void {
    this.hubConnection.on('generatedUserId', (userId) => {
      // With the userId set the chat will be rendered
      this.userId = userId;
    });

    this.hubConnection.on('messageReceived', (participant, message) => {
      // Handle the received message to ng-chat
      console.log(message);
      this.notification.notify('Nuevo mensaje de: ' + participant.displayName, message);
      this.onMessageReceived(participant, message);
    });

    this.hubConnection.on('friendsListChanged', (participantsResponse: Array<ParticipantResponse>) => {
      // Handle the received response to ng-chat
      this.onFriendsListChanged(participantsResponse.filter(x => x.participant.id !== this.userId));
    });
  }

  joinRoom(): void {
    if (this.hubConnection && this.hubConnection.state === signalR.HubConnectionState.Connected) {
      this.hubConnection.send('join', this.username, '');
    }
  }

  listFriends(): Observable<ParticipantResponse[]> {
    // List connected users to show in the friends list
    // Sending the userId from the request body as this is just a demo
    // return this.http
    //   .post(`${SignalRAdapter.serverBaseUrl}listFriends`, { currentUserId: this.userId })
    //   .pipe(
    //     map((res: any) => res),
    //     catchError((error: any) => Observable.throw(error.error || 'Server error'))
    //   );
    return of([]);

  }

  getMessageHistory(destinataryId: any): Observable<Message[]> {
    // This could be an API call to your web application that would go to the database
    // and retrieve a N amount of history messages between the users.
    return of([]);
  }

  sendMessage(message: Message): void {
    if (this.hubConnection && this.hubConnection.state === signalR.HubConnectionState.Connected) {
      console.log(message);
      this.hubConnection.send('sendMessage', message);
    }
  }

  groupCreated(group: Group): void {
    console.log( group);
  }
}

组件的使用

<ng-chat #chat *ngIf="signalRAdapter && signalRAdapter.userId"
  [adapter]="signalRAdapter"
  [userId]="signalRAdapter.userId"
  [groupAdapter]="signalRAdapter"
  (onParticipantChatOpened)="chatOpened($event)"
  [historyEnabled]="false">
</ng-chat>

我已经下载了github创建者页面的示例,但是他没有使用组的signalr的示例,希望您能为我提供帮助。

1 个答案:

答案 0 :(得分:3)

ng-chat将小组视为个人参与者。调用此事件后,您将必须加入您的房间:

groupCreated(group: Group): void { console.log( group); // Invoke your SignalR hub and send the details of the newly created group }

每次创建一个组时,

ng-chat都会生成唯一的ID,因此无论何时从正在运行的ng-chat实例创建一个组,您都可以跟踪哪个组。如何处理这些组的持久性取决于您的应用程序。

您可能希望从SignalR适配器向涉及的用户推送通知,通知他们的朋友列表已更改(此阶段他们将能够看到该组)。您还可以决定不这样做,并且仅在创建组的用户发送初始消息时才推送通知(再次,取决于您的应用程序需求)。

您可能还想在适配器上实现IChatGroupAdapter,以使合同更加明确。

希望这会有所帮助!