我有一个带有signlar 2.2.2和。的角度2应用程序 这是我的信号连接服务类..
{
"error": false,
"message": "Successfull login",
"errorCode": 0,
"data": {
"uid": 7,
"email": "user@example.com",
"name": "username",
"nick": "usernick",
"photoUrl": "media/profiles/defaultImageProfile.png",
"lts": "aaaaeqc9lf9od82rk633aaaaa"
}
}
使用此代码,我可以成功连接到集线器,并将请求从客户端推送到集线器&枢纽到客户。
问题是客户端有时会断开与集线器的连接。 所以我尝试使用下面的url
中显示的事件和方法为这个类添加自动重新连接功能例如:
import { Injectable, Inject } from "@angular/core";
import { Subject } from "rxjs/Subject";
import { Observable } from "rxjs/Observable";
/**
* When SignalR runs it will add functions to the global $ variable
* that you use to create connections to the hub. However, in this
* class we won't want to depend on any global variables, so this
* class provides an abstraction away from using $ directly in here.
*/
export class SignalrWindow extends Window {
$: any;
}
export enum ConnectionState {
Connecting = 1,
Connected = 2,
Reconnecting = 3,
Disconnected = 4
}
export class ChannelConfig {
url: string;
hubName: string;
channel: string;
}
@Injectable()
export class SignalrService {
/**
* starting$ is an observable available to know if the signalr
* connection is ready or not. On a successful connection this
* stream will emit a value.
*/
starting$: Observable<any>;
/**
* connectionState$ provides the current state of the underlying
* connection as an observable stream.
*/
connectionState$: Observable<ConnectionState>;
/**
* error$ provides a stream of any error messages that occur on the
* SignalR connection
*/
error$: Observable<string>;
// These are used to feed the public observables
//
private connectionStateSubject = new Subject<ConnectionState>();
private startingSubject = new Subject<any>();
private errorSubject = new Subject<any>();
// These are used to track the internal SignalR state
//
private hubConnection: any;
private hubProxy: any;
private cuurentHub: any;
// An internal array to track what channel subscriptions exist
// This Part* is to maintain componants which contains methods to call when message is receieved
// Observable string sources
private newStrokeComponentMethodCallSource = new Subject<any>();
private newPhsycComponentMethodCallSource = new Subject<any>();
// Observable string streams
newStrokecomponentMethodCalled$ = this.newStrokeComponentMethodCallSource.asObservable();
newPhsyccomponentMethodCalled$ = this.newPhsycComponentMethodCallSource.asObservable();
// Service message commands
callNewStrokeComponentMethod(phone: string) {
this.newStrokeComponentMethodCallSource.next(phone);
}
callNewPhsycComponentMethod(phone: string) {
this.newPhsycComponentMethodCallSource.next(phone);
}
//----- End of Part*
constructor(
@Inject(SignalrWindow) private window: SignalrWindow,
@Inject("channel.config") private channelConfig: ChannelConfig
) {
if (this.window.$ === undefined || this.window.$.hubConnection === undefined) {
throw new Error("The variable '$' or the .hubConnection() function are not defined...please check the SignalR scripts have been loaded properly");
}
// Set up our observables
//
this.connectionState$ = this.connectionStateSubject.asObservable();
this.error$ = this.errorSubject.asObservable();
this.starting$ = this.startingSubject.asObservable();
this.hubConnection = this.window.$.hubConnection();
this.hubConnection.url = channelConfig.url;
this.hubProxy = this.hubConnection.createHubProxy(channelConfig.hubName);
// Define handlers for the connection state events
//
this.hubConnection.stateChanged((state: any) => {
let newState = ConnectionState.Connecting;
switch (state.newState) {
case this.window.$.signalR.connectionState.connecting:
newState = ConnectionState.Connecting;
break;
case this.window.$.signalR.connectionState.connected:
newState = ConnectionState.Connected;
break;
case this.window.$.signalR.connectionState.reconnecting:
newState = ConnectionState.Reconnecting;
break;
case this.window.$.signalR.connectionState.disconnected:
newState = ConnectionState.Disconnected;
break;
}
// Push the new state on our subject
//
this.connectionStateSubject.next(newState);
});
// Define handlers for any errors
//
this.hubConnection.error((error: any) => {
// Push the error on our subject
//
this.hubConnection.start()
.done(() => {
this.startingSubject.next();
//Invoke connect method on Hub
// this.hubProxy.invoke("Connect", userId, usertype);
})
.fail((error: any) => {
this.startingSubject.error(error);
});
});
this.hubProxy.on("PushRequestToClient", (data: string) => {
//console.log(`onEvent - ${channel} channel`, ev);
// This method acts like a broker for incoming messages. We
// check the interal array of subjects to see if one exists
// for the channel this came in on, and then emit the event
// on it. Otherwise we ignore the message.
//
var request = JSON.parse(data);
if (request !== null && request.TargetClientMethod === "OnPhsycConsultantRespond") {
this.callNewPhsycComponentMethod(data);
}
else {
this.callNewStrokeComponentMethod(data);
}
// this.callNewStrokeComponentMethod(data);
// If we found a subject then emit the event on it
//
});
}
/**
* Start the SignalR connection. The starting$ stream will emit an
* event if the connection is established, otherwise it will emit an
* error.
*/
start(userId,usertype): void {
// Now we only want the connection started once, so we have a special
// starting$ observable that clients can subscribe to know know if
// if the startup sequence is done.
//
// If we just mapped the start() promise to an observable, then any time
// a client subscried to it the start sequence would be triggered
// again since it's a cold observable.
//
this.hubConnection.start()
.done(() => {
this.startingSubject.next();
//Invoke connect method on Hub
this.hubProxy.invoke("Connect", userId, usertype);
})
.fail((error: any) => {
this.startingSubject.error(error);
});
}
// Invoke Server Methods
/** publish provides a way for calles to emit events on any channel. In a
* production app the server would ensure that only authorized clients can
* actually emit the message, but here we're not concerned about that.
*/
PushRequest(targetUserId, userType, data): void {
this.hubProxy.invoke("PushRequest", targetUserId, userType, data);
}
// -- End of Invoke Server Methods
}
但是说
this.hubConnection.closed不是函数
如何重新建立与集线器的连接?
我正在使用 Angular 2&amp; signalr 2.2.2
答案 0 :(得分:3)
onclose
事件是无参数操作,因此您的方法应如下所示:
this.hubConnection.onclose(() => {
// ....
});
但最好在断开连接后尝试重新连接几秒钟:
this.hubConnection.onclose(() => {
setTimeout(function(){
this.hubConnection.start()
.done(() => {
this.startingSubject.next();
//Invoke connect method on Hub
// this.hubProxy.invoke("Connect", userId, usertype);
})
.fail((error: any) => {
this.startingSubject.error(error);
});
},3000);
});