Fix SignalR client in web to use connection pooling

This commit is contained in:
Fergal Moran
2018-05-12 05:47:43 +01:00
parent 8b647ec7ef
commit a7dbab71cf
5 changed files with 52 additions and 19 deletions

View File

@@ -59,7 +59,7 @@ export class AppComponent implements OnInit {
this._signalrService
.init('userupdates')
.then((listener) => {
listener.on<string>(chatterChannel)
listener.on<string>('userupdates', chatterChannel)
.subscribe(result => {
this._toastyService.info(result);
});

View File

@@ -48,13 +48,13 @@ export class EntryListItemComponent implements OnInit {
this.entry.uid
}__info_processed`;
listener
.on<AudioProcessingMessageModel>(updateChannel)
.on<AudioProcessingMessageModel>('audioprocessing', updateChannel)
.subscribe((result) => {
this.percentageProcessed = result.percentage;
this.currentSpeed = result.currentSpeed;
});
listener
.on<PodcastEntryModel>(processedChannel)
.on<PodcastEntryModel>('audioprocessing', processedChannel)
.subscribe((result) => {
this.entry = result;
if (this.entry.processingStatus === 'Processed') {

View File

@@ -26,7 +26,7 @@ export class ChatService extends BaseService {
if (r) {
this._signalRService.init('chat').then((listener) => {
listener
.on<ChatModel>('SendMessage')
.on<ChatModel>('chat', 'SendMessage')
.subscribe((message: ChatModel) => {
console.log(
'chat-widget.component',

View File

@@ -4,34 +4,62 @@ import { HubConnection, HubConnectionBuilder, LogLevel } from '@aspnet/signalr';
import { environment } from 'environments/environment';
import { Observable, Subscriber } from 'rxjs';
class HubListener {
constructor(connection: HubConnection) {
this.connection = connection;
this.isConnecting = false;
this.isConnected = false;
}
connection: HubConnection;
isConnected: boolean;
isConnecting: boolean;
}
interface HubCollection {
[hubName: string]: HubListener;
}
@Injectable()
export class SignalRService {
private _connected: boolean = false;
private _connection: HubConnection;
private connectionPool: HubCollection = {};
constructor(private _auth: PodnomsAuthService) {}
public init(hub: string): Promise<SignalRService> {
public init(hubName: string): Promise<SignalRService> {
return new Promise((resolve) => {
const url = `${environment.SIGNALR_HOST}/hubs/${hub}`;
const url = `${environment.SIGNALR_HOST}/hubs/${hubName}`;
const token = this._auth.getToken();
this._connection = new HubConnectionBuilder()
.configureLogging(LogLevel.Debug)
.withUrl(url + '?token=' + token)
.build();
let hub = this.connectionPool[hubName];
if (!hub) {
const connection = new HubConnectionBuilder()
.configureLogging(LogLevel.Debug)
.withUrl(url + '?token=' + token)
.build();
this.connectionPool[hubName] = new HubListener(connection);
}
resolve(this);
});
}
public on<T>(channel: string): Observable<T> {
public on<T>(hub: string, channel: string): Observable<T> {
const listener = new Observable<T>((subscriber: Subscriber<T>) => {
this._connection.on(channel, (message) => {
const h = this.connectionPool[hub];
h.connection.on(channel, (message) => {
const result: T = message as T;
subscriber.next(result);
});
h.connection.onclose(() => {
h.isConnected = false;
});
if (!h.isConnected && !h.isConnecting) {
h.isConnecting = true;
h.connection.start().then(() => {
h.isConnected = true;
h.isConnecting = false;
this.connectionPool[hub] = h;
});
}
this.connectionPool[hub] = h;
});
if (!this._connected) {
this._connection.start().then(() => (this._connected = true));
}
return listener;
}
}

View File

@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using PodNoms.Api.Models;
using PodNoms.Api.Utils;
namespace PodNoms.Api.Persistence {
public interface IPodcastRepository : IRepository<Podcast> {
@@ -21,7 +22,6 @@ namespace PodNoms.Api.Persistence {
.FirstOrDefaultAsync();
return ret;
}
public async Task<IEnumerable<Podcast>> GetAllForUserAsync(string userId) {
var ret = GetAll()
.Where(u => u.AppUser.Id == userId)
@@ -29,6 +29,11 @@ namespace PodNoms.Api.Persistence {
.OrderByDescending(p => p.Id);
return await ret.ToListAsync();
}
public new Podcast AddOrUpdate(Podcast podcast) {
if (string.IsNullOrEmpty(podcast.TemporaryImageUrl)) {
podcast.TemporaryImageUrl = $"standard/podcast-image-{Randomisers.RandomInteger(1, 16)}.png";
}
return base.AddOrUpdate(podcast);
}
}
}