[SOLVED] I can't send messages from Angular to Unity via SignalR

Issue

so I have been trying to create any form of connection between these two, I don’t know if missing something or not, but I can’t communicate between the two.

I want to be able to "Announce" when someone enters a room with Angular, and I want to "Greet" the user entering the room in Unity.

I can’t seem to make this work, I have no errors.

If I invoke a method in Unity it can receive it just fine, but if Angular invokes the method Unity doesn’t respond.

So here is all the code (that I know of) that is relevant.

This would help me out a lot if you figure it out.

signalr.service.ts (angular)

hubConnection: signalR.HubConnection;

  async StartConnection(): Promise<signalR.HubConnection>
  {
    this.hubConnection = new signalR.HubConnectionBuilder()
    .withUrl(environment.hubURL + "Blackjack", {
      skipNegotiation: true,
      transport: signalR.HttpTransportType.WebSockets
    })
    .build();

    try
    {
      await this.hubConnection.start();
      console.log("Hub connection started!");
      return new Promise<signalR.HubConnection>((resolve) => { resolve(this.hubConnection) });
    } catch (err)
    {
      return new Promise<signalR.HubConnection>((resolve, reject) => 
               { reject(console.error("Error while starting connection" + err)) });
    }
  }

blackjack.component.ts (angular)

ngOnInit(): void
  {
    this.signalrService.StartConnection().then((hubConnection) => {
      this.signalrService.GetUser().subscribe(user => this.JoinRoom(user));
      console.log("ID: " + hubConnection.connectionId);
    });
    this.signalrService.hubConnection.on("JoinRoomResponse", (user) => this.OnJoinRoom(user));
  }

BlackjackHub (server)

    public class BlackjackHub : Hub
    {
        public async Task JoinRoom(User user)
        {
            await Clients.All.SendAsync("JoinRoomResponse", user);
        }
        
        public async Task SendMessage(string author, string message)
        {
            await Clients.All.SendAsync("UpdateMessage", author, message);
        }
    }

Program & Startup (server init)

app.UseWebSockets();

app.UseEndpoints(x => {
    x.MapControllers();
    x.MapHub<BlackjackHub>("Blackjack");
    });

Connector.cs (unity)

public class Connector
{
    public Action<User> OnConnected;
    public Action<string, string> OnMessageRecieved;
    public Action OnDeal;
    private HubConnection _connection;

    public async Task InitAsync()
    {
        _connection = new HubConnectionBuilder()
            .WithUrl("https://localhost:5001/Blackjack", HttpTransportType.WebSockets)
            .Build();

        _connection.On<User>("JoinRoomResponse", (user) =>
        {
            OnConnected?.Invoke(new User(user));
        });

        _connection.On("DealCards", () => OnDeal?.Invoke());

        _connection.On<string, string>("SendMessage", (author, message) =>
        {
            OnMessageRecieved?.Invoke(author, message);
        });

        await StartConnectionAsync();
    }

    private async Task StartConnectionAsync()
    {
        try
        {
            await _connection.StartAsync();
            Debug.Log($"Hub Connection State : {_connection.State} \nConnection ID : {_connection.ConnectionId}");
        }
        catch (Exception ex)
        {
            Debug.LogError(ex);
        }
    }
}

NetworkManager.cs (unity)

public class NetworkManager : MonoBehaviour
{
    private static NetworkManager _instance;
    public static NetworkManager Instance
    {
        get { return _instance; }
    }

    private Connector _connector;

    public List<User> users = new List<User>();

    private void Awake()
    {
        if(_instance != null && _instance != this)
        {
            Destroy(this);
        }
        else
        {
            _instance = this;
        }
    }

    private void Start()
    {
        StartCoroutine(nameof(StartAsync));
    }

    public async Task StartAsync()
    {
        _connector = new Connector();

        _connector.OnConnected += OnConnected;
        _connector.OnMessageRecieved += OnMessageRecieved;

        await _connector.InitAsync();
    }

    public async void OnMessageRecieved(string author, string message)
    {
        Debug.Log($"{author}: {message}");
        await Task.Delay(1);
    }

    public async void OnConnected (User user)
    {
        Debug.Log($"{user.Email} just joined.");
        users.Add(user);
        await Task.Delay(1);
    }
}

When its run in Unity this is the output in the console:
Console Log from Connector.cs

Here is the output from the browser:
Console Log from Angular

If I turn off the WebSocket Transport option in Angular the ID has a value:
Console Log from Angular without WebSockets Transport

Solution

So the issue was the following.

My hub was calling the method "UpdateMessage" on the clients.

But my Unity connection was listening on "SendMessage" which was the wrong one.

Very simple over look on my side.

I apologize to anyone that tried to figure it out.

Answered By – Alexander Vestergaard Eriksen

Answer Checked By – Dawn Plyler (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *