stephen-moyer / ngx-signalr-hubservice

Makes using SignalR in Angular 2/4 easy
MIT License
24 stars 5 forks source link

Multiple Hubs in multiple locations #6

Closed sharpdevel closed 6 years ago

sharpdevel commented 6 years ago

Hi everyone. I'm having trouble talking to multiple hubs on different backends.

Let's assume the following

In my NG project, I defined two services

@Injectable()
@Hub({ hubName: 'DataHub' })
export class DataHubService {
  constructor (private hubService: HubService) {
    this.hubWrapper = this.hubService.register(this);
    this.hubService.connect('http://localhost:81/signalr').toPromise();
  }
}

@Injectable()
@Hub({ hubName: 'EvaluationHub' })
export class EvaluationHubService {
  constructor (private hubService: HubService) {
    this.hubWrapper = this.hubService.register(this);
    this.hubService.connect('http://localhost:82/signalr').toPromise();
  }
}

Calling the connect method on hubService now tries to establish a connection with the given backend url but expects all hubs to be on this url. As the code states all Hub-decorators are called and their named are beeing collected in a global variable.

//all the hubs/events we have to subscribe to when setting up the connection. //signalr requires you to connect to all the hubs before making the connection //so we store them in a global var. var allHubProperties = [];

Is there any way to accomplish the above-mentioned case? If not so, I would like to propose the introduction of a HubGroup that goes into the Hub-decorator and also into the connect method to specify which hubs are on which server. What do you think?

stephen-moyer commented 6 years ago

Yeah this isn't supported at the moment, but it's a good idea.

How would you decide what "HubGroup" to use when connecting then? Would a parameter added to the connect method work?

@Injectable()
@Hub({ hubName: 'DataHub', hubGroup: '81' })
export class DataHubService {
  constructor (private hubService: HubService) {
    this.hubWrapper = this.hubService.register(this);
    this.hubService.connect('http://localhost:81/signalr', { hubGroup: '81' }).toPromise();
  }
}

@Injectable()
@Hub({ hubName: 'EvaluationHub', hubGroup: '82' })
export class EvaluationHubService {
  constructor (private hubService: HubService) {
    this.hubWrapper = this.hubService.register(this);
    this.hubService.connect('http://localhost:82/signalr', { hubGroup: '82' }).toPromise();
  }
}

Would something like this be ok?

sharpdevel commented 6 years ago

Yeah that would be great.

I already forked the project and would make the required changes and propose them back to you via pull request.

D'accord?

stephen-moyer commented 6 years ago

Ah, I just published a new version. 2.0.6 should work. There were a couple bugs with the previous 2x versions.

stephen-moyer commented 6 years ago

I don't have a ton of time right now to update the documentation/examples so if you are looking to submit a PR that would be great! Otherwise you can just close this issue (if it works) and I'll update the docs later this weekend.

Example code:

@Injectable()
@Hub({ hubName: 'DataHub', hubGroups: '81' /* you can also pass in an array of groups */ })
export class DataHubService {
  constructor (private hubService: HubService) {
    this.hubWrapper = this.hubService.register(this);
    this.hubService.connect({ url: 'http://localhost:81/signalr', hubGroups: '81' /* you can also pass in an array of groups */ }).toPromise();
  }
}

Also by looking at your example code, you will probably need to register two instances of the HubService and use InjectionToken's to inject the right HubService for your HubGroup in your services.

sharpdevel commented 6 years ago

Works like a charm. Thanks a lot 🥇