7efa4589b249fbb3dc7b930aceb6f45d30bc710d
[platform/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 <dpl/tcp_socket_rpc_server.h>
23 #include <dpl/tcp_socket_rpc_connection.h>
24 #include <dpl/controller.h>
25 #include <dpl/application.h>
26 #include <dpl/type_list.h>
27 #include <dpl/log/log.h>
28 #include <algorithm>
29 #include <list>
30 #include <dpl/assert.h>
31
32 // Metronome signal event
33 DECLARE_GENERIC_EVENT_0(SignalEvent)
34 DECLARE_GENERIC_EVENT_1(DeleteConnectionEvent, DPL::AbstractRPCConnection *)
35
36 // Heart beat interval
37 const double HEART_BEAT_INTERVAL = 1.0; // seconds
38
39 class MetronomeServerApplication
40     : public DPL::Application,
41       private DPL::Controller<DPL::TypeListDecl<SignalEvent,
42                                                 DeleteConnectionEvent>::Type>,
43       private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>,
44       private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>,
45       private DPL::EventListener<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>
46 {
47 private:
48     DPL::TcpSocketRPCServer m_rpcServer;
49
50     typedef std::list<DPL::AbstractRPCConnection *> ConnectionList;
51     ConnectionList m_connections;
52
53     // Matronome signal received
54     virtual void OnEventReceived(const SignalEvent &event)
55     {
56         (void)event;
57
58         // Signal all conection about heart beat
59         DPL::RPCFunction proc;
60         proc.AppendArg((int)0);
61
62         for (ConnectionList::iterator it = m_connections.begin(); it != m_connections.end(); ++it)
63             (*it)->AsyncCall(proc);
64
65         // Continue to emot heart beats
66         DPL::ControllerEventHandler<SignalEvent>::PostTimedEvent(SignalEvent(), HEART_BEAT_INTERVAL);
67     }
68
69     virtual void OnEventReceived(const DeleteConnectionEvent &event)
70     {
71         delete event.GetArg0();
72     }
73
74     void RemoveConnection(DPL::AbstractRPCConnection *connection)
75     {
76         // Find connection
77         ConnectionList::iterator it = std::find(m_connections.begin(), m_connections.end(), connection);
78         Assert(it != m_connections.end());
79
80         // Erase connection
81         m_connections.erase(it);
82
83         // Detach RPC connection listeners
84         connection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::RemoveListener(this);
85         connection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::RemoveListener(this);
86
87         // Delete connection
88         DPL::ControllerEventHandler<DeleteConnectionEvent>::PostEvent(DeleteConnectionEvent(connection));
89     }
90
91     void AddConnection(DPL::AbstractRPCConnection *connection)
92     {
93         // Add connection
94         m_connections.push_back(connection);
95
96         // Attach event listeners
97         connection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::AddListener(this);
98         connection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::AddListener(this);
99     }
100
101     virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent &event)
102     {
103         (void)event;
104
105         LogInfo("Connection closed");
106
107         // Remove connection from list
108         RemoveConnection(static_cast<DPL::AbstractRPCConnection *>(event.GetSender()));
109     }
110
111     virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event)
112     {
113         (void)event;
114
115         LogInfo("Connection broken");
116
117         // Remove connection from list
118         RemoveConnection(static_cast<DPL::AbstractRPCConnection *>(event.GetSender()));
119     }
120
121     virtual void OnEventReceived(const DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent &event)
122     {
123         // Save connection pointer
124         LogInfo("New connection");
125
126         // Add nre connection to list
127         AddConnection(event.GetArg1());
128     }
129
130 public:
131     MetronomeServerApplication(int argc, char **argv)
132         : Application(argc, argv, "rpc")
133     {
134         // Attach RPC server listeners
135         m_rpcServer.DPL::EventSupport<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::AddListener(this);
136
137         // Inherit calling context
138         Touch();
139
140         // Open RPC server
141         m_rpcServer.Open(12345);
142
143         // Start heart beat
144         DPL::ControllerEventHandler<SignalEvent>::PostTimedEvent(SignalEvent(), HEART_BEAT_INTERVAL);
145
146         // Started
147         LogInfo("Metronome server started");
148      }
149
150     virtual ~MetronomeServerApplication()
151     {
152         // Delete all RPC connections
153         while (!m_connections.empty())
154             RemoveConnection(m_connections.front());
155
156         // Close RPC server
157         m_rpcServer.CloseAll();
158
159         // Detach RPC server listener
160         m_rpcServer.DPL::EventSupport<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::RemoveListener(this);
161     }
162 };
163
164 int main(int argc, char *argv[])
165 {
166     return MetronomeServerApplication(argc, argv).Exec();
167 }