not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

223 lines
5.7 KiB

define(["sugar-web/env"], function (env) {
'use strict';
var lastId = 0;
var callbacks = {};
var notificationCallbacks = {};
var client = null;
var inputStreams = [];
function WebSocketClient(environment) {
this.queue = [];
this.socket = null;
var that = this;
env.getEnvironment(function (error, environment) {
var port = environment.apiSocketPort;
var socket = new WebSocket("ws://localhost:" + port);
socket.binaryType = "arraybuffer";
socket.onopen = function () {
var params = [environment.activityId,
environment.apiSocketKey];
socket.send(JSON.stringify({
"method": "authenticate",
"id": "authenticate",
"params": params
}));
while (that.queue.length > 0) {
socket.send(that.queue.shift());
}
};
socket.onmessage = function (message) {
that.onMessage(message);
};
that.socket = socket;
});
}
WebSocketClient.prototype.send = function (data) {
if (this.socket && this.socket.readyState == WebSocket.OPEN) {
this.socket.send(data);
} else {
this.queue.push(data);
}
};
WebSocketClient.prototype.close = function () {
this.socket.close();
};
var bus = {};
function InputStream() {
this.streamId = null;
this.readCallback = null;
}
InputStream.prototype.open = function (callback) {
var that = this;
bus.sendMessage("open_stream", [], function (error, result) {
that.streamId = result[0];
inputStreams[that.streamId] = that;
callback(error);
});
};
InputStream.prototype.read = function (count, callback) {
if (this.readCallback) {
throw new Error("Read already in progress");
}
this.readCallback = callback;
var buffer = new ArrayBuffer(8);
var headerView = new Uint8Array(buffer, 0, 1);
headerView[0] = this.streamId;
var bodyView = new Uint32Array(buffer, 4, 1);
bodyView[0] = count;
bus.sendBinary(buffer);
};
InputStream.prototype.gotData = function (buffer) {
var callback = this.readCallback;
this.readCallback = null;
callback(null, buffer);
};
InputStream.prototype.close = function (callback) {
var that = this;
function onStreamClosed(error, result) {
if (callback) {
callback(error);
}
delete inputStreams[that.streamId];
}
bus.sendMessage("close_stream", [this.streamId], onStreamClosed);
};
function OutputStream() {
this.streamId = null;
}
OutputStream.prototype.open = function (callback) {
var that = this;
bus.sendMessage("open_stream", [], function (error, result) {
that.streamId = result[0];
callback(error);
});
};
OutputStream.prototype.write = function (data) {
var buffer = new ArrayBuffer(data.byteLength + 1);
var bufferView = new Uint8Array(buffer);
bufferView[0] = this.streamId;
bufferView.set(new Uint8Array(data), 1);
bus.sendBinary(buffer);
};
OutputStream.prototype.close = function (callback) {
bus.sendMessage("close_stream", [this.streamId], callback);
};
bus.createInputStream = function (callback) {
return new InputStream();
};
bus.createOutputStream = function (callback) {
return new OutputStream();
};
bus.sendMessage = function (method, params, callback) {
var message = {
"method": method,
"id": lastId,
"params": params,
"jsonrpc": "2.0"
};
if (callback) {
callbacks[lastId] = callback;
}
client.send(JSON.stringify(message));
lastId++;
};
bus.onNotification = function (method, callback) {
notificationCallbacks[method] = callback;
};
bus.sendBinary = function (buffer, callback) {
client.send(buffer);
};
bus.listen = function (customClient) {
if (customClient) {
client = customClient;
} else {
client = new WebSocketClient();
}
client.onMessage = function (message) {
if (typeof message.data != "string") {
var dataView = new Uint8Array(message.data);
var streamId = dataView[0];
if (streamId in inputStreams) {
var inputStream = inputStreams[streamId];
inputStream.gotData(message.data.slice(1));
}
return;
}
var parsed = JSON.parse(message.data);
var responseId = parsed.id;
if (parsed.method) {
var notificationCallback = notificationCallbacks[parsed.method];
if (notificationCallback !== undefined) {
notificationCallback(parsed.params);
}
return;
}
if (responseId in callbacks) {
var callback = callbacks[responseId];
if (parsed.error === null) {
callback(null, parsed.result);
} else {
callback(new Error(parsed.error), null);
}
delete callbacks[responseId];
}
};
};
bus.close = function () {
client.close();
client = null;
};
return bus;
});