Skip to content

ThorIO.Controller

Magnus Thor edited this page Feb 8, 2017 · 5 revisions

ThorIO.Controller

A ThorIO.Controller is an endpoint that the client(s) can connect to using its alias (see client). Extend your class such as follows. Note the super(connection) call within the constructor. You also need to look at the decorators section below as your controller behavior relys on them.

@ControllerProperties("myController",false)
export class MyController extends ThorIO.Controller
{
	constructor(connection:ThorIO.Connection){
		super(connection);
	}
}

Decorators

Decorators are used to describe and controll the behavior of your controllers. There are three different decorators that you need to know of, ControllerProperties, CanInvoke and CanSet. The Decorators is automaticly reflected when you register your controller to the ThorIO.Engine.

Your tsconfig.json must have tge following entry

{
...
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
...
}

@ControllerProperties(alias:string,isSeald?:boolean = false)

The ControllerProperties is applied to your controller class, it set the alias of the controller, tells if it seald as well as its actually makes your controller class able to register to the ThorIO.Engine.

alias:string

Set the alias on the controller. The alias of the controller is used when you connect from using ThorIOClient.

@ControllerProperties("foo")
export class FooController extends ThorIO.Controller {

	constructor(connection:ThorIO.Connection){
		super(connection);
	}
}

In this case the controller FooController will be know as "foo"

isSeald:boolean

By setting the seald parameter of the ControllerProperties declares if a controller can be used by a client. A seald controller is will automaticly be created by the ThorIO.Engine, as a singelton instance of that particular controller. A seald (true) cannot called from a client, but it can invoke, and publish informations to any client connected to the Engine. A seal controller can be used as Task runner on the server side and produce data for 1-many clients.

CanInvoke(boolean)

Methods that you want the client to be able to invoke / call must be decorated with the @CanSet(true) attribute, the default behavior is to not allow clients to invoke methods.

...
@CanInvoke(true);
public MyMethod(data:any)
{

}

CanSet(boolean)

Properties within your controller can be modified (set) by the client. As each client has it own unique instance of a each controller. Properties can be modified and therefore act as a mechanisem for keeping different state.

....
@CanSet(true)
public age:number;

##Events

onopen(timestamp:Date)

If implemented, onopen will be fired when a client creates a ThorIO.Channel to the controller.

  @ControllerProperties("foo")
  export class FooController extends ThorIO.Controller {
  
	constructor(connection:ThorIO.Connection){
		super(connection);
	}
	
	onopen(ts:Date){
		// do op
	}

  }

onreconnect(connection:ThorIO.Connection,timestamp:Date)

TBD

onclose(timestamp:Date)

If implemented, onclose will be fired when a client close a ThorIO.Channel to the controller.

  @ControllerProperties("foo")
  export class FooController extends ThorIO.Controller {
  
	constructor(connection:ThorIO.Connection){
		super(connection);
	}
	
	onopen(ts:Date){
		// do op
	}

  }

##Methods

close()

This closes a connection to the controller. When .close() is called, the client will be notified (onclose will be fired on the ThorIO.Channel for the actual controller)

invoke(data:any,topic:string,controller:string) : ThorIO.Controller

Invokes/calls a method in the client for the callee.

 // send a message to the callee on 'foo'

  @ControllerProperties("foo")
  export class FooController extends ThorIO.Controller {
  
	constructor(connection:ThorIO.Connection){
		super(connection);
	}
	
	@CanInvoke(true)
	public Say = function (sayMessage:SayMessage,topic:string,controller:string) {

   	 this.invoke(sayMessage, "sayResult");

	};


  }

When method Say is called, the controller ("foo") will send and invoke a method on the callee client named sayResult and pass the data:SayMessage, in this case SayMessage

Our client would then have a method such as the following defined (JavaScript)

  ..

  foo.sayResult = function(sayMessage){
		console.log(sayMessage)
  };

  ..

invokeToAll(data:any,topic:string,controller:string) : ThorIO.Controller

The difference between invokeTo and invoke is that the controller will invoke the specified method on all connected clients - in other words, send and invoke to all connected to the specified controller.

// send a message to all clients connected to 'foo'

..

@CanInvoke(true)
public Say = function (sayMessage:SayMessage,topic:string,controller:string) {

   	 this.invokeToAll(sayMessage, "sayResult");

};

Note: the topic could of course be different from sayResult

invokeToOthers(data: any, topic: string, controller?: string, buffer?: any): ThorIO.Controller

This method is similar to the invokeToAll method, the difference is that it will invoke the method on all connected clients except the the callee.

/ send a message to all clients connected to 'foo'
..

@CanInvoke(true)
public Say = function (sayMessage:SayMessage,topic:string,controller:string) {

   	 this.invokeToOthers(sayMessage, "sayResult");

};

.invokeTo(expression:Function,data:any,topic:string,controller:string) : ThorIO.Controller

invokeTo is a powerful method used in order to target specific clients connected to a controller as you can create an expression (filter) based on each client's specific state.

Where our controller uses the invokeTo extension ( method ) to pass a filter, such as the expression below, to target a client (connection) with a specific state:

 // send a message to the callee on 'foo'

  @ControllerProperties("foo")
  export class FooController extends ThorIO.Controller {
  
    @CanSet(true);
	public age:number;
	constructor(connection:ThorIO.Connection){
		super(connection);
		this.age = 1;  // set default age to 1
	}
	
	@CanInvoke(true)
	public Say = function (sayMessage:SayMessage,topic:string,controller:string) {

		var expression = (pre:FooController) {
			return pre.age >= 10;
		};

	
   	 this.invokeTo(expression,sayMessage, "sayResult");

	};

  }

publish(data:any,topic:string,controller:string): ThorIO.Controller

Publish a message to the callee. The message will only be sent if the current client has created a subscription ( see channels )

  ..
  public SendStuff(mesasge:SayMessage) {

	   this.publish(sayMessage, "bar");

  }

In this case the client has to create a subscription for bar. If no subscription exists, the message will not be delivered.

publishToAll(data:any,topic:string,controller:string): ThorIO.Controller

Publish a message to all connected clients subscribing to the topic.

 ..
  public SendStuff(mesasge:SayMessage) {

	   this.publishToAll(sayMessage, "bar");

  }

In this case the client(s) have to create a subscription for bar. If no subscription exists, the message will not be delivered.

publishTo(expression:Function,data:Object,topic:string,controller:string): void

Publish a message to all connected clients who have subscribed to the topic and are filtered by the expression.

  @ControllerProperties("foo")
  export class FooController extends ThorIO.Controller {
  
    @CanSet(true);
	public age:number;
	constructor(connection:ThorIO.Connection){
		super(connection);
		this.age = 1;  // set default age to 1
	}
	
	@CanInvoke(true)
	public Say = function (sayMessage:SayMessage,topic:string,controller:string) {

		var expression = (pre:FooController) {
			return pre.age >= 10;
		};

	
   	 this.publishTo(expression,sayMessage, "sayResult");

	};

  }

hasSubscription(topic: string): boolean

If you want to check if the current client ( ThorIO.Connection) has subscription for a specific topic.

addSubscription(topic: string): void

Adds an subscription for the specific topic to the current client (Connection). Adding a subscription on the controller will not automaticly add a subscription on the client, but if a message is published in the topic and a subscription exists, it will be sent.

removeSubscription(topic: string): void

Remove (unsubscribe) to a specific topic.

.getConnections(alias:String): Array<ThorIO.Connection>

get all clients (connections) on the specified controller.y If no alias specific you will get all connections to the current controller

...
let allConnections = this.getConnections("foo")

findOn(alias: string, predicate: (item: any) => boolean): Array;

TBD

find<T, U>(array: T[], predicate: (item: any) => boolean, selector?: (item: T) => U): U[];

TBD