tizen 2.4 release
[framework/web/wrt-commons.git] / examples / metronome / metronome_server.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        metronome_server.cpp
18  * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @version     1.0
20  * @brief       This file is the implementation file of metronome server example
21  */
22 #include <stddef.h>
23 #include <dpl/tcp_socket_rpc_server.h>
24 #include <dpl/tcp_socket_rpc_connection.h>
25 #include <dpl/controller.h>
26 #include <dpl/application.h>
27 #include <dpl/type_list.h>
28 #include <dpl/log/wrt_log.h>
29 #include <algorithm>
30 #include <list>
31 #include <dpl/assert.h>
32
33 // Metronome signal event
34 DECLARE_GENERIC_EVENT_0(SignalEvent)
35 DECLARE_GENERIC_EVENT_1(DeleteConnectionEvent, DPL::AbstractRPCConnection *)
36
37 // Heart beat interval
38 const double HEART_BEAT_INTERVAL = 1.0; // seconds
39
40 class MetronomeServerApplication
41     : public DPL::Application,
42       private DPL::Controller<DPL::TypeListDecl<SignalEvent,
43                                                 DeleteConnectionEvent>::Type>,
44       private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>,
45       private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>,
46       private DPL::EventListener<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>
47 {
48 private:
49     DPL::TcpSocketRPCServer m_rpcServer;
50
51     typedef std::list<DPL::AbstractRPCConnection *> ConnectionList;
52     ConnectionList m_connections;
53
54     // Matronome signal received
55     virtual void OnEventReceived(const SignalEvent &event)
56     {
57         (void)event;
58
59         // Signal all conection about heart beat
60         DPL::RPCFunction proc;
61         proc.AppendArg((int)0);
62
63         for (ConnectionList::iterator it = m_connections.begin(); it != m_connections.end(); ++it)
64             (*it)->AsyncCall(proc);
65
66         // Continue to emot heart beats
67         DPL::ControllerEventHandler<SignalEvent>::PostTimedEvent(SignalEvent(), HEART_BEAT_INTERVAL);
68     }
69
70     virtual void OnEventReceived(const DeleteConnectionEvent &event)
71     {
72         delete event.GetArg0();
73     }
74
75     void RemoveConnection(DPL::AbstractRPCConnection *connection)
76     {
77         // Find connection
78         ConnectionList::iterator it = std::find(m_connections.begin(), m_connections.end(), connection);
79         Assert(it != m_connections.end());
80
81         // Erase connection
82         m_connections.erase(it);
83
84         // Detach RPC connection listeners
85         connection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::RemoveListener(this);
86         connection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::RemoveListener(this);
87
88         // Delete connection
89         DPL::ControllerEventHandler<DeleteConnectionEvent>::PostEvent(DeleteConnectionEvent(connection));
90     }
91
92     void AddConnection(DPL::AbstractRPCConnection *connection)
93     {
94         // Add connection
95         m_connections.push_back(connection);
96
97         // Attach event listeners
98         connection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::AddListener(this);
99         connection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::AddListener(this);
100     }
101
102     virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent &event)
103     {
104         (void)event;
105
106         WrtLogD("Connection closed");
107
108         // Remove connection from list
109         RemoveConnection(static_cast<DPL::AbstractRPCConnection *>(event.GetSender()));
110     }
111
112     virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event)
113     {
114         (void)event;
115
116         WrtLogD("Connection broken");
117
118         // Remove connection from list
119         RemoveConnection(static_cast<DPL::AbstractRPCConnection *>(event.GetSender()));
120     }
121
122     virtual void OnEventReceived(const DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent &event)
123     {
124         // Save connection pointer
125         WrtLogD("New connection");
126
127         // Add nre connection to list
128         AddConnection(event.GetArg1());
129     }
130
131 public:
132     MetronomeServerApplication(int argc, char **argv)
133         : Application(argc, argv, "rpc")
134     {
135         // Attach RPC server listeners
136         m_rpcServer.DPL::EventSupport<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::AddListener(this);
137
138         // Inherit calling context
139         Touch();
140
141         // Open RPC server
142         m_rpcServer.Open(12345);
143
144         // Start heart beat
145         DPL::ControllerEventHandler<SignalEvent>::PostTimedEvent(SignalEvent(), HEART_BEAT_INTERVAL);
146
147         // Started
148         WrtLogD("Metronome server started");
149      }
150
151     virtual ~MetronomeServerApplication()
152     {
153         // Delete all RPC connections
154         while (!m_connections.empty())
155             RemoveConnection(m_connections.front());
156
157         // Close RPC server
158         m_rpcServer.CloseAll();
159
160         // Detach RPC server listener
161         m_rpcServer.DPL::EventSupport<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::RemoveListener(this);
162     }
163 };
164
165 int main(int argc, char *argv[])
166 {
167     return MetronomeServerApplication(argc, argv).Exec();
168 }