2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @file generic_socket_rpc_server.h
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20 * @brief This file is the header file for generic socket RPC server
22 #ifndef DPL_GENERIC_SOCKET_RPC_SERVER_H
23 #define DPL_GENERIC_SOCKET_RPC_SERVER_H
25 #include <dpl/rpc/abstract_rpc_connector.h>
26 #include <dpl/socket/abstract_socket.h>
31 template<typename SocketType>
32 class GenericSocketRPCServer :
33 public AbstractRPCConnector,
34 private DPL::Event::EventListener<DPL::Socket::AbstractSocketEvents::
41 DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
42 DECLARE_EXCEPTION_TYPE(Base, OpenFailed)
43 DECLARE_EXCEPTION_TYPE(Base, CloseFailed)
47 // Derived class implementations for connection managment
48 virtual AbstractRPCConnection *OpenSpecificConnection(SocketType *socket) =
52 typedef std::set<SocketType *> InternalInterfaceSet;
53 InternalInterfaceSet m_internalInterfacesSet;
55 virtual void OnEventReceived(
56 const DPL::Socket::AbstractSocketEvents::AcceptEvent &event)
58 // Retrieve socket sender
59 SocketType *server = static_cast<SocketType *>(event.GetSender());
61 // Is this interface still tracked ?
62 // It might have disappeared on close
63 typename InternalInterfaceSet::iterator iterator =
64 m_internalInterfacesSet.find(server);
66 if (iterator == m_internalInterfacesSet.end()) {
67 LogPedantic("RPC server interface socket disappeared");
71 // Accept incoming client
72 SocketType *client = static_cast<SocketType *>(server->Accept());
74 LogPedantic("Spontaneous accept on socket occurred");
79 "Client connected to server: " <<
80 client->GetRemoteAddress().ToString());
82 // Open specific connection implementation
83 AbstractRPCConnection *connection = OpenSpecificConnection(client);
85 // Retrieve ID once again
86 AbstractRPCConnectionID connectionID =
87 static_cast<AbstractRPCConnectionID>(server);
90 DPL::Event::EventSupport<AbstractRPCConnectorEvents::
91 ConnectionEstablishedEvent>::
92 EmitEvent(AbstractRPCConnectorEvents::ConnectionEstablishedEvent(
93 connectionID, connection, EventSender(
94 this)), DPL::Event::EmitMode::Queued);
98 explicit GenericSocketRPCServer()
101 virtual ~GenericSocketRPCServer()
103 // Always close connection
107 AbstractRPCConnectionID Open(const Address &socketAddress)
109 LogPedantic("Starting server: " << socketAddress.ToString());
112 SocketType *socket = new SocketType();
114 // Add socket listener
115 socket->EventSupport<DPL::Socket::AbstractSocketEvents::AcceptEvent>::
123 // Bind socket address
124 socket->Bind(socketAddress);
129 Catch(DPL::Socket::AbstractSocket::Exception::Base)
131 // Remove back socket listener
132 socket->EventSupport<DPL::Socket::AbstractSocketEvents::AcceptEvent>
133 ::RemoveListener(this);
136 LogPedantic("Cannot start server: " << socketAddress.ToString());
138 // Problem with server startup
139 ReThrowMsg(typename Exception::OpenFailed, socketAddress.ToString());
142 // Register new internal connection
143 m_internalInterfacesSet.insert(socket);
147 "Server started on interface: " <<
148 socket->GetLocalAddress().ToString());
150 // Return unique identifier
151 return static_cast<AbstractRPCConnectionID>(socket);
154 void Close(AbstractRPCConnectionID connectionID)
156 LogPedantic("Closing server interface...");
158 // Get socket from ID
159 SocketType *socket = static_cast<SocketType *>(connectionID);
161 // Find corresponding internal connection
162 typename InternalInterfaceSet::iterator iterator =
163 m_internalInterfacesSet.find(socket);
165 if (iterator == m_internalInterfacesSet.end()) {
172 // Remove socket listeners
173 socket->EventSupport<DPL::Socket::AbstractSocketEvents::AcceptEvent>::
174 RemoveListener(this);
177 m_internalInterfacesSet.erase(iterator);
180 LogPedantic("Closed");
185 while (!m_internalInterfacesSet.empty()) {
186 Close(static_cast<AbstractRPCConnectionID>(*m_internalInterfacesSet
194 #endif // DPL_GENERIC_SOCKET_RPC_SERVER_H