80 lines
1.7 KiB
JavaScript
80 lines
1.7 KiB
JavaScript
"use strict";
|
|
|
|
var makeChannel = require('culvert');
|
|
var wrapHandler = require('../lib/wrap-handler');
|
|
|
|
module.exports = function (proxyUrl) {
|
|
if (proxyUrl[proxyUrl.length - 1] !== "/") proxyUrl += "/";
|
|
|
|
return function connect(host, port, onError) {
|
|
port = port|0;
|
|
host = String(host);
|
|
if (!port || !host) throw new TypeError("host and port are required");
|
|
|
|
onData = wrapHandler(onData, onError);
|
|
|
|
var serverChannel = makeChannel();
|
|
var clientChannel = makeChannel();
|
|
var socket = {
|
|
put: serverChannel.put,
|
|
drain: serverChannel.drain,
|
|
take: clientChannel.take
|
|
};
|
|
|
|
var connected = false;
|
|
var ws = new WebSocket(proxyUrl + "tcp/" + host + "/" + port);
|
|
ws.binaryType = "arraybuffer";
|
|
|
|
ws.onopen = wrap(onOpen, onError);
|
|
ws.onclose = wrap(onClose, onError);
|
|
ws.onmessage = wrap(onMessage, onError);
|
|
ws.onerror = wrap(onWsError, onError);
|
|
|
|
return {
|
|
put: clientChannel.put,
|
|
drain: clientChannel.drain,
|
|
take: serverChannel.take
|
|
};
|
|
|
|
function onOpen() {
|
|
ws.send("connect");
|
|
}
|
|
|
|
function onClose() {
|
|
socket.put();
|
|
}
|
|
|
|
function onMessage(evt) {
|
|
if (!connected && evt.data === "connect") {
|
|
connected = true;
|
|
socket.take(onData);
|
|
return;
|
|
}
|
|
|
|
socket.put(new Uint8Array(evt.data));
|
|
}
|
|
|
|
function onWsError() {
|
|
console.error(arguments);
|
|
throw new Error("Generic websocket error");
|
|
}
|
|
|
|
function onData(chunk) {
|
|
ws.send(chunk.buffer);
|
|
socket.take(onData);
|
|
}
|
|
|
|
};
|
|
};
|
|
|
|
function wrap(fn, onError) {
|
|
return function () {
|
|
try {
|
|
return fn.apply(this, arguments);
|
|
}
|
|
catch (err) {
|
|
onError(err);
|
|
}
|
|
};
|
|
}
|