|
|
@@ -0,0 +1,161 @@
|
|
|
+
|
|
|
+/**
|
|
|
+ * @abstract
|
|
|
+ * @constructor
|
|
|
+**/
|
|
|
+function AbstractRawTCPSocket() {
|
|
|
+ /** @type {Array<function(string)>} */
|
|
|
+ this.onReadyReadHandlers = [];
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @abstract
|
|
|
+ * @return {Promise}
|
|
|
+**/
|
|
|
+AbstractRawTCPSocket.prototype.connect = function() {};
|
|
|
+
|
|
|
+/**
|
|
|
+ * @abstract
|
|
|
+ * @param {string} msg
|
|
|
+**/
|
|
|
+AbstractRawTCPSocket.prototype.write = function(msg) {};
|
|
|
+
|
|
|
+/**
|
|
|
+ * @param {function(string)} onReadyRead
|
|
|
+**/
|
|
|
+AbstractRawTCPSocket.prototype.onReadyRead = function(onReadyRead) {
|
|
|
+ this.onReadyReadHandlers.push(onReadyRead);
|
|
|
+};
|
|
|
+
|
|
|
+/** @param {string} msg */
|
|
|
+AbstractRawTCPSocket.prototype.triggerOnReadyRead = function(msg) {
|
|
|
+ this.onReadyReadHandlers.forEach(function(handler) {
|
|
|
+ handler(msg);
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+AbstractRawTCPSocket.prototype.close = function() {};
|
|
|
+
|
|
|
+//
|
|
|
+// This API is not available yet
|
|
|
+// https://www.w3.org/TR/raw-sockets/
|
|
|
+//
|
|
|
+///**
|
|
|
+// * @constructor
|
|
|
+// * @extends {AbstractRawTCPSocket}
|
|
|
+// * @param {string} address
|
|
|
+// * @param {number} port
|
|
|
+//**/
|
|
|
+//function NavigatorRawTCPSocket(address, port) {
|
|
|
+// AbstractRawTCPSocket.apply(this);
|
|
|
+//
|
|
|
+// /** @type {string} */
|
|
|
+// this.address = address;
|
|
|
+//
|
|
|
+// /** @type {number} */
|
|
|
+// this.port = port;
|
|
|
+//}
|
|
|
+//
|
|
|
+//NavigatorRawTCPSocket.prototype = Object.create(AbstractRawTCPSocket);
|
|
|
+//NavigatorRawTCPSocket.prototype.constructor = NavigatorRawTCPSocket;
|
|
|
+//
|
|
|
+//NavigatorRawTCPSocket.prototype.checkPermission = function() {
|
|
|
+// return navigator.tcpPermission.requestPermission({ remoteAddress: this.address, remotePort: this.port });
|
|
|
+//};
|
|
|
+//
|
|
|
+//NavigatorRawTCPSocket.prototype.connect = function() {
|
|
|
+// this.sock = navigator.TCPSocket(this.address, this.port)
|
|
|
+//};
|
|
|
+//
|
|
|
+//NavigatorRawTCPSocket.prototype.write = function(str) {
|
|
|
+//};
|
|
|
+//
|
|
|
+//NavigatorRawTCPSocket.prototype.close = function() {
|
|
|
+//};
|
|
|
+
|
|
|
+/**
|
|
|
+ * @constructor
|
|
|
+ * @extends {AbstractRawTCPSocket}
|
|
|
+ * @param {string} address
|
|
|
+ * @param {number} port
|
|
|
+**/
|
|
|
+function NativeRawTCPSocket(address, port) {
|
|
|
+ AbstractRawTCPSocket.apply(this);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @const
|
|
|
+ * @type {number}
|
|
|
+ **/
|
|
|
+ this.socketId = NativeRawTCPSocket.sockCount++;
|
|
|
+
|
|
|
+ NativeRawTCPSocket.sockets[this.socketId] = this;
|
|
|
+
|
|
|
+ /** @type {string} */
|
|
|
+ this.address = address;
|
|
|
+
|
|
|
+ /** @type {number} */
|
|
|
+ this.port = port;
|
|
|
+
|
|
|
+ /** @type {{ onSuccess: function(), onReject: function() }|null} */
|
|
|
+ this.connectPromise;
|
|
|
+}
|
|
|
+
|
|
|
+NativeRawTCPSocket.prototype = Object.create(AbstractRawTCPSocket);
|
|
|
+NativeRawTCPSocket.prototype.constructor = NativeRawTCPSocket;
|
|
|
+
|
|
|
+/** @return {Promise} */
|
|
|
+NativeRawTCPSocket.prototype.connect = function() {
|
|
|
+ return new Promise(function(onSuccess, onReject) {
|
|
|
+ this.connectPromise = {
|
|
|
+ onSuccess: onSuccess,
|
|
|
+ onReject: onReject
|
|
|
+ };
|
|
|
+ __native.TCPConnect(this.socketId, this.address, this.port);
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+/** @param {boolean} success */
|
|
|
+NativeRawTCPSocket.prototype.onConnected = function(success) {
|
|
|
+ if (this.connectPromise) {
|
|
|
+ if (success)
|
|
|
+ this.connectPromise.onSuccess();
|
|
|
+ else
|
|
|
+ this.connectPromise.onReject();
|
|
|
+ this.connectPromise = null;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** @param {string} msg */
|
|
|
+NativeRawTCPSocket.prototype.write = function(msg) {
|
|
|
+ __native.TCPWrite(this.socketId, msg);
|
|
|
+};
|
|
|
+
|
|
|
+NativeRawTCPSocket.prototype.close = function() {
|
|
|
+ __native.TCPClose(this.socketId);
|
|
|
+};
|
|
|
+
|
|
|
+/** @type {number} */
|
|
|
+NativeRawTCPSocket.sockCount = 0;
|
|
|
+NativeRawTCPSocket.sockets = {};
|
|
|
+
|
|
|
+NativeRawTCPSocket.onConnected = function(sockId, success) {
|
|
|
+ NativeRawTCPSocket.sockets[sockId].onConnected(success);
|
|
|
+};
|
|
|
+
|
|
|
+NativeRawTCPSocket.onReadyRead = function(sockId, msg) {
|
|
|
+ NativeRawTCPSocket.sockets[sockId].triggerOnReadyRead(msg);
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * @param {string} address
|
|
|
+ * @param {number} port
|
|
|
+ * @return {AbstractRawTCPSocket|null}
|
|
|
+**/
|
|
|
+function createSocket(address, port) {
|
|
|
+ if (isNative())
|
|
|
+ return new NativeRawTCPSocket(address, port);
|
|
|
+// else if (navigator && "tcpPermission" in navigator)
|
|
|
+// return new NavigatorRawTCPSocket(address, port);
|
|
|
+ return null; // unsupported
|
|
|
+}
|
|
|
+
|