sockets-for-cordova/socket.js

221 lines
6.6 KiB
JavaScript

cordova.define("cordova-plugin-socket-tcp.Socket", function(require, exports, module) {
/**
* Copyright (c) 2015, Blocshop s.r.o.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the Blocshop s.r.o.. The name of the
* Blocshop s.r.o. may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
var exec = require('cordova/exec');
var SOCKET_EVENT = "SOCKET_EVENT";
var CORDOVA_SERVICE_NAME = "SocketsForCordova";
Socket.State = {};
Socket.State[Socket.State.CLOSED = 0] = "CLOSED";
Socket.State[Socket.State.OPENING = 1] = "OPENING";
Socket.State[Socket.State.OPENED = 2] = "OPENED";
Socket.State[Socket.State.CLOSING = 3] = "CLOSING";
Socket.ErrorType = {};
Socket.ErrorType[Socket.ErrorType.GENERAL = 0] = "general";
Socket.ErrorType[Socket.ErrorType.OPEN_TIMEOUT = 1] = "openTimeout";
Socket.ErrorType[Socket.ErrorType.WRITE_TIMEOUT = 2] = "writeTimeout";
function Socket() {
this._state = Socket.State.CLOSED;
this.onData = null;
this.onClose = null;
this.onError = null;
this.socketKey = guid();
}
Socket.prototype.open = function (host, port, success, error) {
success = success || function() { };
error = error || function() { };
if (!this._ensureState(Socket.State.CLOSED, error)) {
return;
}
var _that = this;
function socketEventHandler(event) {
var payload = event.payload;
if (payload.socketKey !== _that.socketKey) {
return;
}
switch (payload.type) {
case "Close":
_that._state = Socket.State.CLOSED;
window.document.removeEventListener(SOCKET_EVENT, socketEventHandler);
_that.onClose(payload.hasError);
break;
case "DataReceived":
_that.onData(new Uint8Array(payload.data));
break;
case "Error":
_that.onError(payload);
break;
default:
console.error("SocketsForCordova: Unknown event type " + payload.type + ", socket key: " + payload.socketKey);
break;
}
}
_that._state = Socket.State.OPENING;
exec(
function () {
_that._state = Socket.State.OPENED;
window.document.addEventListener(SOCKET_EVENT, socketEventHandler);
success();
},
function(errorMessage) {
_that._state = Socket.State.CLOSED;
error(errorMessage);
},
CORDOVA_SERVICE_NAME,
"open",
[ this.socketKey, host, port ]);
};
Socket.prototype.write = function (data, success, error) {
success = success || function() { };
error = error || function() { };
if (!this._ensureState(Socket.State.OPENED, error)) {
return;
}
var dataToWrite = data instanceof Uint8Array
? Socket._copyToArray(data)
: data;
exec(
success,
error,
CORDOVA_SERVICE_NAME,
"write",
[ this.socketKey, dataToWrite ]);
};
Socket.prototype.shutdownWrite = function (success, error) {
success = success || function() { };
error = error || function() { };
if (!this._ensureState(Socket.State.OPENED, error)) {
return;
}
exec(
success,
error,
CORDOVA_SERVICE_NAME,
"shutdownWrite",
[ this.socketKey ]);
};
Socket.prototype.close = function (success, error) {
success = success || function() { };
error = error || function() { };
if (!this._ensureState(Socket.State.OPENED, error)) {
return;
}
this._state = Socket.State.CLOSING;
exec(
success,
error,
CORDOVA_SERVICE_NAME,
"close",
[ this.socketKey ]);
};
Object.defineProperty(Socket.prototype, "state", {
get: function () {
return this._state;
},
enumerable: true,
configurable: true
});
Socket.prototype._ensureState = function(requiredState, errorCallback) {
var state = this._state;
if (state != requiredState) {
window.setTimeout(function() {
errorCallback("Invalid operation for this socket state: " + Socket.State[state]);
});
return false;
}
else {
return true;
}
};
Socket.dispatchEvent = function (event) {
var eventReceive = document.createEvent('Events');
eventReceive.initEvent(SOCKET_EVENT, true, true);
eventReceive.payload = event;
document.dispatchEvent(eventReceive);
};
Socket._copyToArray = function (array) {
var outputArray = new Array(array.length);
for (var i = 0; i < array.length; i++) {
outputArray[i] = array[i];
}
return outputArray;
};
var guid = (function () {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return function () {
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
};
})();
// Register event dispatcher for Windows Phone
if (navigator.userAgent.match(/iemobile/i)) {
window.document.addEventListener("deviceready", function () {
exec(
Socket.dispatchEvent,
function (errorMessage) {
console.error("SocketsForCordova: Cannot register WP event dispatcher, Error: " + errorMessage);
},
CORDOVA_SERVICE_NAME,
"registerWPEventDispatcher",
[ ]);
});
}
module.exports = Socket;
});