wsd: ClientSession becomes SocketHandler for WS sockets
Change-Id: I02706ccac186e4934b8ccdab5cdebdba7170fd46
This commit is contained in:
parent
fa1dc4e051
commit
6c8f3633de
3 changed files with 77 additions and 89 deletions
|
@ -678,4 +678,64 @@ bool ClientSession::forwardToClient(const std::shared_ptr<Message>& payload)
|
|||
return true;
|
||||
}
|
||||
|
||||
void ClientSession::onDisconnect()
|
||||
{
|
||||
LOG_INF(getName() << " Disconnected.");
|
||||
|
||||
const auto docBroker = getDocumentBroker();
|
||||
LOG_CHECK_RET(docBroker && "Null DocumentBroker instance", );
|
||||
const auto docKey = docBroker->getDocKey();
|
||||
|
||||
try
|
||||
{
|
||||
// Connection terminated. Destroy session.
|
||||
LOG_DBG(getName() << " on docKey [" << docKey << "] terminated. Cleaning up.");
|
||||
|
||||
// We issue a force-save when last editable (non-readonly) session is going away
|
||||
// and defer destroying the last session and the docBroker.
|
||||
docBroker->removeSession(getId(), true);
|
||||
}
|
||||
catch (const UnauthorizedRequestException& exc)
|
||||
{
|
||||
LOG_ERR("Error in client request handler: " << exc.toString());
|
||||
const std::string status = "error: cmd=internal kind=unauthorized";
|
||||
LOG_TRC("Sending to Client [" << status << "].");
|
||||
sendFrame(status);
|
||||
}
|
||||
catch (const std::exception& exc)
|
||||
{
|
||||
LOG_ERR("Error in client request handler: " << exc.what());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (isCloseFrame())
|
||||
{
|
||||
LOG_TRC("Normal close handshake.");
|
||||
// Client initiated close handshake
|
||||
// respond with close frame
|
||||
shutdown();
|
||||
}
|
||||
else if (!ShutdownRequestFlag)
|
||||
{
|
||||
// something wrong, with internal exceptions
|
||||
LOG_TRC("Abnormal close handshake.");
|
||||
closeFrame();
|
||||
shutdown(WebSocketHandler::StatusCodes::ENDPOINT_GOING_AWAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0 // loolnb
|
||||
std::lock_guard<std::mutex> lock(ClientWebSocketsMutex);
|
||||
LOG_TRC("Capturing Client WS for [" << _id << "]");
|
||||
// ClientWebSockets.push_back(ws); //FIXME
|
||||
#endif
|
||||
}
|
||||
}
|
||||
catch (const std::exception& exc)
|
||||
{
|
||||
LOG_WRN(getName() << ": Exception while closing socket for docKey [" << docKey << "]: " << exc.what());
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -112,10 +112,15 @@ public:
|
|||
/// Set WOPI fileinfo object
|
||||
void setWopiFileInfo(std::unique_ptr<WopiStorage::WOPIFileInfo>& wopiFileInfo) { _wopiFileInfo = std::move(wopiFileInfo); }
|
||||
|
||||
private:
|
||||
|
||||
/// SocketHandler: disconnection event.
|
||||
void onDisconnect() override;
|
||||
/// SocketHandler: have data to write.
|
||||
bool hasQueuedWrites() const override;
|
||||
/// SocketHandler: write to socket.
|
||||
void performWrites() override;
|
||||
|
||||
private:
|
||||
virtual bool _handleInput(const char* buffer, int length) override;
|
||||
|
||||
bool loadDocument(const char* buffer, int length, const std::vector<std::string>& tokens,
|
||||
|
|
|
@ -1638,9 +1638,8 @@ private:
|
|||
|
||||
void onDisconnect() override
|
||||
{
|
||||
if (_clientSession)
|
||||
disposeSession();
|
||||
|
||||
// FIXME: Move to ClientSession (ideally, wrap in ConnectionCounter object
|
||||
// to wrap this global NumConnections).
|
||||
const size_t curConnections = --LOOLWSD::NumConnections;
|
||||
LOG_TRC("Disconnected connection #" << _connectionNum << " (of " <<
|
||||
(curConnections + 1) << ") as session [" << _id << "].");
|
||||
|
@ -1649,16 +1648,6 @@ private:
|
|||
/// Called after successful socket reads.
|
||||
void handleIncomingMessage() override
|
||||
{
|
||||
if (_clientSession)
|
||||
{
|
||||
LOG_INF("Forwarding incoming message to client [" << _id << "]");
|
||||
|
||||
// TODO: might be better to reset the handler in the socket
|
||||
// so we avoid this double-dispatching.
|
||||
_clientSession->handleIncomingMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
auto socket = _socket.lock();
|
||||
std::vector<char>& in = socket->_inBuffer;
|
||||
|
||||
|
@ -1788,19 +1777,12 @@ private:
|
|||
|
||||
bool hasQueuedWrites() const override
|
||||
{
|
||||
// FIXME: - the session should be owning the fd in DocumentBroker's _poll
|
||||
if (_clientSession)
|
||||
return _clientSession->hasQueuedWrites();
|
||||
|
||||
LOG_TRC("ClientRequestDispatcher - asked for queued writes");
|
||||
return false;
|
||||
}
|
||||
|
||||
void performWrites() override
|
||||
{
|
||||
// FIXME: - the session should be owning the fd in DocumentBroker's _poll
|
||||
if (_clientSession)
|
||||
return _clientSession->performWrites();
|
||||
}
|
||||
|
||||
void handleFileServerRequest(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message)
|
||||
|
@ -2211,91 +2193,32 @@ private:
|
|||
if (docBroker)
|
||||
{
|
||||
// TODO: Move to DocumentBroker.
|
||||
_clientSession = createNewClientSession(ws, _id, uriPublic, docBroker, isReadOnly);
|
||||
if (_clientSession)
|
||||
auto clientSession = createNewClientSession(ws, _id, uriPublic, docBroker, isReadOnly);
|
||||
if (clientSession)
|
||||
{
|
||||
// Transfer the client socket to the DocumentBroker.
|
||||
auto socket = _socket.lock();
|
||||
if (socket)
|
||||
{
|
||||
// Move the socket into DocBroker.
|
||||
WebServerPoll.releaseSocket(socket);
|
||||
_clientSession->onConnect(socket);
|
||||
docBroker->addSocketToPoll(socket);
|
||||
|
||||
// Set the ClientSession to handle Socket events.
|
||||
socket->setHandler(clientSession);
|
||||
}
|
||||
docBroker->startThread();
|
||||
}
|
||||
}
|
||||
if (!docBroker || !_clientSession)
|
||||
LOG_WRN("Failed to connect DocBroker and Client Session.");
|
||||
}
|
||||
|
||||
// this session went away - cleanup now.
|
||||
void disposeSession()
|
||||
{
|
||||
LOG_CHECK_RET(_clientSession && "Null ClientSession instance", );
|
||||
const auto docBroker = _clientSession->getDocumentBroker();
|
||||
LOG_CHECK_RET(docBroker && "Null DocumentBroker instance", );
|
||||
const auto docKey = docBroker->getDocKey();
|
||||
|
||||
try
|
||||
{
|
||||
// Connection terminated. Destroy session.
|
||||
LOG_DBG("Client session [" << _id << "] on docKey [" << docKey << "] terminated. Cleaning up.");
|
||||
|
||||
// We issue a force-save when last editable (non-readonly) session is going away
|
||||
// and defer destroying the last session and the docBroker.
|
||||
docBroker->removeSession(_id, true);
|
||||
|
||||
LOG_INF("Finishing GET request handler for session [" << _id << "].");
|
||||
}
|
||||
catch (const UnauthorizedRequestException& exc)
|
||||
{
|
||||
LOG_ERR("Error in client request handler: " << exc.toString());
|
||||
const std::string status = "error: cmd=internal kind=unauthorized";
|
||||
LOG_TRC("Sending to Client [" << status << "].");
|
||||
_clientSession->sendFrame(status);
|
||||
}
|
||||
catch (const std::exception& exc)
|
||||
{
|
||||
LOG_ERR("Error in client request handler: " << exc.what());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (_clientSession->isCloseFrame())
|
||||
{
|
||||
LOG_TRC("Normal close handshake.");
|
||||
// Client initiated close handshake
|
||||
// respond with close frame
|
||||
_clientSession->shutdown();
|
||||
}
|
||||
else if (!ShutdownRequestFlag)
|
||||
{
|
||||
// something wrong, with internal exceptions
|
||||
LOG_TRC("Abnormal close handshake.");
|
||||
_clientSession->closeFrame();
|
||||
_clientSession->shutdown(WebSocketHandler::StatusCodes::ENDPOINT_GOING_AWAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0 // loolnb
|
||||
std::lock_guard<std::mutex> lock(ClientWebSocketsMutex);
|
||||
LOG_TRC("Capturing Client WS for [" << _id << "]");
|
||||
// ClientWebSockets.push_back(ws); //FIXME
|
||||
#endif
|
||||
}
|
||||
}
|
||||
catch (const std::exception& exc)
|
||||
{
|
||||
LOG_WRN("Exception while closing socket for session [" << _id <<
|
||||
"] of docKey [" << docKey << "]: " << exc.what());
|
||||
LOG_WRN("Failed to create Client Session with id [" << _id << "] on docKey [" << docKey << "].");
|
||||
}
|
||||
else
|
||||
LOG_WRN("Failed to create DocBroker with docKey [" << docKey << "].");
|
||||
}
|
||||
|
||||
private:
|
||||
// The socket that owns us (we can't own it).
|
||||
std::weak_ptr<StreamSocket> _socket;
|
||||
std::shared_ptr<ClientSession> _clientSession;
|
||||
std::string _id;
|
||||
size_t _connectionNum;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue