mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-02 06:06:10 -04:00
Improve async distant chat, fix chat msg receiving
DistantChatService::initiateDistantChatConnexion(...) made notification message optional (enabled by default) p3ChatService removed duplicion avoidance as it is not necessary p3ChatService::sendStatusString(...) send status only if peer is online protect p3ChatService::mDistantGxsMap with mutex as operation on it may be done by different threads p3ChatService::receiveGxsMai(...) set chat message item peer id with distant tunnel id, so it is recognized as a distant message later made p3GxsTunnelService::makeGxsTunnelId(...) static as it need no access to this, now it can be used easier by other components rename RsGxsMailItem::recipientsHint to recipientHint as for now only one recipient is possible (TODO: update documentation too) GxsMailsClient::receiveGxsMail(...) changed paramethers for better abstracion, now destination id is passed too because it is usually a very useful information ChatWidget some adaptation to async chat, a couple of method have been deprecated too PopupDistantChatDialog::updateDisplay(...) adapt message shown to the user to the new async chat paradigm (TODO: need review)
This commit is contained in:
parent
0f1106fd8f
commit
953b70fbe4
14 changed files with 212 additions and 212 deletions
|
@ -243,7 +243,9 @@ void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid)
|
|||
mDistantChatContacts.erase(it) ;
|
||||
}
|
||||
|
||||
bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, DistantChatPeerId& dcpid, uint32_t& error_code)
|
||||
bool DistantChatService::initiateDistantChatConnexion(
|
||||
const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id,
|
||||
DistantChatPeerId& dcpid, uint32_t& error_code, bool notify )
|
||||
{
|
||||
RsGxsTunnelId tunnel_id ;
|
||||
|
||||
|
@ -259,17 +261,19 @@ bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& to_gxs_id,
|
|||
|
||||
error_code = RS_DISTANT_CHAT_ERROR_NO_ERROR ;
|
||||
|
||||
// Make a self message to raise the chat window
|
||||
|
||||
RsChatMsgItem *item = new RsChatMsgItem;
|
||||
item->message = "[Starting distant chat. Please wait for secure tunnel to be established]" ;
|
||||
item->chatFlags = RS_CHAT_FLAG_PRIVATE ;
|
||||
item->sendTime = time(NULL) ;
|
||||
item->PeerId(RsPeerId(tunnel_id)) ;
|
||||
handleRecvChatMsgItem(item) ;
|
||||
|
||||
delete item ; // item is replaced by NULL if partial, but this is not the case here.
|
||||
|
||||
if(notify)
|
||||
{
|
||||
// Make a self message to raise the chat window
|
||||
RsChatMsgItem *item = new RsChatMsgItem;
|
||||
item->message = "[Starting distant chat. Please wait for secure tunnel";
|
||||
item->message += " to be established]";
|
||||
item->chatFlags = RS_CHAT_FLAG_PRIVATE;
|
||||
item->sendTime = time(NULL);
|
||||
item->PeerId(RsPeerId(tunnel_id));
|
||||
handleRecvChatMsgItem(item);
|
||||
delete item ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,10 +45,15 @@ public:
|
|||
bool processLoadListItem(const RsItem *item) ;
|
||||
void addToSaveList(std::list<RsItem*>& list) const;
|
||||
|
||||
// Creates the invite if the public key of the distant peer is available.
|
||||
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
|
||||
//
|
||||
bool initiateDistantChatConnexion(const RsGxsId& to_gxs_id, const RsGxsId &from_gxs_id, DistantChatPeerId& dcpid, uint32_t &error_code) ;
|
||||
/**
|
||||
* Creates the invite if the public key of the distant peer is available.
|
||||
* On success, stores the invite in the map above, so that we can respond
|
||||
* to tunnel requests. */
|
||||
bool initiateDistantChatConnexion( const RsGxsId& to_gxs_id,
|
||||
const RsGxsId &from_gxs_id,
|
||||
DistantChatPeerId& dcpid,
|
||||
uint32_t &error_code,
|
||||
bool notify = true );
|
||||
bool closeDistantChatConnexion(const DistantChatPeerId &tunnel_id) ;
|
||||
|
||||
// Sets flags to only allow connexion from some people.
|
||||
|
|
|
@ -59,8 +59,9 @@ p3ChatService::p3ChatService( p3ServiceControl *sc, p3IdService *pids,
|
|||
DistributedChatService(getServiceInfo().mServiceType, sc, historyMgr,pids),
|
||||
mChatMtx("p3ChatService"), mServiceCtrl(sc), mLinkMgr(lm),
|
||||
mHistoryMgr(historyMgr), _own_avatar(NULL),
|
||||
_serializer(new RsChatSerialiser()), mGxsTransport(gxsMailService),
|
||||
recentlyReceivedMutex("p3ChatService recently received mutex")
|
||||
_serializer(new RsChatSerialiser()),
|
||||
mDGMutex("p3ChatService distant id - gxs id map mutex"),
|
||||
mGxsTransport(gxsMailService)
|
||||
{
|
||||
addSerialType(_serializer);
|
||||
mGxsTransport.registerGxsMailsClient( GxsMailSubServices::P3_CHAT_SERVICE,
|
||||
|
@ -76,8 +77,6 @@ int p3ChatService::tick()
|
|||
|
||||
DistributedChatService::flush();
|
||||
|
||||
cleanListOfReceivedMessageHashes();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -203,37 +202,38 @@ void p3ChatService::sendGroupChatStatusString(const std::string& status_string)
|
|||
}
|
||||
}
|
||||
|
||||
void p3ChatService::sendStatusString(const ChatId& id , const std::string& status_string)
|
||||
void p3ChatService::sendStatusString( const ChatId& id,
|
||||
const std::string& status_string )
|
||||
{
|
||||
if(id.isLobbyId())
|
||||
sendLobbyStatusString(id.toLobbyId(),status_string) ;
|
||||
else if(id.isBroadcast())
|
||||
sendGroupChatStatusString(status_string);
|
||||
else if(id.isPeerId() || id.isDistantChatId())
|
||||
{
|
||||
RsChatStatusItem *cs = new RsChatStatusItem ;
|
||||
if(id.isLobbyId()) sendLobbyStatusString(id.toLobbyId(),status_string);
|
||||
else if(id.isBroadcast()) sendGroupChatStatusString(status_string);
|
||||
else if(id.isPeerId() || id.isDistantChatId())
|
||||
{
|
||||
RsPeerId vpid;
|
||||
if(id.isDistantChatId()) vpid = RsPeerId(id.toDistantChatId());
|
||||
else vpid = id.toPeerId();
|
||||
|
||||
cs->status_string = status_string ;
|
||||
cs->flags = RS_CHAT_FLAG_PRIVATE ;
|
||||
RsPeerId vpid;
|
||||
if(id.isDistantChatId())
|
||||
vpid = RsPeerId(id.toDistantChatId());
|
||||
else
|
||||
vpid = id.toPeerId();
|
||||
|
||||
cs->PeerId(vpid);
|
||||
if(isOnline(vpid))
|
||||
{
|
||||
RsChatStatusItem *cs = new RsChatStatusItem;
|
||||
|
||||
cs->status_string = status_string;
|
||||
cs->flags = RS_CHAT_FLAG_PRIVATE;
|
||||
cs->PeerId(vpid);
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "sending chat status packet:" << std::endl ;
|
||||
cs->print(std::cerr) ;
|
||||
std::cerr << "sending chat status packet:" << std::endl;
|
||||
cs->print(std::cerr);
|
||||
#endif
|
||||
sendChatItem(cs);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "p3ChatService::sendStatusString() Error: chat id of this type is not handled, is it empty?" << std::endl;
|
||||
return;
|
||||
}
|
||||
sendChatItem(cs);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "p3ChatService::sendStatusString() Error: chat id of this "
|
||||
<< "type is not handled, is it empty?" << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void p3ChatService::clearChatLobby(const ChatId& id)
|
||||
|
@ -339,7 +339,8 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
|
|||
|
||||
if(destination.isDistantChatId())
|
||||
{
|
||||
DEPMap::const_iterator it =
|
||||
RS_STACK_MUTEX(mDGMutex);
|
||||
DIDEMap::const_iterator it =
|
||||
mDistantGxsMap.find(destination.toDistantChatId());
|
||||
if(it != mDistantGxsMap.end())
|
||||
{
|
||||
|
@ -687,31 +688,50 @@ bool p3ChatService::checkForMessageSecurity(RsChatMsgItem *ci)
|
|||
return true ;
|
||||
}
|
||||
|
||||
bool p3ChatService::initiateDistantChatConnexion(
|
||||
const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id,
|
||||
DistantChatPeerId& pid, uint32_t& error_code )
|
||||
bool p3ChatService::initiateDistantChatConnexion( const RsGxsId& to_gxs_id,
|
||||
const RsGxsId& from_gxs_id,
|
||||
DistantChatPeerId& pid,
|
||||
uint32_t& error_code,
|
||||
bool notify )
|
||||
{
|
||||
if(DistantChatService::initiateDistantChatConnexion( to_gxs_id,
|
||||
from_gxs_id, pid,
|
||||
error_code ))
|
||||
error_code, notify ))
|
||||
{
|
||||
RS_STACK_MUTEX(mDGMutex);
|
||||
DistantEndpoints ep; ep.from = from_gxs_id; ep.to = to_gxs_id;
|
||||
mDistantGxsMap.insert(DEPMap::value_type(pid, ep));
|
||||
mDistantGxsMap.insert(DIDEMap::value_type(pid, ep));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool p3ChatService::receiveGxsMail(const RsGxsMailItem&, const uint8_t* data, uint32_t dataSize)
|
||||
bool p3ChatService::receiveGxsMail( const RsGxsId& authorId,
|
||||
const RsGxsId& recipientId,
|
||||
const uint8_t* data, uint32_t dataSize )
|
||||
{
|
||||
RsChatMsgItem* item = new RsChatMsgItem( const_cast<uint8_t*>(data),
|
||||
dataSize );
|
||||
handleRecvChatMsgItem(item);
|
||||
delete item;
|
||||
return true;
|
||||
DistantChatPeerId pid;
|
||||
uint32_t error_code;
|
||||
if(initiateDistantChatConnexion(
|
||||
authorId, recipientId, pid, error_code, false ))
|
||||
{
|
||||
RsChatMsgItem* item = new RsChatMsgItem( const_cast<uint8_t*>(data),
|
||||
dataSize );
|
||||
RsPeerId rd(p3GxsTunnelService::makeGxsTunnelId(authorId, recipientId));
|
||||
item->PeerId(rd);
|
||||
handleRecvChatMsgItem(item);
|
||||
delete item;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::cerr << "p3ChatService::receiveGxsMail(...) (EE) failed initiating"
|
||||
<< " distant chat connection error: "<< error_code
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool p3ChatService::notifySendMailStatus(const RsGxsMailItem& originalMessage, GxsMailStatus status)
|
||||
bool p3ChatService::notifySendMailStatus( const RsGxsMailItem& originalMessage,
|
||||
GxsMailStatus status )
|
||||
{
|
||||
if ( status != GxsMailStatus::RECEIPT_RECEIVED ) return true;
|
||||
|
||||
|
@ -740,29 +760,6 @@ bool p3ChatService::notifySendMailStatus(const RsGxsMailItem& originalMessage, G
|
|||
|
||||
bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *& ci)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
{ // Check for duplicates
|
||||
uint32_t sz = ci->serial_size();
|
||||
std::vector<uint8_t> srz; srz.resize(sz);
|
||||
ci->serialise(&srz[0], sz);
|
||||
Sha1CheckSum hash = RsDirUtil::sha1sum(&srz[0], sz);
|
||||
{
|
||||
RS_STACK_MUTEX(recentlyReceivedMutex);
|
||||
if( mRecentlyReceivedMessageHashes.find(hash) !=
|
||||
mRecentlyReceivedMessageHashes.end() )
|
||||
{
|
||||
std::cerr << "p3ChatService::handleRecvChatMsgItem(...) (II) "
|
||||
<< "receiving distant message of hash " << hash
|
||||
<< " more than once. Probably it has arrived before "
|
||||
<< "by other means." << std::endl;
|
||||
delete ci; ci=NULL;
|
||||
return true;
|
||||
}
|
||||
mRecentlyReceivedMessageHashes[hash] = now;
|
||||
}
|
||||
}
|
||||
|
||||
std::string name;
|
||||
uint32_t popupChatFlag = RS_POPUP_CHAT;
|
||||
|
||||
|
@ -840,7 +837,7 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *& ci)
|
|||
}
|
||||
}
|
||||
|
||||
ci->recvTime = now;
|
||||
ci->recvTime = time(NULL);
|
||||
|
||||
ChatMessage cm;
|
||||
initChatMessage(ci, cm);
|
||||
|
@ -1169,24 +1166,6 @@ RsChatStatusItem *p3ChatService::makeOwnCustomStateStringItem()
|
|||
return ci ;
|
||||
}
|
||||
|
||||
void p3ChatService::cleanListOfReceivedMessageHashes()
|
||||
{
|
||||
RS_STACK_MUTEX(recentlyReceivedMutex);
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
for( auto it = mRecentlyReceivedMessageHashes.begin();
|
||||
it != mRecentlyReceivedMessageHashes.end(); )
|
||||
if( now > RECENTLY_RECEIVED_INTERVAL + it->second )
|
||||
{
|
||||
std::cerr << "p3MsgService(): cleanListOfReceivedMessageHashes("
|
||||
<< "). Removing old hash " << it->first << ", aged "
|
||||
<< now - it->second << " secs ago." << std::endl;
|
||||
|
||||
it = mRecentlyReceivedMessageHashes.erase(it);
|
||||
}
|
||||
else ++it;
|
||||
}
|
||||
RsChatAvatarItem *p3ChatService::makeOwnAvatarItem()
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
|
|
@ -95,11 +95,11 @@ struct p3ChatService :
|
|||
*/
|
||||
bool sendPrivateChat(const RsPeerId &id, const std::string &msg);
|
||||
|
||||
/*!
|
||||
* can be used to send 'immediate' status msgs, these status updates are meant for immediate use by peer (not saved by rs)
|
||||
* e.g currently used to update user when a peer 'is typing' during a chat
|
||||
*/
|
||||
void sendStatusString(const ChatId& id,const std::string& status_str) ;
|
||||
/**
|
||||
* can be used to send 'immediate' status msgs, these status updates are
|
||||
* meant for immediate use by peer (not saved by rs) e.g currently used to
|
||||
* update user when a peer 'is typing' during a chat */
|
||||
void sendStatusString( const ChatId& id, const std::string& status_str );
|
||||
|
||||
/**
|
||||
* @brief clearChatLobby: Signal chat was cleared by GUI.
|
||||
|
@ -168,10 +168,12 @@ struct p3ChatService :
|
|||
virtual bool initiateDistantChatConnexion( const RsGxsId& to_gxs_id,
|
||||
const RsGxsId& from_gxs_id,
|
||||
DistantChatPeerId &pid,
|
||||
uint32_t& error_code );
|
||||
uint32_t& error_code,
|
||||
bool notify = true );
|
||||
|
||||
/// @see GxsMailsClient::receiveGxsMail(...)
|
||||
virtual bool receiveGxsMail( const RsGxsMailItem& /*originalMessage*/,
|
||||
virtual bool receiveGxsMail( const RsGxsId& authorId,
|
||||
const RsGxsId& recipientId,
|
||||
const uint8_t* data, uint32_t dataSize );
|
||||
|
||||
/// @see GxsMailsClient::notifySendMailStatus(...)
|
||||
|
@ -256,7 +258,7 @@ private:
|
|||
|
||||
AvatarInfo *_own_avatar ;
|
||||
std::map<RsPeerId,AvatarInfo *> _avatars ;
|
||||
std::map<RsPeerId,RsChatMsgItem *> _pendingPartialMessages ;
|
||||
std::map<RsPeerId,RsChatMsgItem *> _pendingPartialMessages;
|
||||
|
||||
std::string _custom_status_string ;
|
||||
std::map<RsPeerId,StateStringInfo> _state_strings ;
|
||||
|
@ -264,16 +266,11 @@ private:
|
|||
RsChatSerialiser *_serializer;
|
||||
|
||||
struct DistantEndpoints { RsGxsId from; RsGxsId to; };
|
||||
typedef std::map<DistantChatPeerId, DistantEndpoints> DEPMap;
|
||||
DEPMap mDistantGxsMap;
|
||||
p3GxsMails& mGxsTransport;
|
||||
typedef std::map<DistantChatPeerId, DistantEndpoints> DIDEMap;
|
||||
DIDEMap mDistantGxsMap;
|
||||
RsMutex mDGMutex;
|
||||
|
||||
/** As we have multiple backends duplicates are possible, keep track of
|
||||
* recently received messages hashes for at least 2h to avoid them */
|
||||
const static uint32_t RECENTLY_RECEIVED_INTERVAL = 2*3600;
|
||||
std::map<Sha1CheckSum, uint32_t> mRecentlyReceivedMessageHashes;
|
||||
RsMutex recentlyReceivedMutex;
|
||||
void cleanListOfReceivedMessageHashes();
|
||||
p3GxsMails& mGxsTransport;
|
||||
};
|
||||
|
||||
class p3ChatService::StateStringInfo
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue