Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Uses json-message extension in Chatroom.js (#770)
* Uses json message extension

* Sends json-message without the body element

* Info comments and parameter order changes
  • Loading branch information
pvgupta24 authored and bgrozev committed Jul 17, 2018
1 parent 05b7ae6 commit 9207f1f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 40 deletions.
32 changes: 18 additions & 14 deletions JitsiConference.js
Expand Up @@ -43,7 +43,7 @@ import RecordingManager from './modules/recording/RecordingManager';
import VideoSIPGW from './modules/videosipgw/VideoSIPGW';
import * as VideoSIPGWConstants from './modules/videosipgw/VideoSIPGWConstants';
import * as XMPPEvents from './service/xmpp/XMPPEvents';
import { JITSI_MEET_MUC_TOPIC } from './modules/xmpp/ChatRoom';
import { JITSI_MEET_MUC_TYPE } from './modules/xmpp/ChatRoom';

import SpeakerStatsCollector from './modules/statistics/SpeakerStatsCollector';

Expand Down Expand Up @@ -588,22 +588,27 @@ JitsiConference.prototype.removeCommandListener = function(command) {
/**
* Sends text message to the other participants in the conference
* @param message the text message.
* @param elementName the element name to encapsulate the message.
* @deprecated Use 'sendMessage' instead. TODO: this should be private.
*/
JitsiConference.prototype.sendTextMessage = function(message) {
JitsiConference.prototype.sendTextMessage = function(
message, elementName = 'body') {
if (this.room) {
this.room.sendMessage(message);
this.room.sendMessage(message, elementName);
}
};

/**
* Send private text message to another participant of the conference
* @param id the id of the participant to send a private message.
* @param message the text message.
* @param elementName the element name to encapsulate the message.
* @deprecated Use 'sendMessage' instead. TODO: this should be private.
*/
JitsiConference.prototype.sendPrivateTextMessage = function(id, message) {
JitsiConference.prototype.sendPrivateTextMessage = function(
id, message, elementName = 'body') {
if (this.room) {
this.room.sendPrivateMessage(id, message);
this.room.sendPrivateMessage(id, message, elementName);
}
};

Expand Down Expand Up @@ -2144,16 +2149,15 @@ JitsiConference.prototype.sendMessage = function(
} else {
let messageToSend = message;

if (messageType === 'object') {
// Encapsulate the object in the jitsi-meet format, and convert it
// to JSON.
messageToSend = {
payload: message,
[JITSI_MEET_MUC_TOPIC]: ''
};
// Name of packet extension of message stanza to send the required
// message in.
let elementName = 'body';

if (messageType === 'object') {
try {
messageToSend[JITSI_MEET_MUC_TYPE] = '';
messageToSend = JSON.stringify(messageToSend);
elementName = 'json-message';
} catch (e) {
logger.error('Can not send a message, stringify failed: ', e);

Expand All @@ -2162,10 +2166,10 @@ JitsiConference.prototype.sendMessage = function(
}

if (to) {
this.sendPrivateTextMessage(to, messageToSend);
this.sendPrivateTextMessage(to, messageToSend, elementName);
} else {
// Broadcast
this.sendTextMessage(messageToSend);
this.sendTextMessage(messageToSend, elementName);
}
}

Expand Down
72 changes: 46 additions & 26 deletions modules/xmpp/ChatRoom.js
Expand Up @@ -79,21 +79,19 @@ function filterNodeFromPresenceJSON(pres, nodeName) {
/**
* The name of the field used to recognize a chat message as carrying a JSON
* payload from another endpoint.
* If the body of a chat message contains a valid JSON object, and the JSON has
* this key, then the transported payload is contained in the 'payload'
* property of the JSON object.
* If the json-message of a chat message contains a valid JSON object, and the
* JSON has this key, then it is a valid json-message to be sent.
*/
export const JITSI_MEET_MUC_TOPIC = 'jitsi-meet-muc-msg-topic';
export const JITSI_MEET_MUC_TYPE = 'type';

/**
* Check if the given argument is a valid JSON ENDPOINT_MESSAGE string by
* parsing it and checking if it has a field called 'jitsi-meet-muc-msg-topic'
* and a field called 'payload'
* parsing it and checking if it has a field called 'type'.
*
* @param {string} jsonString check if this string is a valid json string
* and contains the special structure
* and contains the special structure.
* @returns {boolean, object} if given object is a valid JSON string, return
* the json object. Otherwise, return false;
* the json object. Otherwise, returns false.
*/
function tryParseJSONAndVerify(jsonString) {
try {
Expand All @@ -107,15 +105,14 @@ function tryParseJSONAndVerify(jsonString) {
// so we must check for that, too.
// Thankfully, null is falsey, so this suffices:
if (json && typeof json === 'object') {
const topic = json[JITSI_MEET_MUC_TOPIC];
const payload = json.payload;
const type = json[JITSI_MEET_MUC_TYPE];

if ((typeof topic !== 'undefined') && payload) {
return payload;
if (typeof type !== 'undefined') {
return json;
}

logger.debug('parsing valid json but does not have correct '
+ 'structure', 'topic: ', topic, 'payload: ', payload);
+ 'structure', 'topic: ', type);
}
} catch (e) {

Expand Down Expand Up @@ -708,35 +705,54 @@ export default class ChatRoom extends Listenable {

/**
* Send text message to the other participants in the conference
* @param body
* @param message
* @param elementName
* @param nickname
*/
sendMessage(body, nickname) {
sendMessage(message, elementName, nickname) {
const msg = $msg({ to: this.roomjid,
type: 'groupchat' });

msg.c('body', body).up();
// We are adding the message in a packet extension. If this element
// is different from 'body', we add a custom namespace.
// e.g. for 'json-message' extension of message stanza.
if (elementName === 'body') {
msg.c(elementName, message).up();
} else {
msg.c(elementName, { xmlns: 'http://jitsi.org/jitmeet' }, message)
.up();
}
if (nickname) {
msg.c('nick', { xmlns: 'http://jabber.org/protocol/nick' })
.t(nickname)
.up()
.up();
}
this.connection.send(msg);
this.eventEmitter.emit(XMPPEvents.SENDING_CHAT_MESSAGE, body);
this.eventEmitter.emit(XMPPEvents.SENDING_CHAT_MESSAGE, message);
}

/* eslint-disable max-params */
/**
* Send private text message to another participant of the conference
* @param id id/muc resource of the receiver
* @param body
* @param message
* @param elementName
* @param nickname
*/
sendPrivateMessage(id, body, nickname) {
sendPrivateMessage(id, message, elementName, nickname) {
const msg = $msg({ to: `${this.roomjid}/${id}`,
type: 'chat' });

msg.c('body', body).up();
// We are adding the message in packet. If this element is different
// from 'body', we add our custom namespace for the same.
// e.g. for 'json-message' message extension.
if (elementName === 'body') {
msg.c(elementName, message).up();
} else {
msg.c(elementName, { xmlns: 'http://jitsi.org/jitmeet' }, message)
.up();
}
if (nickname) {
msg.c('nick', { xmlns: 'http://jabber.org/protocol/nick' })
.t(nickname)
Expand All @@ -745,9 +761,10 @@ export default class ChatRoom extends Listenable {
}

this.connection.send(msg);
this.eventEmitter.emit(XMPPEvents.SENDING_PRIVATE_CHAT_MESSAGE, body);
this.eventEmitter.emit(
XMPPEvents.SENDING_PRIVATE_CHAT_MESSAGE, message);
}

/* eslint-enable max-params */

/**
*
Expand Down Expand Up @@ -907,12 +924,15 @@ export default class ChatRoom extends Listenable {
.length) {
this.discoRoomInfo();
}
const jsonMessage = $(msg).find('>json-message').text();
const parsedJson = tryParseJSONAndVerify(jsonMessage);

const jsonPayload = tryParseJSONAndVerify(txt);

if (jsonPayload) {
// We emit this event if the message is a valid json, and is not
// delivered after a delay, i.e. stamp is undefined.
// e.g. - subtitles should not be displayed if delayed.
if (parsedJson && stamp === undefined) {
this.eventEmitter.emit(XMPPEvents.JSON_MESSAGE_RECEIVED,
from, jsonPayload);
from, parsedJson);

return;
}
Expand Down

0 comments on commit 9207f1f

Please sign in to comment.