diff --git a/packages/client-core/lib/Client.js b/packages/client-core/lib/Client.js index fbda4fc57..235e07e4e 100644 --- a/packages/client-core/lib/Client.js +++ b/packages/client-core/lib/Client.js @@ -12,6 +12,10 @@ class Client extends Connection { return this.Transport.prototype.send.call(this, element, ...args); } + sendMultiple(...args) { + return this.Transport.prototype.sendMultiple.call(this, ...args); + } + _findTransport(service) { return this.transports.find((Transport) => { try { diff --git a/packages/client/README.md b/packages/client/README.md index c253ff478..6f2767da0 100644 --- a/packages/client/README.md +++ b/packages/client/README.md @@ -230,7 +230,11 @@ xmpp.send(xml("presence")).catch(console.error); Returns a promise that resolves once the stanza is serialized and written to the socket or rejects if any of those fails. -You can also pass multiple stanzas. Here is an example sending the same text message to multiple recipients. +### sendMultiple + +Sends multiple stanzas. + +Here is an example sending the same text message to multiple recipients. ```js const message = "Hello"; @@ -238,9 +242,13 @@ const recipients = ["romeo@example.com", "juliet@example.com"]; const stanzas = recipients.map((address) => xml("message", { to: address, type: "chat" }, xml("body", null, message)), ); -xmpp.send(...stanzas).catch(console.error); +xmpp.sendMultiple(stanzas).catch(console.error); ``` +Returns a promise that resolves once all the stanzas have been sent. + +If you need to send a stanza to multiple recipients we recommend using [Extended Stanza Addressing](https://xmpp.org/extensions/xep-0033.html) instead. + ### xmpp.reconnect See [@xmpp/reconnect](/packages/reconnect). diff --git a/packages/component/README.md b/packages/component/README.md index 2a8542a27..862cdeaa1 100644 --- a/packages/component/README.md +++ b/packages/component/README.md @@ -200,7 +200,11 @@ xmpp.send(xml("presence")).catch(console.error); Returns a promise that resolves once the stanza is serialized and written to the socket or rejects if any of those fails. -You can also pass multiple stanzas. Here is an example sending the same text message to multiple recipients. +### sendMultiple + +Sends multiple stanzas. + +Here is an example sending the same text message to multiple recipients. ```js const message = "Hello"; @@ -208,9 +212,13 @@ const recipients = ["romeo@example.com", "juliet@example.com"]; const stanzas = recipients.map((address) => xml("message", { to: address, type: "chat" }, xml("body", null, message)), ); -xmpp.send(...stanzas).catch(console.error); +xmpp.sendMultiple(stanzas).catch(console.error); ``` +Returns a promise that resolves once all the stanzas have been sent. + +If you need to send a stanza to multiple recipients we recommend using [Extended Stanza Addressing](https://xmpp.org/extensions/xep-0033.html) instead. + ### xmpp.reconnect See [@xmpp/reconnect](/packages/reconnect). diff --git a/packages/connection-tcp/index.js b/packages/connection-tcp/index.js index f4de72fb6..36f3dd032 100644 --- a/packages/connection-tcp/index.js +++ b/packages/connection-tcp/index.js @@ -11,6 +11,21 @@ const NS_STREAM = "http://etherx.jabber.org/streams"; * Extensible Messaging and Presence Protocol (XMPP): Core http://xmpp.org/rfcs/rfc6120.html */ class ConnectionTCP extends Connection { + async sendMultiple(elements) { + let fragment = ""; + + for (const element of elements) { + element.parent = this.root; + fragment += element.toString(); + } + + await this.write(fragment); + + for (const element of elements) { + this.emit("send", element); + } + } + socketParameters(service) { const { port, hostname, protocol } = parseURI(service); diff --git a/packages/connection-tcp/test/Connection.js b/packages/connection-tcp/test/Connection.js index 5e208c6ee..3c37cae8b 100644 --- a/packages/connection-tcp/test/Connection.js +++ b/packages/connection-tcp/test/Connection.js @@ -4,6 +4,7 @@ const test = require("ava"); const _Connection = require("../../../packages/connection"); const Connection = require(".."); const net = require("net"); +const xml = require("@xmpp/xml"); const NS_STREAM = "http://etherx.jabber.org/streams"; @@ -52,3 +53,21 @@ test("socketParameters()", (t) => { undefined, ); }); + +test("sendMultiple", async (t) => { + t.plan(1); + const conn = new Connection(); + conn.root = xml("root"); + + const foo = xml("foo"); + const bar = xml("bar"); + + conn.socket = { + write(str, fn) { + t.is(str, ""); + fn(); + }, + }; + + await conn.sendMultiple([foo, bar]); +}); diff --git a/packages/connection/index.js b/packages/connection/index.js index 53ea20f9f..71a99cada 100644 --- a/packages/connection/index.js +++ b/packages/connection/index.js @@ -308,19 +308,10 @@ class Connection extends EventEmitter { return this.open({ domain, lang }); } - async send(...elements) { - let fragment = ""; - - for (const element of elements) { - element.parent = this.root; - fragment += element.toString(); - } - - await this.write(fragment); - - for (const element of elements) { - this.emit("send", element); - } + async send(element) { + element.parent = this.root; + await this.write(element.toString()); + this.emit("send", element); } sendReceive(element, timeout = this.timeout) { diff --git a/packages/connection/test/send.js b/packages/connection/test/send.js index 06f094b4e..d5052dc17 100644 --- a/packages/connection/test/send.js +++ b/packages/connection/test/send.js @@ -4,7 +4,7 @@ const xml = require("@xmpp/xml"); const test = require("ava"); const Connection = require(".."); -test("single element", (t) => { +test("send", (t) => { t.plan(3); const conn = new Connection(); conn.root = xml("root"); @@ -27,20 +27,3 @@ test("single element", (t) => { t.is(element, foo); }); }); - -test("multiple elements", (t) => { - t.plan(1); - const conn = new Connection(); - conn.root = xml("root"); - - const foo = xml("foo"); - const bar = xml("bar"); - - conn.socket = { - write(str) { - t.is(str, ""); - }, - }; - - conn.send(foo, bar); -}); diff --git a/packages/websocket/lib/Connection.js b/packages/websocket/lib/Connection.js index bab3e9b39..eda0859d4 100644 --- a/packages/websocket/lib/Connection.js +++ b/packages/websocket/lib/Connection.js @@ -22,6 +22,12 @@ class ConnectionWebSocket extends Connection { return super.send(element, ...args); } + async sendMultiple(elements) { + for (const element of elements) { + await this.send(element); + } + } + // https://tools.ietf.org/html/rfc7395#section-3.6 footerElement() { return new xml.Element("close", { diff --git a/packages/websocket/test/test.js b/packages/websocket/test/test.js index b44e7573f..deaeb5052 100644 --- a/packages/websocket/test/test.js +++ b/packages/websocket/test/test.js @@ -81,3 +81,18 @@ test("socket close", (t) => { socket.socket.emit("close", evt); }); + +test("sendMultiple", async (t) => { + t.plan(2); + const conn = new ConnectionWebSocket(); + conn.root = xml("root"); + + const foo = xml("foo"); + const bar = xml("bar"); + + conn.send = () => { + t.pass(); + }; + + await conn.sendMultiple([foo, bar]); +});