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>
34 template<typename SocketType>
35 class GenericSocketRPCServer
36 : public AbstractRPCConnector,
37 private DPL::Event::EventListener<DPL::Socket::AbstractSocketEvents::AcceptEvent>
43 DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
44 DECLARE_EXCEPTION_TYPE(Base, OpenFailed)
45 DECLARE_EXCEPTION_TYPE(Base, CloseFailed)
49 // Derived class implementations for connection managment
50 virtual AbstractRPCConnection *OpenSpecificConnection(SocketType *socket) = 0;
53 typedef std::set<SocketType *> InternalInterfaceSet;
54 InternalInterfaceSet m_internalInterfacesSet;
56 virtual void OnEventReceived(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 = m_internalInterfacesSet.find(server);
65 if (iterator == m_internalInterfacesSet.end())
67 LogPedantic("RPC server interface socket disappeared");
71 // Accept incoming client
72 SocketType *client = static_cast<SocketType *>(server->Accept());
75 LogPedantic("Spontaneous accept on socket occurred");
79 LogPedantic("Client connected to server: " << client->GetRemoteAddress().ToString());
81 // Open specific connection implementation
82 AbstractRPCConnection *connection = OpenSpecificConnection(client);
84 // Retrieve ID once again
85 AbstractRPCConnectionID connectionID = static_cast<AbstractRPCConnectionID>(server);
88 DPL::Event::EventSupport<AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::
89 EmitEvent(AbstractRPCConnectorEvents::ConnectionEstablishedEvent(
90 connectionID, connection, EventSender(this)), DPL::Event::EmitMode::Queued);
94 explicit GenericSocketRPCServer()
98 virtual ~GenericSocketRPCServer()
100 // Always close connection
104 AbstractRPCConnectionID Open(const Address &socketAddress)
106 LogPedantic("Starting server: " << socketAddress.ToString());
109 SocketType *socket = new SocketType();
111 // Add socket listener
112 socket->EventSupport<DPL::Socket::AbstractSocketEvents::AcceptEvent>::AddListener(this);
119 // Bind socket address
120 socket->Bind(socketAddress);
125 Catch (DPL::Socket::AbstractSocket::Exception::Base)
127 // Remove back socket listener
128 socket->EventSupport<DPL::Socket::AbstractSocketEvents::AcceptEvent>::RemoveListener(this);
131 LogPedantic("Cannot start server: " << socketAddress.ToString());
133 // Problem with server startup
134 ReThrowMsg(typename Exception::OpenFailed, socketAddress.ToString());
137 // Register new internal connection
138 m_internalInterfacesSet.insert(socket);
141 LogPedantic("Server started on interface: " << socket->GetLocalAddress().ToString());
143 // Return unique identifier
144 return static_cast<AbstractRPCConnectionID>(socket);
147 void Close(AbstractRPCConnectionID connectionID)
149 LogPedantic("Closing server interface...");
151 // Get socket from ID
152 SocketType *socket = static_cast<SocketType *>(connectionID);
154 // Find corresponding internal connection
155 typename InternalInterfaceSet::iterator iterator = m_internalInterfacesSet.find(socket);
157 if (iterator == m_internalInterfacesSet.end())
163 // Remove socket listeners
164 socket->EventSupport<DPL::Socket::AbstractSocketEvents::AcceptEvent>::RemoveListener(this);
167 m_internalInterfacesSet.erase(iterator);
170 LogPedantic("Closed");
175 while (!m_internalInterfacesSet.empty())
176 Close(static_cast<AbstractRPCConnectionID>(*m_internalInterfacesSet.begin()));
183 #endif // DPL_GENERIC_SOCKET_RPC_SERVER_H