Add Modello web sample applications; version up
[profile/ivi/sdk/web-sample-build.git] / samples / web / Sample / Tizen / Web App / Modello_SDL / project / ffw / RPCClient.js
1 /*
2  * Copyright (c) 2013, Ford Motor Company All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *  · Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  *  · Redistributions in binary form must reproduce the above copyright notice,
9  * this list of conditions and the following disclaimer in the documentation
10  * and/or other materials provided with the distribution.
11  *  · Neither the name of the Ford Motor Company nor the names of its
12  * contributors may be used to endorse or promote products derived from this
13  * software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 /*
28  * Base class for RPC client
29  *
30  * Class provides access to basic functionality of RPC components Message Broker
31  * as: registerComponent unregisterComponent subscription to notifications logic
32  * to calculate request id
33  */
34
35 FFW.RPCClient = Em.Object.extend( {
36
37     /*
38      * transport layer for messages exchange
39      */
40     socket: null, // instance of websocket
41
42     /*
43      * url for message broker
44      */
45     url: "ws://localhost:8087",
46
47     /*
48      * Component name in RPC system It is unique.
49      */
50     componentName: null,
51
52     /*
53      * observer of RPC states
54      */
55     observer: null,
56
57     /*
58      * these variables are used to have unique request ids for different
59      * components in RPC bus idStart is received as a response for
60      * registerRPCComponent messages. space for ids for specific RPC component
61      * is allocated by message broker
62      */
63     idStart: -1,
64     idRange: 1000,
65     requestId: -1,
66
67     registerRequestId: -1,
68     unregisterRequestId: -1,
69
70     /*
71      * Open WebSocket and initialize handlers
72      */
73     connect: function( observer, startId ) {
74         this.observer = observer;
75         this.idStart = startId;
76
77         this.socket = new WebSocket( this.url, 'sample' );
78
79         var self = this;
80
81         this.socket.onopen = function( evt ) {
82             self.onWSOpen( evt )
83         };
84         this.socket.onclose = function( evt ) {
85             self.onWSClose( evt )
86         };
87         this.socket.onmessage = function( evt ) {
88             self.onWSMessage( evt )
89         };
90         this.socket.onerror = function( evt ) {
91             self.onWSError( evt )
92         };
93
94     },
95
96     /*
97      * Close WebSocket connection Please make sure that component was
98      * unregistered in advance
99      */
100     disconnect: function() {
101         this.unregisterRPCComponent();
102     },
103
104     /*
105      * WebSocket connection is ready Now RPC component can be registered in
106      * message broker
107      */
108     onWSOpen: function( evt ) {
109         Em.Logger.log( "RPCCLient.onWSOpen" );
110
111         this.registerRPCComponent();
112     },
113
114     /*
115      * when result is received from RPC component this function is called It is
116      * the propriate place to check results of reuqest execution Please use
117      * previously store reuqestID to determine to which request repsonse belongs
118      * to
119      */
120     onWSMessage: function( evt ) {
121         Em.Logger.log( "Message received: " + evt.data );
122
123         var jsonObj = JSON.parse( evt.data );
124
125         // handle component registration
126         if( jsonObj.id == this.registerRequestId ){
127             if( jsonObj.error == null ){
128                 this.requestId = this.idStart = jsonObj.result;
129                 this.observer.onRPCRegistered();
130             }
131             // handle component unregistration
132         }else if( jsonObj.id == this.unregisterRequestId ){
133             if( jsonObj.error == null ){
134                 this.socket.close();
135                 this.observer.onRPCUnregistered();
136             }
137             // handle result, error, notification, requests
138         }else{
139             if( jsonObj.id == null ){
140                 this.observer.onRPCNotification( jsonObj );
141             }else{
142                 if( jsonObj.result != null )
143                     this.observer.onRPCResult( jsonObj );
144                 else if( jsonObj.error != null )
145                     this.observer.onRPCError( jsonObj );
146                 else
147                     this.observer.onRPCRequest( jsonObj );
148             }
149         }
150     },
151
152     /*
153      * WebSocket connection is closed Please make sure that RPCComponent was
154      * dunregistered in advance
155      */
156     onWSClose: function( evt ) {
157         Em.Logger.log( "RPCClient: Connection is closed" );
158         this.observer.onRPCDisconnected();
159     },
160
161     /*
162      * WebSocket connection errors handling
163      */
164     onWSError: function( evt ) {
165         // Em.Logger.log("ERROR: " + evt.data);
166         Em.Logger.log( "ERROR: " );
167     },
168
169     /*
170      * register component is RPC bus
171      */
172     registerRPCComponent: function() {
173         this.registerRequestId = this.idStart;
174
175         var JSONMessage = {
176             "jsonrpc": "2.0",
177             "id": this.registerRequestId,
178             "method": "MB.registerComponent",
179             "params": {
180                 "componentName": this.componentName
181             }
182         };
183         this.send( JSONMessage );
184     },
185
186     /*
187      * unregister component is RPC bus
188      */
189     unregisterRPCComponent: function() {
190         this.unregisterRequestId = this.generateId();
191
192         var JSONMessage = {
193             "jsonrpc": "2.0",
194             "id": this.unregisterRequestId,
195             "method": "MB.unregisterComponent",
196             "params": {
197                 "componentName": this.componentName
198             }
199         };
200         this.send( JSONMessage );
201     },
202
203     /*
204      * Subscribes to notification. Returns the request's id.
205      */
206     subscribeToNotification: function( notification ) {
207         var msgId = this.generateId();
208         var JSONMessage = {
209             "jsonrpc": "2.0",
210             "id": msgId,
211             "method": "MB.subscribeTo",
212             "params": {
213                 "propertyName": notification
214             }
215         };
216         this.send( JSONMessage );
217         return msgId;
218     },
219
220     /*
221      * Unsubscribes from notification. Returns the request's id.
222      */
223     unsubscribeFromNotification: function( notification ) {
224         var msgId = this.client.generateId();
225         var JSONMessage = {
226             "jsonrpc": "2.0",
227             "id": msgId,
228             "method": "MB.unsubscribeFrom",
229             "params": {
230                 "propertyName": notification
231             }
232         };
233         this.send( JSONMessage );
234         return msgId;
235     },
236
237     /*
238      * stringify object and send via socket connection
239      */
240     send: function( obj ) {
241         if( this.socket.readyState == this.socket.OPEN ){
242             var strJson = JSON.stringify( obj );
243             Em.Logger.log( strJson );
244             this.socket.send( strJson );
245         }else{
246             Em.Logger.error( "RPCClient: Can't send message since socket is not ready" );
247         }
248     },
249
250     /*
251      * Generate id for new request to RPC component Function has to be used as
252      * private
253      */
254     generateId: function() {
255         this.requestId++;
256         if( this.requestId >= this.idStart + this.idRange )
257             this.requestId = this.idStart;
258         return this.requestId;
259     }
260
261 } )