350 likes | 520 Views
Exercise TK3 Assigment 2: RMC & WorldView. FG Telekooperation Prof. Dr. Max Mühlhäuser Daniel Schreiber. Exercise Groups. Outline. RMC RMC with MundoCore MCC precompiler WorldView. Pub/Sub with MundoCore. // sending a message : public void run() { //…
E N D
Exercise TK3Assigment 2: RMC & WorldView FG Telekooperation Prof. Dr. Max Mühlhäuser Daniel Schreiber
Outline • RMC • RMC with MundoCore • MCC precompiler • WorldView
Pub/Sub with MundoCore //sending a message: public void run() { //… TypedMap map = new TypedMap(); map.putString("ln", ln); publisher.send(newMessage(map)); //… } //receiving a message publicvoidreceived(Messagemsg, MessageContextctx) { System.out.println(msg.getMap().getString("ln")); }
Publish Subscribe Chat Disadvantage: Messages have to be created and parsed “by hand” (new Message() …)
A More Complex Example public void foo(inta) { } public void bar(String b) { } //parsingthemessageanddispatchingtomethods publicvoidreceived(Messagemsg, MessageContextctx) { String method = msg.getMap().getString(“call")); if (“foo”.equals(method)) { foo(msg.getMap().getInt(“p0")); } if (“bar”.equals(method)) { foo(msg.getMap().getString(“p0")); } }
RMC • Message dispatch • Parameter marshalling • RMC means: This is done by the middleware • you just implement foo and bar and the middleware takes care of dispatching and marshalling String method = msg.getMap().getString(“call")); if (“foo”.equals(method)) { … } if (“bar”.equals(method)) { … } foo(msg.getMap().getString(“p0"));
Remote Method Call Chat Service Marshalling Demarshalling • RMC builds upon Publish/Subscribe • Same syntax for local and remote method calls • Service provides methods via interface: • Service subscribes for service requests • Service publishes service results • Marshalling/Demarshalling of parameters needed
RMC with MundoCore Java MyClient MyService MyService do void foo(int a) o2.foo(5); o1: MyClient do = o2 o2: MyService MundoCore Node A MundoCore Node B MundoCore
RMC with MundoCore Java Thisdoes not work! classMyService must bedeclared in Node A o2 hasnoaddress in Node A implementationofMyService (Node B) shouldworkwithoutmanualdispatch MyClient MyService MyService do void foo(int a) o2.foo(5); o1: MyClient do = o2 o2: MyService MundoCore Node A MundoCore Node B MundoCore
RMC with MundoCore Java MyClient DoMyService SrvMyService MyService DoMyService do void foo(int a) MyService o void foo(int a) o1: MyClient o2: DoMyService s: SrvMyService do = o2 o2: MyService o = o2 o2.foo(5); MundoCore Node A MundoCore Node B MundoCore
What do the helper classes do? • SrvMyService contains a generic dispatch method • look at message • decide which method to call • parse parameters • call method of associated object • create a message with results • send via MundoCore pub/sub • DoMyService contains a generic MundoCore wrapper • create a message with method name and parameters • send via MundoCore pub/sub • [wait for result] • [return result to caller]
Advantages / Disadvantages of RMC • + code is much more readable • + MundoCore handling is isolated in one place • - client must have interface description from server • - need to write lots of boilerplate code • This can be avoided by using a precompiler!! • Mundo contains the mcc precompiler • Have a look in the ant build file • files in prep directory are created by mcc • caveat: Eclipse does not know when to invoke mcc!
Creating Distributed Objects • Creating the boilerplate code for distributed objects: • MundoCore (Pre-)Compiler • creates client- and server-stubs • creates code for serializer and deserializer • Rerun mcc whenever the interface changes! Mustbeavailable at theclient!! MyService.java Client-Stub, „Distributed Object“ DoMyService.java mcc SrvMyService.java Server-Stub
Generating Do… from interface only • Normally mcc does not have access to server implementation MyService • e.g. service provider only publishes WSDL • DoMyService must be created from interface only • @mcImport: The following class must be generated by mcc from WSDL • mcc –I <path-to-wsdl-interfaces> //@mcImport import org.mundo.service.wmstore.WMStoreService; import org.mundo.service.wmstore.DoWMStoreService;
How to make methods RMC-able? • Serviceclasses have to be marked with @mcRemote • Remote available methods have to be marked with @mcMethod • mcc creates the required stubs • Example: @mcRemote class ChatService extends Service { … @mcMethod publicvoid chatMessage(String msg) { System.out.println(msg); } }
Connecting RMC Server & Client • Server: publicboolean init() { … Signal.connect(getSession().subscribe("lan", "chat_rmc"), this); … } • Client DoMyService stub = new DoMyService(); Signal.connect(stub,getSession().publish("lan", "chat_rmc")); • If you invoke a method on the stub object, it will be called on all objects of class MyService listening to „chat_rmc“ • For invoking the method only on one distributed objects, you need to store the reference to this object and invoke the method directly on it.
Method invocations • Synchron: Client is blocked until result is returned • One-way („fire and forget“): Client invokes method, but does not wait for the answer • Asynchron: Client invokes method, but retrieves answer later or specifies callback method that is called as soon as the result is available
Method invocations II • All methods that are available via RMC are extended by an additional parameter that specifies the type of method invocation: • Synchron:stub.chatMessage(„hallo“); • One-way („fire and forget“)stub.chatMessage(„hallo“, DoChatService.ONEWAY); • Asynchron to retrieve returnvalue later: AsyncCall callObject = stub.add(1, 2, DoCalculator.ASYNC); … int result = ((Integer)callObject.getObj()).intValue(); or to specify a callback method: AsyncCall callObject = stub.add(1, 2, DoCalculator.CREATEONLY); callObject.setResultListener(new AsyncCall.IResultListener() { publicvoid resultReceived(AsyncCall callObject) { int rslt = ((Integer)callObject.getObj()).intValue(); } }); callObject.invoke();
De/Marshalling • To use an object as parameter / returnvalue classes need to be serializable • Primitive datatypes, references on distributed objects (Do…) are serializable • Serializing own classes: • mcc can build serializing metadata for own classes. For that purpose these classes have to be marked with @mcSerialize • All public fields need to be serializable • The class has to specify a public nullary constructor • Resulting classes start with Meta… • Mapping from classname to metaclass is configured in file metaclasses.xml needs to be in the path! • Eclipse may cause problems What is the path?
De/Marshalling • Example: • „name“ can be transmitted by-value • To transmit „address“ by-value needs to be serialized: Address Street=… City=…
De/Marshalling • To transmit „address“ by-reference: • Each distributed object has a unique ID that corresponds to the channelname they are subscribed to. • The object that invokes the method adds its ID to the message to receive results
DeMarshalling • publicclassMetaAddress { • voidactivate(Object o, TypedMap m) { • Address t=(Address)o; • Address.street = m.getString(„Street“); • … • } • } Metaclass Address Object
WorldView • UbiComp applications often involve real world data • Entering and leaving the room to test your ContextAwareLightSwitch is impractical • Idea: Simulate the sensor data for testing purposes • Mundo provides the WorldView Tool for this • WorldView allows to • view, edit and create world models • simulate sensor data by moving the model elements • update model elements based on sensor data
WorldView II application MundoCore events simulated world, simulated sensors „WorldView“ real world via sensors automatic updates Testing of application, testing of real world sensors
Assignment 2 • Download, compile & run WorldView • Create a WorldModel and save it • Implement a MundoCore service LightSwitch • Implement a ContextAwareLightSwitch service • Implement your own Lamp service
WorldView • Download at: https://leda.tk.informatik.tu-darmstadt.de/cgi-bin/twiki/view/Mundo/MundoDownloads • runwithjava –jar worldview.jar
Adding Items • Room: Tool -> Rectangle • add pickable classes „region“ • give the rectangle a name • Light: Tool -> Building Automation -> Lamp • set the channel the lamp listens on • Location Tracking: Tool -> Mundo IRIS -> Badge & Camera
Simulating Sensor Data • set a channel for IRIS Camera • start IRIS Cient: File -> Iris Client • check the „simulate“ box • have a look at the events generated by moving the IRIS Badge around in Inspect
Saving the new World • Start the „worldmodelstore“ • wmstore.zip from homepage • java –jar wmstore-app.jar • File -> Upload • The World is now available for all other services in the WorldModel store • This needs to be done after creating or loading a new world in WorldView • File -> Save As… • save as a file, so you can load it later
Accessing the WorldModel • wmstore stores WorldModel in wmstore-db.xml • To access the worldmodel clients can use an API via RMC • example: wmstore-querytest • mcc needs to know the interface of WMStore to generate DoWMStore (see slide 15) • interfaces in interfaces.zip • Look at the ant file in wmstore-querytest.zip
Service LightSwitch • skeleton provided in lamp.zip on the homepage • should start with java –cp /…/mundocore.jar LightSwitch <channel> • Reads from the command-line • ‚1‘ turns the light on • ‚0‘ turns the light off • ‚?‘ outputs the current state of the light • Use RMC • use mcc to create the stub DoLamp from org.mundo.bas.Ilamp • Ilamp is defined in interfaces.zip • mcc -09 –x –Oprep –I../interfaces src/*.java • will generate stubs in dir prep • connecting to the lamp in WorldView see the example on slide 16
Your LampServer • Imagine you want to provide a real implementation of the LightService, e.g. a LED controlled via RS232 • Write a MundoCore Service • that implements the ILamp interface • can be used by your LightSwitch via MundoCore RMC • controls a real LED… • or outputs „on“ / „off“ on the console • You need to connect an instance of your service to a MundoCore channel like shown on slide 16
Service ContextAwareLightSwitch • connect to the IRIS event Channel • IRIS events contain serialized IRISSpaceCoordTable object • IRIS classes are contained in interfaces.zip • see example in iris-receiver.zip • whenever you receive an event, compute whether a user is in a „room“ • If user is in room turn light on, else turn light off • You need to query the WorldModel to compare user coordinates with room coordinates • Look at the example in wmstore-querytest.zip • we will test your service with our own worldmodels • You can also get channel information, lamps… from worldmodel
Grading • Hand in a zip file containing: • A screenshot of your world in WorldView 5% • the corresponding wmstore-db.xml from wmstore 5% • The sourcecode and build instructions (or ant files) for your services • LightSwitch 25% • ContextAwareLightSwitch 30% • LightService implementation 25% • a video / screencast showing how the ContextAwareLightSwitch is working 10% • Deadline: Sunday 17.05. 24:00