mirror of
https://github.com/lubosz/overte.git
synced 2025-04-13 20:06:16 +02:00
Merge pull request #16574 from ctrlaltdavid/DOC-242
DOC-242: WebSocket and WebSocketServer JSDoc
This commit is contained in:
commit
bec28e7e05
3 changed files with 256 additions and 0 deletions
|
@ -68,6 +68,18 @@ void WebSocketClass::close(QWebSocketProtocol::CloseCode closeCode, QString reas
|
|||
_webSocket->close(closeCode, reason);
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* Called when the connection closes.
|
||||
* @callback WebSocket~onCloseCallback
|
||||
* @param {WebSocket.CloseData} data - Information on the connection closure.
|
||||
*/
|
||||
/**jsdoc
|
||||
* Information on a connection being closed.
|
||||
* @typedef {object} WebSocket.CloseData
|
||||
* @property {WebSocket.CloseCode} code - The reason why the connection was closed.
|
||||
* @property {string} reason - Description of the reason why the connection was closed.
|
||||
* @property {boolean} wasClean - <code>true</code> if the connection closed cleanly, <code>false</code> if it didn't.
|
||||
*/
|
||||
void WebSocketClass::handleOnClose() {
|
||||
bool hasError = (_webSocket->error() != QAbstractSocket::UnknownSocketError);
|
||||
if (_onCloseEvent.isFunction()) {
|
||||
|
@ -81,12 +93,73 @@ void WebSocketClass::handleOnClose() {
|
|||
}
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* Called when an error occurs.
|
||||
* @callback WebSocket~onErrorCallback
|
||||
* @param {WebSocket.SocketError} error - The error.
|
||||
*/
|
||||
/**jsdoc
|
||||
* Information on a socket error.
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Name</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>0</code></td><td>ConnectionRefusedError</td><td>The connection was refused or timed out.</td></tr>
|
||||
* <tr><td><code>1</code></td><td>RemoteHostClosedError</td><td>The remote host closed the connection.</td></tr>
|
||||
* <tr><td><code>2</code></td><td>HostNotFoundError</td><td>The host address was not found.</td></tr>
|
||||
* <tr><td><code>3</code></td><td>SocketAccessError</td><td>The socket operation failed because the application doesn't have
|
||||
* the necessary privileges.</td></tr>
|
||||
* <tr><td><code>4</code></td><td>SocketResourceError</td><td>The local system ran out of resources (e.g., too many
|
||||
* sockets).</td></tr>
|
||||
* <tr><td><code>5</code></td><td>SocketTimeoutError</td><td>The socket operation timed out.</td></tr>
|
||||
* <tr><td><code>6</code></td><td>DatagramTooLargeError</td><td>The datagram was larger than the OS's limit.</td></tr>
|
||||
* <tr><td><code>7</code></td><td>NetworkError</td><td>An error occurred with the network.</td></tr>
|
||||
* <tr><td><code>8</code></td><td>AddressInUseError</td><td>The is already in use and cannot be reused.</td></tr>
|
||||
* <tr><td><code>9</code></td><td>SocketAddressNotAvailableError</td><td>The address specified does not belong to the
|
||||
* host.</td></tr>
|
||||
* <tr><td><code>10</code></td><td>UnsupportedSocketOperationError</td><td>The requested socket operation is not supported
|
||||
* by the local OS.</td></tr>
|
||||
* <tr><td><code>11</code></td><td>ProxyAuthenticationRequiredError</td><td>The socket is using a proxy and requires
|
||||
* authentication.</td></tr>
|
||||
* <tr><td><code>12</code></td><td>SslHandshakeFailedError</td><td>The SSL/TLS handshake failed.</td></tr>
|
||||
* <tr><td><code>13</code></td><td>UnfinishedSocketOperationError</td><td>The last operation has not finished yet.</td></tr>
|
||||
* <tr><td><code>14</code></td><td>ProxyConnectionRefusedError</td><td>Could not contact the proxy server because connection
|
||||
* was denied.</td></tr>
|
||||
* <tr><td><code>15</code></td><td>ProxyConnectionClosedError</td><td>The connection to the proxy server was unexpectedly
|
||||
* closed.</td></tr>
|
||||
* <tr><td><code>16</code></td><td>ProxyConnectionTimeoutError</td><td>The connection to the proxy server timed
|
||||
* out.</td></tr>
|
||||
* <tr><td><code>17</code></td><td>ProxyNotFoundError</td><td>The proxy address was not found.</td></tr>
|
||||
* <tr><td><code>18</code></td><td>ProxyProtocolError</td><td>Connection to the proxy server failed because the server
|
||||
* response could not be understood.</td></tr>
|
||||
* <tr><td><code>19</code></td><td>OperationError</td><td>An operation failed because the socket state did not permit
|
||||
* it.</td></tr>
|
||||
* <tr><td><code>20</code></td><td>SslInternalError</td><td>Internal error in the SSL library being used.</td></tr>
|
||||
* <tr><td><code>21</code></td><td>SslInvalidUserDataError</td><td>Error in the SSL library because of invalid
|
||||
* data.</td></tr>
|
||||
* <tr><td><code>22</code></td><td>TemporaryError</td><td>A temporary error occurred.</td></tr>
|
||||
* <tr><td><code>-1</code></td><td>UnknownSocketError</td><td>An unknown error occurred.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {number} WebSocket.SocketError
|
||||
*/
|
||||
void WebSocketClass::handleOnError(QAbstractSocket::SocketError error) {
|
||||
if (_onErrorEvent.isFunction()) {
|
||||
_onErrorEvent.call();
|
||||
}
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a message is received.
|
||||
* @callback WebSocket~onMessageCallback
|
||||
* @param {WebSocket.MessageData} message - The message received.
|
||||
*/
|
||||
/**jsdoc
|
||||
* A message received on a WebSocket connection.
|
||||
* @typedef {object} WebSocket.MessageData
|
||||
* @property {string} data - The message content.
|
||||
*/
|
||||
void WebSocketClass::handleOnMessage(const QString& message) {
|
||||
if (_onMessageEvent.isFunction()) {
|
||||
QScriptValueList args;
|
||||
|
@ -97,6 +170,10 @@ void WebSocketClass::handleOnMessage(const QString& message) {
|
|||
}
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* Called when the connection opens.
|
||||
* @callback WebSocket~onOpenCallback
|
||||
*/
|
||||
void WebSocketClass::handleOnOpen() {
|
||||
if (_onOpenEvent.isFunction()) {
|
||||
_onOpenEvent.call();
|
||||
|
|
|
@ -16,6 +16,68 @@
|
|||
#include <QScriptEngine>
|
||||
#include <QWebSocket>
|
||||
|
||||
/**jsdoc
|
||||
* Provides a bi-direcctional, event-driven communication session between the script and another WebSocket connection. It is a
|
||||
* near-complete implementation of the WebSocket API described in the Mozilla docs:
|
||||
* <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket">https://developer.mozilla.org/en-US/docs/Web/API/WebSocket</a>.</p>
|
||||
*
|
||||
* <p>Constructed by <code>new WebSocket(...)</code> in Interface, client entity, avatar, and server entity scripts, or the
|
||||
* {@link WebSocketServer} class in server entity and assignment client scripts.
|
||||
*
|
||||
* <p><strong>Note:</strong> Does not support secure, <code>wss:</code> protocol.</p>
|
||||
*
|
||||
* @class WebSocket
|
||||
* @param {string|WebSocket} urlOrWebSocket - The URL to connect to or an existing {@link WebSocket} to reuse the connection of.
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
* @property {string} binaryType="blob" - <em>Not used.</em>
|
||||
* @property {number} bufferedAmount=0 - <em>Not implemented.</em> <em>Read-only.</em>
|
||||
* @property {string} extensions="" - <em>Not implemented.</em> <em>Read-only.</em>
|
||||
*
|
||||
* @property {WebSocket~onOpenCallback} onopen - Function called when the connection opens.
|
||||
* @property {WebSocket~onMessageCallback} onmessage - Function called when a message is received.
|
||||
* @property {WebSocket~onErrorCallback} onerror - Function called when an error occurs.
|
||||
* @property {WebSocket~onCloseCallback} onclose - Function called when the connection closes.
|
||||
*
|
||||
* @property {string} protocol="" - <em>Not implemented.</em> <em>Read-only.</em>
|
||||
* @property {WebSocket.ReadyState} readyState - The state of the connection. <em>Read-only.</em>
|
||||
* @property {string} url - The URL to connect to. <em>Read-only.</em>
|
||||
*
|
||||
* @property {WebSocket.ReadyState} CONNECTING - The connection is opening. <em>Read-only.</em>
|
||||
* @property {WebSocket.ReadyState} OPEN - The connection is open. <em>Read-only.</em>
|
||||
* @property {WebSocket.ReadyState} CLOSING - The connection is closing. <em>Read-only.</em>
|
||||
* @property {WebSocket.ReadyState} CLOSED - The connection is closed. <em>Read-only.</em>
|
||||
*
|
||||
* @example <caption>Echo a message off websocket.org.</caption>
|
||||
* print("Create WebSocket");
|
||||
* var WEBSOCKET_PING_URL = "ws://echo.websocket.org";
|
||||
* var webSocket = new WebSocket(WEBSOCKET_PING_URL);
|
||||
*
|
||||
* webSocket.onclose = function (data) {
|
||||
* print("WebSocket closed");
|
||||
* print("Ready state =", webSocket.readyState); // 3
|
||||
* };
|
||||
*
|
||||
* webSocket.onmessage = function (data) {
|
||||
* print("Message received:", data.data);
|
||||
*
|
||||
* print("Close WebSocket");
|
||||
* webSocket.close();
|
||||
* };
|
||||
*
|
||||
* webSocket.onopen = function () {
|
||||
* print("WebSocket opened");
|
||||
* print("Ready state =", webSocket.readyState); // 1
|
||||
*
|
||||
* print("Send a test message");
|
||||
* webSocket.send("Test message");
|
||||
* };
|
||||
*/
|
||||
class WebSocketClass : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString binaryType READ getBinaryType WRITE setBinaryType)
|
||||
|
@ -43,6 +105,21 @@ public:
|
|||
|
||||
static QScriptValue constructor(QScriptContext* context, QScriptEngine* engine);
|
||||
|
||||
/**jsdoc
|
||||
* The state of a WebSocket connection.
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Name</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>0</code></td><td>CONNECTING</td><td>The connection is opening.</td></tr>
|
||||
* <tr><td><code>1</code></td><td>OPEN</td><td>The connection is open.</td></tr>
|
||||
* <tr><td><code>2</code></td><td>CLOSING</td><td>The connection is closing.</td></tr>
|
||||
* <tr><td><code>3</code></td><td>CLOSED</td><td>The connection is closed.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {number} WebSocket.ReadyState
|
||||
*/
|
||||
enum ReadyState {
|
||||
CONNECTING = 0,
|
||||
OPEN,
|
||||
|
@ -100,8 +177,44 @@ public:
|
|||
QScriptValue getOnOpen() { return _onOpenEvent; }
|
||||
|
||||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
* Sends a message on the connection.
|
||||
* @function WebSocket.send
|
||||
* @param {string|object} message - The message to send. If an object, it is converted to a string.
|
||||
*/
|
||||
void send(QScriptValue message);
|
||||
|
||||
/**jsdoc
|
||||
* Closes the connection.
|
||||
* @function WebSocket.close
|
||||
* @param {WebSocket.CloseCode} [closeCode=1000] - The reason for closing.
|
||||
* @param {string} [reason=""] - A description of the reason for closing.
|
||||
*/
|
||||
/**jsdoc
|
||||
* The reason why the connection was closed.
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Name</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>1000</code></td><td>Normal</td><td>Normal closure.</td></tr>
|
||||
* <tr><td><code>1001</code></td><td>GoingAway</td><td>Going away.</td></tr>
|
||||
* <tr><td><code>1002</code></td><td>ProtocolError</td><td>Protocol error.</td></tr>
|
||||
* <tr><td><code>1003</code></td><td>DatatypeNotSupported</td><td>Unsupported data.</td></tr>
|
||||
* <tr><td><code>1004</code></td><td>Reserved1004</td><td>Reserved.</td></tr>
|
||||
* <tr><td><code>1005</code></td><td>MissingStatusCode</td><td>No status received.</td></tr>
|
||||
* <tr><td><code>1006</code></td><td>AbnormalDisconnection</td><td>abnormal closure.</td></tr>
|
||||
* <tr><td><code>1007</code></td><td>WrongDatatype</td><td>Invalid frame payload data.</td></tr>
|
||||
* <tr><td><code>1008</code></td><td>PolicyViolated</td><td>Policy violation.</td></tr>
|
||||
* <tr><td><code>1009</code></td><td>TooMuchData</td><td>Message too big.</td></tr>
|
||||
* <tr><td><code>1010</code></td><td>MissingExtension</td><td>Mandatory extension missing.</td></tr>
|
||||
* <tr><td><code>1011</code></td><td>BadOperation</td><td>Internal server error.</td></tr>
|
||||
* <tr><td><code>1015</code></td><td>TlsHandshakeFailed</td><td>TLS handshake failed.</td></tr>
|
||||
* </tbody>
|
||||
* <table>
|
||||
* @typedef {number} WebSocket.CloseCode
|
||||
*/
|
||||
void close();
|
||||
void close(QWebSocketProtocol::CloseCode closeCode);
|
||||
void close(QWebSocketProtocol::CloseCode closeCode, QString reason);
|
||||
|
|
|
@ -17,6 +17,60 @@
|
|||
#include <QWebSocketServer>
|
||||
#include "WebSocketClass.h"
|
||||
|
||||
/**jsdoc
|
||||
* Manages {@link WebSocket}s in server entity and assignment client scripts.
|
||||
*
|
||||
* @class WebSocketServer
|
||||
*
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
* @property {string} url - The URL that the server is listening on. <em>Read-only.</em>
|
||||
* @property {number} port - The port that the server is listening on. <em>Read-only.</em>
|
||||
* @property {boolean} listening - <code>true</code> if the server is listening for incoming connections, <code>false</code> if
|
||||
* it isn't. <em>Read-only.</em>
|
||||
*
|
||||
* @example <caption>Echo a message back to sender.</caption>
|
||||
* // Server entity script. Echoes received message back to sender.
|
||||
* (function () {
|
||||
* print("Create WebSocketServer");
|
||||
* var webSocketServer = new WebSocketServer();
|
||||
* print("Server url:", webSocketServer.url);
|
||||
*
|
||||
* function onNewConnection(webSocket) {
|
||||
* print("New connection");
|
||||
*
|
||||
* webSocket.onmessage = function (message) {
|
||||
* print("Message received:", message.data);
|
||||
*
|
||||
* var returnMessage = message.data + " back!";
|
||||
* print("Echo a message back:", returnMessage);
|
||||
* webSocket.send(message.data + " back!");
|
||||
* };
|
||||
* }
|
||||
*
|
||||
* webSocketServer.newConnection.connect(onNewConnection);
|
||||
* })
|
||||
*
|
||||
* @example
|
||||
* // Interface script. Bounces message off server entity script.
|
||||
* // Use the server URL reported by the server entity script.
|
||||
* var WEBSOCKET_PING_URL = "ws://127.0.0.1:nnnnn";
|
||||
* var TEST_MESSAGE = "Hello";
|
||||
*
|
||||
* print("Create WebSocket");
|
||||
* var webSocket = new WebSocket(WEBSOCKET_PING_URL);
|
||||
*
|
||||
* webSocket.onmessage = function(data) {
|
||||
* print("Message received:", data.data);
|
||||
* };
|
||||
*
|
||||
* webSocket.onopen = function() {
|
||||
* print("WebSocket opened");
|
||||
* print("Send test message:", TEST_MESSAGE);
|
||||
* webSocket.send(TEST_MESSAGE);
|
||||
* };
|
||||
*/
|
||||
class WebSocketServerClass : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString url READ getURL)
|
||||
|
@ -34,6 +88,11 @@ public:
|
|||
static QScriptValue constructor(QScriptContext* context, QScriptEngine* engine);
|
||||
|
||||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
* Closes all connections and closes the WebSocketServer.
|
||||
* @function WebSocketServer.close
|
||||
*/
|
||||
void close();
|
||||
|
||||
private:
|
||||
|
@ -45,6 +104,13 @@ private slots:
|
|||
void onNewConnection();
|
||||
|
||||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when there is a new connection.
|
||||
* @function WebSocketServer.newConnection
|
||||
* @param {WebSocket} webSocket - The {@link WebSocket} for the new connection.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void newConnection(WebSocketClass* client);
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue