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';
|
export * from './token';
|
||||||
|
|
|
@ -3,12 +3,14 @@ import { Store, select } from '@ngrx/store';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Type,
|
Type,
|
||||||
|
PropertyKeyType,
|
||||||
} from '@loafer/core';
|
} from '@loafer/core';
|
||||||
|
|
||||||
import { TypeUtil } from '@loafer/core/util/TypeUtil';
|
import { TypeUtil } from '@loafer/core/util/TypeUtil';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Class,
|
Class,
|
||||||
|
Method,
|
||||||
Metadata,
|
Metadata,
|
||||||
} from '@loafer/core/reflect';
|
} from '@loafer/core/reflect';
|
||||||
|
|
||||||
|
@ -17,14 +19,26 @@ import { RPCSubscriberDecorator } from '../decorator';
|
||||||
import {
|
import {
|
||||||
RPCClientNotificationCodec,
|
RPCClientNotificationCodec,
|
||||||
} from '../protocol';
|
} from '../protocol';
|
||||||
|
import { SubscriberParameterError } from '../core';
|
||||||
|
|
||||||
|
export interface SubscriberMethod {
|
||||||
|
className: PropertyKeyType;
|
||||||
|
methodName: PropertyKeyType;
|
||||||
|
parameterTypes: string[];
|
||||||
|
|
||||||
|
method: Method;
|
||||||
|
instance: any;
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RPCSubscribeService {
|
export class RPCSubscribeService {
|
||||||
private subscribers: Set<any>;
|
private subscribers: Set<any>;
|
||||||
|
private subscriberMethodMap: Map<string, SubscriberMethod[]>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
) {
|
) {
|
||||||
this.subscribers = new Set();
|
this.subscribers = new Set();
|
||||||
|
this.subscriberMethodMap = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
public addSubscriber(subscriber: Type<any>): void {
|
public addSubscriber(subscriber: Type<any>): void {
|
||||||
|
@ -46,11 +60,100 @@ export class RPCSubscribeService {
|
||||||
const methods = clazz.getMethods();
|
const methods = clazz.getMethods();
|
||||||
methods.forEach((method, propertyKey) => {
|
methods.forEach((method, propertyKey) => {
|
||||||
const annon = method.getAnnotation(RPCSubscriberDecorator);
|
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 {
|
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';
|
} from '../../model';
|
||||||
import * as CIDR from 'ip-cidr';
|
import * as CIDR from 'ip-cidr';
|
||||||
import * as DiscoveredStore from '../../store/setting';
|
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({
|
@Component({
|
||||||
selector: 'of-setting',
|
selector: 'of-setting',
|
||||||
|
@ -21,7 +21,7 @@ import { SettingSelector, NotificationSelector } from '../../store';
|
||||||
export class SettingComponent implements OnInit, AfterContentInit {
|
export class SettingComponent implements OnInit, AfterContentInit {
|
||||||
|
|
||||||
settingSucceed$ = this.discoverdstore.pipe(select(SettingSelector.select('isStart')));
|
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;
|
started = false;
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,11 @@ import {
|
||||||
DiscoverHost = '[discovery.discovery] discoverHost',
|
DiscoverHost = '[discovery.discovery] discoverHost',
|
||||||
DiscoverPort = '[discovery.discovery] discoverPort',
|
DiscoverPort = '[discovery.discovery] discoverPort',
|
||||||
DiscoverService = '[discovery.discovery] discoverService',
|
DiscoverService = '[discovery.discovery] discoverService',
|
||||||
DiscoveredZone = '[@@NOTIFICATION] DiscoveryService.discoveredZone',
|
|
||||||
DiscoveredHost = '[@@NOTIFICATION] DiscoveryService.discoveredHost',
|
DiscoveredZone = '[discovery.discovery] DiscoveryService.discoveredZone',
|
||||||
DiscoveredPort = '[@@NOTIFICATION] DiscoveryService.discoveredPort',
|
DiscoveredHost = '[discovery.discovery] DiscoveryService.discoveredHost',
|
||||||
DiscoveredService = '[@@NOTIFICATION] DiscoveryService.discoveredService',
|
DiscoveredPort = '[discovery.discovery] DiscoveryService.discoveredPort',
|
||||||
|
DiscoveredService = '[discovery.discovery] DiscoveryService.discoveredService',
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DiscoverZone implements Action {
|
export class DiscoverZone implements Action {
|
|
@ -1,8 +1,8 @@
|
||||||
import { TestBed, inject } from '@angular/core/testing';
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
import { Effects } from './notification.effect';
|
import { Effects } from './discover.effect';
|
||||||
|
|
||||||
describe('Notification.Effects', () => {
|
describe('Discover.Effects', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [Effects]
|
providers: [Effects]
|
|
@ -20,7 +20,7 @@ import {
|
||||||
DiscoverPort,
|
DiscoverPort,
|
||||||
DiscoverService,
|
DiscoverService,
|
||||||
ActionType
|
ActionType
|
||||||
} from './notification.action';
|
} from './discover.action';
|
||||||
import {DiscoveryService} from '../../service/discovery.service';
|
import {DiscoveryService} from '../../service/discovery.service';
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import {
|
import {
|
||||||
Actions,
|
Actions,
|
||||||
ActionType,
|
ActionType,
|
||||||
} from './notification.action';
|
} from './discover.action';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
State,
|
State,
|
||||||
initialState,
|
initialState,
|
||||||
} from './notification.state';
|
} from './discover.state';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Zone,
|
Zone,
|
||||||
|
@ -19,7 +19,9 @@ export function reducer(state = initialState, action: Actions): State {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case ActionType.DiscoveredZone: {
|
case ActionType.DiscoveredZone: {
|
||||||
const zone: Zone = <Zone>action.payload;
|
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;
|
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 { MODULE } from '../discovery.constant';
|
||||||
|
|
||||||
|
|
||||||
import * as NotificationStore from './notification';
|
import * as DiscoverStore from './discover';
|
||||||
import * as SettingStore from './setting';
|
import * as SettingStore from './setting';
|
||||||
|
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
notification: NotificationStore.State;
|
discover: DiscoverStore.State;
|
||||||
setting: SettingStore.State;
|
setting: SettingStore.State;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const REDUCERS = {
|
export const REDUCERS = {
|
||||||
notification: NotificationStore.reducer,
|
discover: DiscoverStore.reducer,
|
||||||
setting: SettingStore.reducer,
|
setting: SettingStore.reducer,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EFFECTS = [
|
export const EFFECTS = [
|
||||||
SettingStore.Effects,
|
SettingStore.Effects,
|
||||||
NotificationStore.Effects,
|
DiscoverStore.Effects,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const selectDiscoveryState = createFeatureSelector<State>(MODULE.name);
|
export const selectDiscoveryState = createFeatureSelector<State>(MODULE.name);
|
||||||
|
|
||||||
export const NotificationSelector = new StateSelector<NotificationStore.State>(createSelector(
|
export const DiscoverSelector = new StateSelector<DiscoverStore.State>(createSelector(
|
||||||
selectDiscoveryState,
|
selectDiscoveryState,
|
||||||
(state: State) => state.notification
|
(state: State) => state.discover
|
||||||
));
|
));
|
||||||
|
|
||||||
export const SettingSelector = new StateSelector<SettingStore.State>(createSelector(
|
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 { RPCSubscriber } from '@loafer/ng-rpc/decorator';
|
||||||
|
|
||||||
import * as DiscoveryStore from '../store/notification';
|
import * as DiscoverStore from '../store/discover';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Zone,
|
Zone,
|
||||||
|
@ -16,24 +16,28 @@ import {
|
||||||
export class DiscoverySubscriber {
|
export class DiscoverySubscriber {
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private store: Store<DiscoveryStore.State>,
|
private store: Store<DiscoverStore.State>,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@RPCSubscriber({method: 'DiscoveryService.discoveredZone'})
|
@RPCSubscriber({method: 'DiscoveryService.discoveredZone'})
|
||||||
public discoveredZone(zone: Zone): void {
|
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'})
|
@RPCSubscriber({method: 'DiscoveryService.discoveredHost'})
|
||||||
public discoveredHost(host: Host): void {
|
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'})
|
@RPCSubscriber({method: 'DiscoveryService.discoveredPort'})
|
||||||
public discoveredPort(port: Port): void {
|
public discoveredPort(port: Port): void {
|
||||||
this.store.dispatch(new DiscoveryStore.DiscoveredPort(port));
|
this.store.dispatch(new DiscoverStore.DiscoveredPort(port));
|
||||||
}
|
}
|
||||||
@RPCSubscriber({method: 'DiscoveryService.discoveredService'})
|
@RPCSubscriber({method: 'DiscoveryService.discoveredService'})
|
||||||
public discoveredService(service: Service): void {
|
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