|
|
-
- #include <MWSessionI.h>
- #include <MWUtils.h>
-
- using namespace std;
-
- class SessionCallbackAdapter : public MWMapCallbackAdapter,
- public enable_shared_from_this<SessionCallbackAdapter>
- {
- public:
-
- SessionCallbackAdapter(const shared_ptr<MW::MWRoomCallbackPrx>& callback,
- const shared_ptr<MW::MWSessionPrx>& session,
- bool trace, const shared_ptr<Ice::Logger>& logger, const std::string& name) :
- _callback(callback),
- _session(session),
- _trace(trace),
- _logger(logger),
- _name(name)
- {
- }
-
- void init(Ice::StringSeq users) override
- {
- auto self = shared_from_this();
- try
- {
- _callback->initAsync(users, nullptr, [self](std::exception_ptr eptr) { self->failed(eptr); });
- }
- catch(const Ice::CommunicatorDestroyedException&)
- {
- // Ignored server is being shutdown
- }
- }
-
- void join(const shared_ptr<MW::UserJoinedEvent>& e) override
- {
- auto self = shared_from_this();
- try
- {
- _callback->joinAsync(e->timestamp, e->name, nullptr, [self](exception_ptr eptr) { self->failed(eptr); });
- }
- catch(const Ice::CommunicatorDestroyedException&)
- {
- // Ignored server is being shutdown
- }
- }
-
- void leave(const shared_ptr<MW::UserLeftEvent>& e) override
- {
- auto self = shared_from_this();
- try
- {
- _callback->leaveAsync(e->timestamp, e->name, nullptr, [self](exception_ptr eptr) { self->failed(eptr); });
- }
- catch(const Ice::CommunicatorDestroyedException&)
- {
- // Ignored server is being shutdown
- }
- }
-
- void send(const shared_ptr<MW::MessageEvent>& e) override
- {
- auto self = shared_from_this();
- try
- {
- _callback->sendAsync(e->timestamp, e->name, e->message, nullptr, [self](exception_ptr eptr) { self->failed(eptr); });
- }
- catch(const Ice::CommunicatorDestroyedException&)
- {
- // Ignored server is being shutdown
- }
- }
-
- void failed(exception_ptr)
- {
- if(_trace)
- {
- Ice::Trace out(_logger, "info");
- out << "Error sending request to user '" << _name << "'. The user's session will be destroyed.";
- }
- try
- {
- _session->ice_endpoints(Ice::EndpointSeq())->destroy(); // Collocated call.
- }
- catch(const Ice::LocalException&)
- {
- }
- }
-
- private:
-
- const shared_ptr<MW::MWMapCallbackPrx> _callback;
- const shared_ptr<MW::MWSessionPrx> _session;
- const bool _trace;
- const shared_ptr<Ice::Logger> _logger;
- const string _name;
- };
-
- MWSessionI::MWSessionI(const shared_ptr<MWMap>& MWMap, const string& name, bool trace, const shared_ptr<Ice::Logger>& logger) :
- _MWMap(MWMap),
- _name(name),
- _trace(trace),
- _logger(logger)
- {
- }
-
- void
- MWSessionI::setCallback(shared_ptr<MW::MWMapCallbackPrx> callback, const Ice::Current& current)
- {
- lock_guard<mutex> sync(_mutex);
- if(_destroy)
- {
- if(_trace)
- {
- Ice::Trace out(_logger, "info");
- out << "User '" << _name << "' tried to set the session callback but the session is already destroyed.";
- }
- throw Ice::ObjectNotExistException(__FILE__, __LINE__);
- }
-
- if(_callback || !callback)
- {
- return;
- }
-
- Ice::Context ctx;
- ctx["_fwd"] = "o";
- _callback = make_shared<SessionCallbackAdapter>(
- callback->ice_context(ctx),
- Ice::uncheckedCast<MW::MWSessionPrx>(current.adapter->createProxy(current.id)),
- _trace, _logger, _name);
- _MWRoom->join(_name, _callback);
- }
-
- long long
- MWSessionI::send(string message, const Ice::Current&)
- {
- lock_guard<mutex> sync(_mutex);
- if(_destroy)
- {
- if(_trace)
- {
- Ice::Trace out(_logger, "info");
- out << "User '" << _name << "' tried to send a message but the session is already destroyed.";
- }
- throw Ice::ObjectNotExistException(__FILE__, __LINE__);
- }
- if(!_callback)
- {
- if(_trace)
- {
- Ice::Trace out(_logger, "info");
- out << "User '" << _name << "' tried to send a message without setting the callback.";
- }
- throw MW::InvalidMessageException("You cannot send messages until you join the MW Map.");
- }
- string msg;
- try
- {
- msg = validateMessage(message);
- }
- catch(const exception& ex)
- {
- if(_trace)
- {
- Ice::Trace out(_logger, "info");
- out << "User '" << _name << "' sent an invalid message:\n" << ex;
- }
- throw MW::InvalidMessageException(ex.what());
- }
- return _MWMap->send(_name, move(msg));
- }
-
- void
- MWSessionI::destroy(const Ice::Current& current)
- {
- lock_guard<mutex> sync(_mutex);
- if(_destroy)
- {
- if(_trace)
- {
- Ice::Trace out(_logger, "info");
- out << "Trying to destroy the session for user '" << _name << "' but the session is already destroyed.";
- }
- throw Ice::ObjectNotExistException(__FILE__, __LINE__);
- }
- try
- {
- current.adapter->remove(current.id);
- if(_callback)
- {
- _MWMap->leave(_name);
- }
- else
- {
- _MWMap->unreserve(_name);
- }
- }
- catch(const Ice::ObjectAdapterDeactivatedException&)
- {
- // No need to clean up, the server is shutting down.
- }
- if(_trace)
- {
- Ice::Trace out(_logger, "info");
- out << "Push session for user '" << _name << "' destroyed.";
- }
- _destroy = true;
- }
|