Skip to content

Commit

Permalink
Add support for multiple encodings for messages
Browse files Browse the repository at this point in the history
  • Loading branch information
interpretor committed Jul 11, 2017
1 parent 81970e6 commit d4fa967
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 21 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ Returns information of all known groups
zyre.getGroups();
```

Sets the encoding of received messages. Defaults to utf8

```js
zyre.setEncoding('utf8'); // Default encoding
zyre.setEncoding(null); // Receive raw Buffers as messages
// Available encodings: ascii, utf8, utf16le/ucs2, base64, binary, hex, raw/null
```

Connect is fired when a new peer joins the network

```js
Expand Down
65 changes: 53 additions & 12 deletions lib/zyre.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class Zyre extends EventEmitter {
* Sends a message to a ZyrePeer.
*
* @param {string} identity - Identity of the peer
* @param {Buffer} message - Message to send
* @param {(string|Buffer)} message - Message to send
*/
whisper(identity, message) {
if (this._zyrePeers.exists(identity)) {
Expand All @@ -173,7 +173,7 @@ class Zyre extends EventEmitter {
* Sends a message to a ZyreGroup.
*
* @param {string} group - Name of the group
* @param {Buffer} message - Message to send
* @param {(string|Buffer)} message - Message to send
*/
shout(group, message) {
if (this._zyreGroups.exists(group)) {
Expand Down Expand Up @@ -249,6 +249,45 @@ class Zyre extends EventEmitter {
return this._zyreGroups.toObj();
}

/**
* Sets the encoding of received messages. Defaults to utf8.
*
* @param {string} encoding - Encoding of messages
*/
setEncoding(encoding) {
switch (encoding) {
case 'ascii':
case 'utf8':
case 'utf16le':
case 'ucs2':
case 'base64':
case 'binary':
case 'hex':
this._encoding = encoding;
break;

case 'raw':
case null:
this._encoding = 'raw';
break;

default:
this._encoding = 'utf8';
}
}

/**
* Returns the encoded content of the ZreMsg. Encoding is set by setEncoding(encoding).
*
* @param {Buffer} content - Content of a ZreMsg
* @return {(string|Buffer)}
*/
_getEncodedContent(content) {
if (typeof this._encoding === 'undefined') return content.toString('utf8');
if (this._encoding === 'raw') return content;
return content.toString(this._encoding);
}

/**
* Creates handler as object properties in a separate method to ensure proper scope via arrow
* functions.
Expand Down Expand Up @@ -284,45 +323,47 @@ class Zyre extends EventEmitter {
this.emit('expired', peer.getIdentity(), peer.getName());
};

this._whisperHandler = (peer, message) => {
this._whisperHandler = (peer, msg) => {
const content = this._getEncodedContent(msg.getContent());
/**
* @event Zyre#whisper
* @property {string} identity - Identity of the peer
* @property {string} name - Name of the peer
* @property {Buffer} message - Message
* @property {(string|Buffer)} message - Message
*/
this.emit('whisper', peer.getIdentity(), peer.getName(), message);
this.emit('whisper', peer.getIdentity(), peer.getName(), content);
};

this._shoutHandler = (peer, message, group) => {
this._shoutHandler = (peer, msg) => {
const content = this._getEncodedContent(msg.getContent());
/**
* @event Zyre#shout
* @property {string} identity - Identity of the peer
* @property {string} name - Name of the peer
* @property {Buffer} message - Message
* @property {(string|Buffer)} message - Message
* @property {string} group - Group where the message came from
*/
this.emit('shout', peer.getIdentity(), peer.getName(), message, group);
this.emit('shout', peer.getIdentity(), peer.getName(), content, msg.getGroup());
};

this._joinHandler = (peer, group) => {
this._joinHandler = (peer, msg) => {
/**
* @event Zyre#join
* @property {string} identity - Identity of the peer
* @property {string} name - Name of the peer
* @property {string} group - Group which the peer joins
*/
this.emit('join', peer.getIdentity(), peer.getName(), group);
this.emit('join', peer.getIdentity(), peer.getName(), msg.getGroup());
};

this._leaveHandler = (peer, group) => {
this._leaveHandler = (peer, msg) => {
/**
* @event Zyre#leave
* @property {string} identity - Identity of the peer
* @property {string} name - Name of the peer
* @property {string} group - Group which the peer leaves
*/
this.emit('leave', peer.getIdentity(), peer.getName(), group);
this.emit('leave', peer.getIdentity(), peer.getName(), msg.getGroup());
};
}

Expand Down
17 changes: 8 additions & 9 deletions lib/zyre_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,20 +202,19 @@ class ZyreNode extends EventEmitter {
/**
* @event ZyreNode#whisper
* @property {ZyrePeer} zyrePeer - ZyrePeer
* @property {Buffer} message - Message
* @property {ZreMsg} zreMsg - ZreMsg
*/
this.emit('whisper', zyrePeer, zreMsg.getContent());
this.emit('whisper', zyrePeer, zreMsg);
break;

case ZreMsg.SHOUT:
if (this._groups.includes(zreMsg.getGroup())) {
/**
* @event ZyreNode#shout
* @property {ZyrePeer} zyrePeer - ZyrePeer
* @property {Buffer} message - Message
* @property {string} group - Group where the message came from
* @property {ZreMsg} zreMsg - ZreMsg
*/
this.emit('shout', zyrePeer, zreMsg.getContent(), zreMsg.getGroup());
this.emit('shout', zyrePeer, zreMsg);
}
break;

Expand All @@ -224,19 +223,19 @@ class ZyreNode extends EventEmitter {
/**
* @event ZyreNode#join
* @property {ZyrePeer} zyrePeer - ZyrePeer
* @property {string} group - Group which the peer joins
* @property {ZreMsg} zreMsg - ZreMsg
*/
this.emit('join', zyrePeer, zreMsg.getGroup());
this.emit('join', zyrePeer, zreMsg);
break;

case ZreMsg.LEAVE:
this._zyreGroups.remove(zreMsg.getGroup(), zyrePeer);
/**
* @event ZyreNode#leave
* @property {ZyrePeer} zyrePeer - ZyrePeer
* @property {string} group - Group which the peer leaves
* @property {ZreMsg} zreMsg - ZreMsg
*/
this.emit('leave', zyrePeer, zreMsg.getGroup());
this.emit('leave', zyrePeer, zreMsg);
break;

case ZreMsg.PING:
Expand Down
57 changes: 57 additions & 0 deletions test/zyre_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,4 +355,61 @@ describe('Zyre', () => {
});
});
});

it('should support different encodings for messages', (done) => {
const zyre1 = new Zyre();
const zyre2 = new Zyre();

let hit = 0;

zyre1.on('shout', (id, name, msg) => {
hit += 1;
if (hit === 1) assert.isTrue(Buffer.isBuffer(msg));
if (hit === 2) assert.strictEqual(msg, 'asdC$C6C<b\u0002,');
if (hit === 3) assert.strictEqual(msg, 'asdäöü€');
if (hit === 4) assert.strictEqual(msg, '跧꒍軬뚎諮芲');
if (hit === 5) assert.strictEqual(msg, '跧꒍軬뚎諮芲');
if (hit === 6) assert.strictEqual(msg, 'WVhOa3c2VER0c084NG9Lcw==');
if (hit === 7) assert.strictEqual(msg, 'asdäöü€');
if (hit === 8) assert.strictEqual(msg, '363137333634633361346333623663336263653238326163');
if (hit === 9) assert.strictEqual(msg, 'asdäöü€');
});

const stopAll = () => {
zyre2.stop().then(() => {
zyre1.stop().then(() => {
if (hit === 9) setTimeout(() => done(), 100);
});
});
};

function sendMessage(encoding) {
zyre1.setEncoding(encoding);

if (encoding === null) {
zyre2.shout('CHAT', Buffer.from('asdäöü€'));
} else if (encoding === 'garbish') {
zyre2.shout('CHAT', 'asdäöü€');
} else {
zyre2.shout('CHAT', Buffer.from('asdäöü€').toString(encoding));
}
}

zyre1.start().then(() => {
zyre1.join('CHAT');
zyre2.start().then(() => {
zyre2.join('CHAT');
setTimeout(() => sendMessage(null), 50);
setTimeout(() => sendMessage('ascii'), 100);
setTimeout(() => sendMessage('utf8'), 150);
setTimeout(() => sendMessage('utf16le'), 200);
setTimeout(() => sendMessage('ucs2'), 250);
setTimeout(() => sendMessage('base64'), 300);
setTimeout(() => sendMessage('binary'), 350);
setTimeout(() => sendMessage('hex'), 400);
setTimeout(() => sendMessage('garbish'), 450);
setTimeout(stopAll, 500);
});
});
});
});

0 comments on commit d4fa967

Please sign in to comment.