2

I have an auction application where I need to show real time bids by each user. The technology I want to use is Angular 6 for the frontend , Signal R for the real time communication and Asp.net MVC as backend apis. I tried both using @aspnet/signalR as well as ng2-signalR

Following is some of my code :

App.component.ts

import { Component, Injectable } from '@angular/core';
import { SignalR, SignalRConnection, ISignalRConnection, BroadcastEventListener } from '../../node_modules/ng2-signalr';
import { Route, ActivatedRoute, Resolve } from '@angular/router';
import { BidService } from './app.service';
import { BidBlotter } from './Bid.Model';
import * as signalR from '@aspnet/signalr';
import { HubConnection } from '@aspnet/signalr';

// import '~/signalr/hubs';
declare var $: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  private _connection: SignalRConnection;
  public _hubConnection: SignalRConnection;

  constructor(
    private _signalR: SignalR,
    private _bidservice: BidService,
    public route: ActivatedRoute) {
  }
  private _hubConnection1: HubConnection | undefined;
  ngOnInit() {
this.getBids(1);
    this.connectToSignalR();
    }

private server: any; // used to call server
  // $.connection.testSignalRHub.client
  private client: any; // used to receive calls from server
  // $.connection.testSignalRHub
  private hub: any; // hub itself
  private hub1: any; // hub itself
  connectToSignalR() {

    jQuery.getScript('http://localhost:52106/signalr/hubs', () => {
this.server.broadcastCommonData = (data: any) => {
        alert(1);
        // self.commonData = data;
      };


    })
    // if you need to call the server hub method - use server variable:
    //this.server.broadcastCommonData(this.commonData);
  }
  bidDetails = [];
  bidBlotter: BidBlotter;

  title = 'app';
  QuickBid(amount) {
    // this._signalR.connect().then((c) => {
    debugger
    var abc = amount;
    var data = Object.assign({}, this.bidBlotter, {
      Amount: abc
    });
    this._bidservice.SaveBidDetails(data).subscribe(() => {
      // this.myfun();
      // this.getBids(1);
      debugger
      this.connection.invoke('BroadcastCommonData').then((data: string[]) => {
        // this.speakers = data;
      });

    });
    // });
  }

  id: number = 1;

  getBids(id) {
    this._bidservice.GetBidList(id).subscribe((response) => {
      var data = JSON.parse(JSON.stringify(response));
      this.bidDetails = data;
    })
  }

 private connection: any;
  private proxy: any;
  private ulr: any;

  myfun() {
 this.connection = $.hubConnection("http://localhost:52106");
    let conx = this._signalR.createConnection();
    conx.status.subscribe((s) => console.log(s.name));
    debugger
    conx.start().then((c) => {
      console.log("Connected");
    });
    let onMessageSent$ = new BroadcastEventListener<any>('ON_MESSAGE_SENT');
    this.connection.listen(onMessageSent$);
    onMessageSent$.subscribe((chatMessage: any) => {
      debugger
      alert("success");
      // this.chatMessages.push(chatMessage);
    });
    }
  public sendMessage(): void {
    debugger
    this.proxy.invoke('PostToClient', alert(1))
      // .subscribe(()=>{
      //   debugger;
      // })
      .catch((error: any) => {
        console.log('SendMessage error -> ' + error);
      });
  }


}

import { EventEmitter, NgZone, OnDestroy } from "@angular/core";
import * as jQuery from "jquery";
import { Observable, Observer, ReplaySubject, Subject } from "rxjs";

export enum HubConnectionState {
  Connecting = 1,
  Connected = 2,
  Reconnecting = 3,
  Disconnected = 4
}

Following is App.Module.ts file

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { Http, Response, Headers,RequestOptions } from '@angular/http';
import { AppComponent } from './app.component';
import { SignalRModule } from 'ng2-signalr';
import { SignalRConfiguration } from 'ng2-signalr';
import { RouterModule, Routes} from '@angular/router';
// import { ConnectionResolver } from './app.component';
import { BidService } from './app.service';
import { HttpClient, HttpHeaders, HttpClientModule } from '@angular/common/http';
import { ConnectionResolver } from './app.component.resolver';


export function createConfig(): SignalRConfiguration {
  const c = new SignalRConfiguration();
  c.hubName = 'RequestLog';
  // c.qs = { user: 'donald' };
  // c.url = 'http://localhost:52106/';
  c.url = 'http://localhost:52106/';
  c.logging = true;

  // >= v5.0.0
  c.executeEventsInZone = true; // optional, default is true
  c.executeErrorsInZone = false; // optional, default is false
  c.executeStatusChangeInZone = true; // optional, default is true
  return c;
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot([]),
    SignalRModule.forRoot(createConfig),
    HttpClientModule

  ],
  providers: [BidService],
  bootstrap: [AppComponent]
})
export class AppModule { }

FOllowing is App.service.ts

import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/Observable/of';
import { HttpClient, HttpHeaders, HttpClientModule } from '@angular/common/http';
import { BidBlotter } from './Bid.Model';

@Injectable()
export class BidService {

    constructor(private http: HttpClient) { }

    private BaseUrl = "http://localhost:52106/";

    SaveBidDetails(bidblotter: BidBlotter) {
        return this.http.post(this.BaseUrl + `api/Bid/SaveBid`, bidblotter);
    }

    GetBidList(id : number) {
        return this.http.get(this.BaseUrl + `api/Bid/GetListByID/${id}`);
    }
}

There are some more files like app.component.html , route, model etc. but I think these files are enough to detail signal r processing. Any help would be appreciated.....

Shalin Jirawla
  • 489
  • 1
  • 5
  • 24

2 Answers2

5

I just experienced a lot of the same frustrations. I just answered another post highlighting some of the things I went through to set up an angular app with a c# .net framework backend.

1) The @aspnet/signalr package is used for .Net Core. For .Net Framework you need the signalr package (npm install signalr).

2) Since you are now using the signalr package, you wont have access to the HubConnectionBuilder when trying to instantiate a new HubConnection in your angular component.

Instead, when the signalr script gets executed, it will attach additional events to the $ in your code. Note: if you get errors on build or in compile time from your ts files, make sure you've included the @types/signalr and @types/jquery from npm

To set up a new hub connection, use $.hubConnection("your-url-here/signalr"). This will attach to your server's Hub when running. Note: I stored the result from this as a variable called hubConnection in my angular component

On your server code (.cs file), where you have your Hub class, you will need to add above the class name: [HubName("YourHubName")]. So in your case your .cs file would look something like this at the top:

[HubName("HubName")]    
public class MyHubClass: Hub

You will most likely have to include this at the top of your .cs file: using Microsoft.AspNet.SignalR.Hubs;

Then in your Angular Component you set up a proxy to attach to that Hub on your server The very next line after instantiating your new hubConnection, write:

this.hubConnection.createHubProxy("yourHubName");.

After you have made your proxy, you can then attach listeners to listen to events emitted from the server, or you can invoke server functions from your angular components.

I followed this example here to learn how to set up calling events and listening to server events. Yes it is angular 2, but the functions from signalr all still work the same in my angular 7 app.

See my other answer here for further explanations on jQuery and signalR if that gives you some issues

pol
  • 421
  • 4
  • 7
2

You need to use ng2-signalR, since you are not using ASP.NET Core. You also need to append /signalr/ to your URL on the client.

leem
  • 140
  • 1
  • 11