diff --git a/addons/mail/controllers/discuss.py b/addons/mail/controllers/discuss.py index b6319eec329..aa828d571fe 100644 --- a/addons/mail/controllers/discuss.py +++ b/addons/mail/controllers/discuss.py @@ -439,6 +439,19 @@ class DiscussController(http.Controller): if session and session.partner_id == request.env.user.partner_id: session._update_and_broadcast(values) + @http.route('/mail/rtc/session/ping', methods=['POST'], type='json', auth='public') + def rtc_session_ping(self, rtc_session_id): + rtc_session_sudo = request.env['mail.channel.rtc.session'].sudo().browse(int(rtc_session_id)).exists() + if not rtc_session_sudo: + return + if request.env.user._is_public(): + guest = request.env['mail.guest']._get_guest_from_request(request) + if not guest or guest != rtc_session_sudo.guest_id: + return + elif rtc_session_sudo.env.user.partner_id != rtc_session_sudo.partner_id: + return + rtc_session_sudo.write({}) # update write_date + @http.route('/mail/rtc/channel/join_call', methods=['POST'], type="json", auth="public") def channel_call_join(self, channel_id): """ Joins the RTC call of a channel if the user is a member of that channel diff --git a/addons/mail/models/mail_channel_partner.py b/addons/mail/models/mail_channel_partner.py index f4f9ef998b1..e1d7d2173b9 100644 --- a/addons/mail/models/mail_channel_partner.py +++ b/addons/mail/models/mail_channel_partner.py @@ -112,6 +112,7 @@ class ChannelPartner(models.Model): self.ensure_one() self.channel_id._rtc_cancel_invitations(partner_ids=self.partner_id.ids, guest_ids=self.guest_id.ids) self.rtc_session_ids._disconnect() + self.env['mail.channel.rtc.session']._gc_inactive_sessions() rtc_session = self.env['mail.channel.rtc.session'].create({'channel_partner_id': self.id}) res = { 'iceServers': self.env['mail.ice.server']._get_ice_servers() or False, diff --git a/addons/mail/models/mail_channel_rtc_session.py b/addons/mail/models/mail_channel_rtc_session.py index 1f4cfead1ae..ea24de61bd2 100644 --- a/addons/mail/models/mail_channel_rtc_session.py +++ b/addons/mail/models/mail_channel_rtc_session.py @@ -75,7 +75,7 @@ class MailRtcSession(models.Model): this can happen when the server or the user's browser crash or when the user's odoo session ends. """ - rtc_sessions = self.search([('write_date', '<', fields.Datetime.now() - relativedelta(days=1))]) + rtc_sessions = self.search([('write_date', '<', fields.Datetime.now() - relativedelta(minutes=1))]) rtc_sessions._disconnect() def action_disconnect(self): diff --git a/addons/mail/static/src/models/rtc/rtc.js b/addons/mail/static/src/models/rtc/rtc.js index bed80e939fa..1fe795208c8 100644 --- a/addons/mail/static/src/models/rtc/rtc.js +++ b/addons/mail/static/src/models/rtc/rtc.js @@ -77,7 +77,13 @@ function factory(dependencies) { * connection that were established but failed or timed out. */ this._intervalId = browser.setInterval(() => { - this.channel && this.currentRtcSession && this._callSessions(); + if (!this.currentRtcSession) { + return; + } + this._pingServer(); + if (this.channel) { + this._callSessions(); + } }, 30000); // 30 seconds } @@ -664,6 +670,18 @@ function factory(dependencies) { } } + /** + * Pings the server to ensure this session is kept alive. + */ + async _pingServer() { + await this.env.services.rpc({ + route: '/mail/rtc/session/ping', + params: { + 'rtc_session_id': this.currentRtcSession.id, + }, + }, { shadow: true }); + } + /** * Attempts a connection recovery by closing and restarting the call * from the receiving end.