ing
This commit is contained in:
parent
19621ef090
commit
6edb85aa07
6
src/@loafer/ng-rpc/core/error.ts
Normal file
6
src/@loafer/ng-rpc/core/error.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export class SubscriberParameterError extends Error {
|
||||
public constructor(message?: string) {
|
||||
super(message);
|
||||
Object.setPrototypeOf(this, new.target.prototype);
|
||||
}
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
export * from './error';
|
||||
export * from './token';
|
||||
|
|
|
@ -3,12 +3,14 @@ import { Store, select } from '@ngrx/store';
|
|||
|
||||
import {
|
||||
Type,
|
||||
PropertyKeyType,
|
||||
} from '@loafer/core';
|
||||
|
||||
import { TypeUtil } from '@loafer/core/util/TypeUtil';
|
||||
|
||||
import {
|
||||
Class,
|
||||
Method,
|
||||
Metadata,
|
||||
} from '@loafer/core/reflect';
|
||||
|
||||
|
@ -17,14 +19,26 @@ import { RPCSubscriberDecorator } from '../decorator';
|
|||
import {
|
||||
RPCClientNotificationCodec,
|
||||
} from '../protocol';
|
||||
import { SubscriberParameterError } from '../core';
|
||||
|
||||
export interface SubscriberMethod {
|
||||
className: PropertyKeyType;
|
||||
methodName: PropertyKeyType;
|
||||
parameterTypes: string[];
|
||||
|
||||
method: Method;
|
||||
instance: any;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class RPCSubscribeService {
|
||||
private subscribers: Set<any>;
|
||||
private subscriberMethodMap: Map<string, SubscriberMethod[]>;
|
||||
|
||||
constructor(
|
||||
) {
|
||||
this.subscribers = new Set();
|
||||
this.subscriberMethodMap = new Map();
|
||||
}
|
||||
|
||||
public addSubscriber(subscriber: Type<any>): void {
|
||||
|
@ -46,11 +60,100 @@ export class RPCSubscribeService {
|
|||
const methods = clazz.getMethods();
|
||||
methods.forEach((method, propertyKey) => {
|
||||
const annon = method.getAnnotation(RPCSubscriberDecorator);
|
||||
console.log(`subscriber method[${annon.attribute.method}]`);
|
||||
if (undefined === annon) {
|
||||
return;
|
||||
}
|
||||
|
||||
const subscriberMethodName = annon.attribute.method;
|
||||
let subscriberMethods: SubscriberMethod[] = this.subscriberMethodMap.get(subscriberMethodName);
|
||||
if (undefined === subscriberMethods) {
|
||||
subscriberMethods = [];
|
||||
this.subscriberMethodMap.set(subscriberMethodName, subscriberMethods);
|
||||
}
|
||||
|
||||
const paramTypes = this.getParamTypes(method);
|
||||
|
||||
const subscriberMethod: SubscriberMethod = {
|
||||
className: clazz.getName(),
|
||||
methodName: method.getName(),
|
||||
parameterTypes: paramTypes,
|
||||
method: method,
|
||||
instance: subscriber,
|
||||
};
|
||||
|
||||
subscriberMethods.push(subscriberMethod);
|
||||
});
|
||||
}
|
||||
|
||||
public notify(codec: RPCClientNotificationCodec): void {
|
||||
console.log(`notify method[${codec.method()}] params[${codec.params()}]`);
|
||||
const method = codec.method();
|
||||
const params = codec.params();
|
||||
|
||||
const subscriberMethods: SubscriberMethod[] = this.subscriberMethodMap.get(method);
|
||||
if (undefined === subscriberMethods) {
|
||||
console.warn(`Subscriber for method[${method}] is not exist`);
|
||||
return;
|
||||
}
|
||||
subscriberMethods.forEach((subscriberMethod) => {
|
||||
try {
|
||||
const args = this.converParams(params, subscriberMethod.parameterTypes);
|
||||
subscriberMethod.method.invoke(subscriberMethod.instance, ...args);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getParamTypes(method: Method): string[] {
|
||||
if (undefined === method || null === method || 0 === method.getParameterCount()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const parameters = method.getParameters();
|
||||
const results: string[] = [];
|
||||
for (let indexI = 0; indexI < parameters.length; indexI++) {
|
||||
const paramType = parameters[indexI].getType();
|
||||
results.push(paramType.name);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private converParams(params: string[], paramTypes: string[]): any[] {
|
||||
const results: any[] = [];
|
||||
|
||||
if (undefined === params || null === params || 0 === params.length) {
|
||||
return results;
|
||||
}
|
||||
if (undefined === paramTypes || null === paramTypes || 0 === paramTypes.length) {
|
||||
return results;
|
||||
}
|
||||
if (params.length !== paramTypes.length) {
|
||||
throw new SubscriberParameterError(`Count is not same from server[${params.length}] and method[${paramTypes.length}]`);
|
||||
}
|
||||
for (let indexI = 0; indexI < params.length; indexI++) {
|
||||
const param = params[indexI];
|
||||
const type = paramTypes[indexI];
|
||||
switch (type) {
|
||||
case 'Object':
|
||||
case 'Array':
|
||||
case 'Map':
|
||||
results.push(JSON.parse(param));
|
||||
break;
|
||||
case 'String':
|
||||
results.push(param);
|
||||
break;
|
||||
case 'Number':
|
||||
results.push(Number(param));
|
||||
break;
|
||||
case 'Boolean':
|
||||
results.push(Boolean(param));
|
||||
break;
|
||||
case 'Function':
|
||||
throw new SubscriberParameterError(`Function type [${indexI}] is not allowed`);
|
||||
default:
|
||||
throw new SubscriberParameterError(`${type} type parameter[${indexI}] is not allowed`);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ import {
|
|||
} from '../../model';
|
||||
import * as CIDR from 'ip-cidr';
|
||||
import * as DiscoveredStore from '../../store/setting';
|
||||
import * as DiscoverStore from '../../store/notification';
|
||||
import * as DiscoverStore from '../../store/discover';
|
||||
|
||||
import { SettingSelector, NotificationSelector } from '../../store';
|
||||
import { SettingSelector, DiscoverSelector } from '../../store';
|
||||
|
||||
@Component({
|
||||
selector: 'of-setting',
|
||||
|
@ -21,7 +21,7 @@ import { SettingSelector, NotificationSelector } from '../../store';
|
|||
export class SettingComponent implements OnInit, AfterContentInit {
|
||||
|
||||
settingSucceed$ = this.discoverdstore.pipe(select(SettingSelector.select('isStart')));
|
||||
discoveryResult$ = this.discoverstore.pipe(select(NotificationSelector.select('getDiscoveryResult')));
|
||||
discoveryResult$ = this.discoverstore.pipe(select(DiscoverSelector.select('getDiscoveryResult')));
|
||||
|
||||
started = false;
|
||||
|
||||
|
|
|
@ -16,10 +16,11 @@ import {
|
|||
DiscoverHost = '[discovery.discovery] discoverHost',
|
||||
DiscoverPort = '[discovery.discovery] discoverPort',
|
||||
DiscoverService = '[discovery.discovery] discoverService',
|
||||
DiscoveredZone = '[@@NOTIFICATION] DiscoveryService.discoveredZone',
|
||||
DiscoveredHost = '[@@NOTIFICATION] DiscoveryService.discoveredHost',
|
||||
DiscoveredPort = '[@@NOTIFICATION] DiscoveryService.discoveredPort',
|
||||
DiscoveredService = '[@@NOTIFICATION] DiscoveryService.discoveredService',
|
||||
|
||||
DiscoveredZone = '[discovery.discovery] DiscoveryService.discoveredZone',
|
||||
DiscoveredHost = '[discovery.discovery] DiscoveryService.discoveredHost',
|
||||
DiscoveredPort = '[discovery.discovery] DiscoveryService.discoveredPort',
|
||||
DiscoveredService = '[discovery.discovery] DiscoveryService.discoveredService',
|
||||
}
|
||||
|
||||
export class DiscoverZone implements Action {
|
|
@ -1,8 +1,8 @@
|
|||
import { TestBed, inject } from '@angular/core/testing';
|
||||
|
||||
import { Effects } from './notification.effect';
|
||||
import { Effects } from './discover.effect';
|
||||
|
||||
describe('Notification.Effects', () => {
|
||||
describe('Discover.Effects', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [Effects]
|
|
@ -20,7 +20,7 @@ import {
|
|||
DiscoverPort,
|
||||
DiscoverService,
|
||||
ActionType
|
||||
} from './notification.action';
|
||||
} from './discover.action';
|
||||
import {DiscoveryService} from '../../service/discovery.service';
|
||||
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
import {
|
||||
Actions,
|
||||
ActionType,
|
||||
} from './notification.action';
|
||||
} from './discover.action';
|
||||
|
||||
import {
|
||||
State,
|
||||
initialState,
|
||||
} from './notification.state';
|
||||
} from './discover.state';
|
||||
|
||||
import {
|
||||
Zone,
|
||||
|
@ -19,7 +19,9 @@ export function reducer(state = initialState, action: Actions): State {
|
|||
switch (action.type) {
|
||||
case ActionType.DiscoveredZone: {
|
||||
const zone: Zone = <Zone>action.payload;
|
||||
state.zones.set(zone.network, zone);
|
||||
const zones: Map<string, Zone> = null === state.zones ? new Map() : state.zones;
|
||||
|
||||
zones.set(zone.network, zone);
|
||||
|
||||
return state;
|
||||
}
|
4
src/packages/discovery/store/discover/index.ts
Normal file
4
src/packages/discovery/store/discover/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
export * from './discover.action';
|
||||
export * from './discover.reducer';
|
||||
export * from './discover.state';
|
||||
export * from './discover.effect';
|
|
@ -10,30 +10,30 @@ import { StateSelector } from 'packages/core/ngrx/store';
|
|||
import { MODULE } from '../discovery.constant';
|
||||
|
||||
|
||||
import * as NotificationStore from './notification';
|
||||
import * as DiscoverStore from './discover';
|
||||
import * as SettingStore from './setting';
|
||||
|
||||
|
||||
export interface State {
|
||||
notification: NotificationStore.State;
|
||||
discover: DiscoverStore.State;
|
||||
setting: SettingStore.State;
|
||||
}
|
||||
|
||||
export const REDUCERS = {
|
||||
notification: NotificationStore.reducer,
|
||||
discover: DiscoverStore.reducer,
|
||||
setting: SettingStore.reducer,
|
||||
};
|
||||
|
||||
export const EFFECTS = [
|
||||
SettingStore.Effects,
|
||||
NotificationStore.Effects,
|
||||
DiscoverStore.Effects,
|
||||
];
|
||||
|
||||
export const selectDiscoveryState = createFeatureSelector<State>(MODULE.name);
|
||||
|
||||
export const NotificationSelector = new StateSelector<NotificationStore.State>(createSelector(
|
||||
export const DiscoverSelector = new StateSelector<DiscoverStore.State>(createSelector(
|
||||
selectDiscoveryState,
|
||||
(state: State) => state.notification
|
||||
(state: State) => state.discover
|
||||
));
|
||||
|
||||
export const SettingSelector = new StateSelector<SettingStore.State>(createSelector(
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
export * from './notification.action';
|
||||
export * from './notification.reducer';
|
||||
export * from './notification.state';
|
||||
export * from './notification.effect';
|
|
@ -3,7 +3,7 @@ import { Store, select } from '@ngrx/store';
|
|||
|
||||
import { RPCSubscriber } from '@loafer/ng-rpc/decorator';
|
||||
|
||||
import * as DiscoveryStore from '../store/notification';
|
||||
import * as DiscoverStore from '../store/discover';
|
||||
|
||||
import {
|
||||
Zone,
|
||||
|
@ -16,24 +16,28 @@ import {
|
|||
export class DiscoverySubscriber {
|
||||
|
||||
public constructor(
|
||||
private store: Store<DiscoveryStore.State>,
|
||||
private store: Store<DiscoverStore.State>,
|
||||
) {
|
||||
}
|
||||
|
||||
@RPCSubscriber({method: 'DiscoveryService.discoveredZone'})
|
||||
public discoveredZone(zone: Zone): void {
|
||||
this.store.dispatch(new DiscoveryStore.DiscoveredZone(zone));
|
||||
console.log(`DiscoverySubscriber.discoveredZone zone:${zone}`);
|
||||
|
||||
this.store.dispatch(new DiscoverStore.DiscoveredZone(zone));
|
||||
}
|
||||
@RPCSubscriber({method: 'DiscoveryService.discoveredHost'})
|
||||
public discoveredHost(host: Host): void {
|
||||
this.store.dispatch(new DiscoveryStore.DiscoveredHost(host));
|
||||
console.log(`DiscoverySubscriber.discoveredHost host:${host}`);
|
||||
|
||||
this.store.dispatch(new DiscoverStore.DiscoveredHost(host));
|
||||
}
|
||||
@RPCSubscriber({method: 'DiscoveryService.discoveredPort'})
|
||||
public discoveredPort(port: Port): void {
|
||||
this.store.dispatch(new DiscoveryStore.DiscoveredPort(port));
|
||||
this.store.dispatch(new DiscoverStore.DiscoveredPort(port));
|
||||
}
|
||||
@RPCSubscriber({method: 'DiscoveryService.discoveredService'})
|
||||
public discoveredService(service: Service): void {
|
||||
this.store.dispatch(new DiscoveryStore.DiscoveredService(service));
|
||||
this.store.dispatch(new DiscoverStore.DiscoveredService(service));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user