2#include "cajun/json/writer.h"
14#define RESIPROCATE_SUBSYSTEM kurento::KurentoSubsystem::KURENTOCLIENT
23 : mObserver(observer),
27 mRetryInterval(retryInterval),
28 mWaitForResponse(waitForResponse)
41 InfoLog(<<
"trying to open connection to Kurento");
42 websocketpp::lib::error_code ec;
43 client::connection_ptr con = mWSClient.get_connection(mUri, ec);
45 ErrLog(<<
"could not create connection because: " << ec.message());
49 mHandle = con->get_handle();
51 con->set_open_handler(websocketpp::lib::bind(
55 websocketpp::lib::placeholders::_1
57 con->set_fail_handler(websocketpp::lib::bind(
61 websocketpp::lib::placeholders::_1
63 con->set_close_handler(websocketpp::lib::bind(
67 websocketpp::lib::placeholders::_1
69 con->set_message_handler(websocketpp::lib::bind(
73 websocketpp::lib::placeholders::_1,
74 websocketpp::lib::placeholders::_2
77 mWSClient.connect(con);
92 ErrLog(<<
"connection attempt failed, will retry after " << mRetryInterval.count() <<
" ms");
93 wSClient->set_timer(mRetryInterval.count(), [
this](websocketpp::lib::error_code ec){onRetryRequired();});
104 ErrLog(<<
"connection closed unexpectedly, will try to reopen it");
105 wSClient->set_timer(mRetryInterval.count(), [
this](websocketpp::lib::error_code ec){onRetryRequired();});
111 if (msg->get_opcode() != websocketpp::frame::opcode::text)
113 ErrLog(<<
"received unknown message type, ignoring it");
117 const std::string& m = msg->get_payload();
118 DebugLog(<<
"received a message: " << m.c_str());
120 json::Object message;
121 std::stringstream stream;
125 json::Reader::Read(message, stream);
127 catch (json::Reader::ParseException& e)
130 DebugLog(<<
"Caught json::ParseException: " << e.what() <<
", Line/offset: " << e.m_locTokenBegin.m_nLine + 1
131 <<
'/' << e.m_locTokenBegin.m_nLineOffset + 1);
136 if(mSessionId.length() == 0)
144 mSessionId = sessionId.Value();
145 DebugLog(<<
"registered new sessionId: " << mSessionId);
152 const json::String& idValue = message[
JSON_RPC_ID];
153 std::string
id = idValue.Value();
154 DebugLog(<<
"has id = '" <<
id <<
"', response");
156 const KurentoResponseHandlerMap::const_iterator it = mResponseHandlers.find(
id);
158 if(it != mResponseHandlers.end())
160 onResponse(
id, it->second, message);
164 WarningLog(<<
"unrecognised id = '" <<
id <<
"'");
170 DebugLog(<<
"has no id, checking if it is a notification");
174 const std::string& _eventName = eventName.Value();
175 DebugLog(<<
"received an event: " << _eventName);
177 onEvent(_eventName, message);
181 DebugLog(<<
"don't know how to handle the message: " << m);
189KurentoConnection::onResponse(
const std::string&
id, std::shared_ptr<KurentoResponseHandler> krh,
const json::Object& message)
192 unsigned long _id = std::stol(
id);
193 mResponseHandlers.erase(
id);
194 krh->processResponse(
id, krh, message);
195 if(_id > mLastResponse)
201 WarningLog(<<
"mLastResponse = " << mLastResponse <<
" but received response for earlier request: " << _id);
203 mResponseReceivedCount++;
204 DebugLog(<<
"mRequestSentCount = " << mRequestSentCount
205 <<
" mResponseReceivedCount = " << mResponseReceivedCount);
210KurentoConnection::onEvent(
const std::string& eventName,
const json::Object& message)
216 const json::String& objectId = values[
"object"];
217 const std::string& _objectId = objectId.Value();
219 if(mObjects.find(_objectId) != mObjects.end())
221 std::shared_ptr<Object>
object = mObjects[_objectId];
222 DebugLog(<<
"event is being routed to Object " << _objectId);
223 object->onEvent(eventName, message);
227 WarningLog(<<
"event is for unknown Object " << _objectId);
234KurentoConnection::sendMessage(
const std::string& msg)
236 mSendQueue.push_back(msg);
237 DebugLog(<<
"mRequestSentCount = " << mRequestSentCount
238 <<
" mResponseReceivedCount = " << mResponseReceivedCount);
243KurentoConnection::processSendQueue()
245 while(!mSendQueue.empty())
247 if(mWaitForResponse && mRequestSentCount > mResponseReceivedCount)
249 DebugLog(<<
"new request to send but still waiting for response for a previous request");
252 if(mWSClient.get_con_from_hdl(mHandle)->get_state() == websocketpp::session::state::value::open)
254 std::string& msg = mSendQueue.front();
255 websocketpp::lib::error_code ec;
256 mWSClient.send(mHandle, msg.c_str(), websocketpp::frame::opcode::text, ec);
259 ErrLog(<<
"failed to send a message to Kurento");
264 StackLog(<<
"message sent to Kurento, removing from queue: " << msg);
265 mSendQueue.pop_front();
271 ErrLog(<<
"connection to Kurento is not in the open state, message has been queued");
280 const std::string
id = std::to_string(mNextId++);
282 json::Object request;
283 json::Object _params =
params;
284 if(mSessionId.length() > 0)
294 std::stringstream stream;
295 json::Writer::Write(request, stream);
297 mResponseHandlers[id] = krh;
298 StackLog(<<
"added ResponseHandler for id '" <<
id <<
"', handler count: " << mResponseHandlers.size());
300 sendMessage(stream.str());
308 std::shared_ptr<Object> _object = std::static_pointer_cast<Object>(
object);
309 mObjects[_object->getId()] = _object;
316 mObjects.erase(objectId);
#define JSON_RPC_PROTO_VERSION
#define JSON_RPC_SESSION_ID
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
virtual void onConnected()=0
virtual ~KurentoConnectionObserver()
void registerObject(std::shared_ptr< KurentoResponseHandler > object)
virtual ~KurentoConnection()
void onMessage(client *wSClient, websocketpp::connection_hdl, client::message_ptr msg)
void unregisterObject(const std::string &objectId)
KurentoConnection(KurentoConnectionObserver &observer, std::string uri, client &wSClient, std::chrono::milliseconds timeout, std::chrono::milliseconds retryInterval, bool waitForResponse=true)
void onOpen(client *wSClient, websocketpp::connection_hdl h)
void onFail(client *wSClient, websocketpp::connection_hdl h)
std::string sendRequest(std::shared_ptr< KurentoResponseHandler > krh, const std::string &method, const json::Object ¶ms)
void onClose(client *wSClient, websocketpp::connection_hdl h)
This class is used in the logging subsystem to identify logging messages generated from the Kurento c...
websocketpp::client< websocketpp::config::asio_client > client
dcm! – add UnusedChecking(_enum) below;