The communication between Angular and Unity using SignalR for messaging is not functioning properly, as I am unable to

Trying to establish a connection between Angular and Unity has been challenging for me. I can't seem to get them to communicate with each other.

My goal is to have Angular "announce" when someone enters a room, and have Unity "greet" the user entering the room.

Despite not encountering any errors, I still can't make it work. When Unity invokes a method, it works fine, but if Angular does it, Unity doesn't respond.

Below are the relevant code snippets that I'm aware of. Any help in figuring this out would be greatly appreciated.

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 tested in Unity, the following output appeared on the console:
https://i.sstatic.net/FcWMV.png

And here is the output from the browser:
https://i.sstatic.net/1GVLE.png

If I disable the WebSocket Transport option in Angular, the ID shows a value:
https://i.sstatic.net/59S99.png

Answer №1

The problem arose when I realized the mistake I had made.

I was instructing my hub to utilize the "UpdateMessage" method with clients.

However, my Unity connection was set up to receive communication on "SendMessage," which was incorrect.

This oversight was a simple one on my part.

I extend my apologies to those who attempted to troubleshoot it.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue encountered in Angular 4 due to XSS script in URL causing "Cannot match any routes" error

I've been working on a project in Angular 4 and encountered an issue while setting up routes for a feature module. The error message I'm receiving is Error: Cannot match any routes. Below is the code snippet of the routes I've defined: con ...

Learn how to utilize the combineLatest/zip operators to only respond to emissions from the second observable while disregarding emissions from the first observable

Here's an example of how I'm initializing a property: this.currentMapObject$ = zip(this.mapObjects$, this.currentMapObjectsIndex$, (mapObjects, index) => mapObjects[index]); I want the value of this.currentMapObject$ to be emitted only ...

Is there a way to enforce a mandatory lambda argument?

I am trying to pass a lambda into a function, but I need the lambda to have only one argument. TypeScript correctly generates an error if I provide two parameters to the lambda, however it does not raise any issues if I leave out any arguments altogether ...

Is there a method to globally import "typings" in Visual Code without having to make changes to every JS file?

Is there a method to streamline the process of inputting reference paths for typings in Visual Studio Code without requiring manual typing? Perhaps by utilizing a configuration file that directs to all typings within the project, eliminating the need to ...

Having difficulty deploying a Node.js and Angular app on an Azure Web App via Azure DevOps

I am currently working on setting up a pipeline for my MEAN stack application in Azure DevOps. The frontend is developed using Node.js with Angular, while the backend is built with Node.js and Express. 1) Once I deploy the frontend Node.js project to an A ...

Typescript error message TS2314: One type argument is required for the generic type 'Array<T>'

I recently started my journey in learning typescript and have written some basic code. class Learning { subjects: Array[string]; hoursPerDay: number; constructor(subj: Array[string], hrs: number) { this.subjects = subj; thi ...

Is it possible to customize the pagination-control labels from numbers (1 2 3) to different values, such as 'Anything1 Anything2 ...', by utilizing ngFor* with an array in ngx-pagination?

Is there a way to customize ngx-pagination's pagination control? Currently, the page numbers are displayed as '1 2 3' but I would like to replace them with specific string values from an array. <pagination-controls (pageChange)=& ...

Accessing the NestJS DI container directly allows for seamless integration of dependency

I have been using NestJS for the past 4 months after working with PHP for 5 years, mainly with Symfony. With PHP, I had the ability to access the compiled DI container and retrieve any necessary service from it. For example, in an application with service ...

Exploring the concept of individuality within front-end development

Would it be possible to manage identity directly on the front end using Angular's auth guard instead of setting up identity management on the server-side? The auth guard could handle all aspects of identity, even for smaller projects. For instance, in ...

Implementing a ReactJS component with a TypeScript interface for displaying an Alert box message using Material

I have a MUI Alert box in my application where I am trying to change the message inside with an href URL. However, when I use the herf tag, it shows as text instead of a link. How can I make it display as an actual link? In the code below, when I click th ...

Save this code snippet to your clipboard using vanilla JavaScript (no jQuery needed)

I am working on an Angular 9 application where I want to implement the functionality of copying the URL to clipboard when clicked. Currently, I have the following code: The issue I am facing is that it only copies the URL on the second attempt and then st ...

Angular: Observing changes in the store and sending a message from a Service component to another component once the Service has finished specific tasks

Within our codebase, we introduce two classes known as GetDataAsyncService. This service is designed to wait for a change in the store before executing the block of code contained within it. By utilizing observables and subscribing to data changes with t ...

Exploring an array of objects to find a specific string similar to the one being

I recently developed a TypeScript code snippet that searches for objects in a list by their name and surname, not strictly equal: list = list.filter( x => (x.surname + ' ' + x.name) .trim() .toLowerCase() .sear ...

Is there a way to automatically establish a connection with a BLE device when it is within

I am currently working on an app for IONIC 2 that requires my BLE device to automatically connect when in range. The app should be able to handle this whether it is in the background or foreground, and if the connection is lost, it should continuously se ...

Building a personalized React component poses challenges when working with MUI REACT interfaces

I am looking to develop a unique component that will display two different elements, an icon, and a title. However, I seem to be encountering errors from TypeScript regarding the declaration of my interface. The error message reads: Property 'map&apos ...

When it comes to passing prop values through functions, TypeScript types do not provide suggestions

I'm struggling to find a way to ensure that developers have suggested types for specific props in my component, regardless of how they pass data to the prop. For example, when I directly pass an array of values to the prop: <Component someProp={[{ ...

What is the best way to implement material theme colors into my Angular2 CSS?

Suppose I want to utilize the mat-primary color as a background for a div using a CSS/SASS class, how should I reference it? My initial thought was: @import '~@angular/material/prebuilt-themes/deeppurple-amber.css'; .my-class{ background-colo ...

Creating a connection between properties and their values

I am looking to implement a property for data binding on my own terms. For instance, consider the following list of items: [{name='name1', invalid='error.name1'}] Along with another list of errors. errors : any= ['name1': & ...

Angular is throwing an error due to an unexpected token when running on an IIS server within a subfolder

I have recently developed an Angular 11 template (Angular version 11 + .Net core 5.0) using visual studio 2019. The Angular application needs to be accessed from a subfolder called caui rather than the root folder. After publishing the Angular application ...

Angular throws a NullInjectorError when a unit test fails due to issues with dependency

As a newcomer to Angular, I am struggling to grasp the concept of Dependency Injection (DI) and how it functions. My current challenge involves trying to pass a unit test successfully. Below is the code for the test; import { TestBed } from '@angula ...