Skip to content

Commit

Permalink
Added Hprose WebSocket Client.
Browse files Browse the repository at this point in the history
  • Loading branch information
andot committed Apr 17, 2015
1 parent ed6dacb commit ee2359b
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 20 deletions.
4 changes: 2 additions & 2 deletions dist/hprose-html5.js

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion src/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* *
* hprose client for HTML5. *
* *
* LastModified: Mar 15, 2015 *
* LastModified: Apr 17, 2015 *
* Author: Ma Bingyao <andot@hprose.com> *
* *
\**********************************************************/
Expand Down Expand Up @@ -708,6 +708,10 @@
parser.protocol === 'https:') {
return new global.hprose.HttpClient(uri, functions);
}
if (parser.protocol === 'ws:' ||
parser.protocol === 'wss:') {
return new global.hprose.WebSocketClient(uri, functions);
}
throw new Exception('The ' + parser.protocol + ' client isn\'t implemented.');
}

Expand Down
21 changes: 10 additions & 11 deletions src/HttpClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,16 @@
* *
* hprose http client for HTML5. *
* *
* LastModified: Mar 15, 2015 *
* LastModified: Apr 17, 2015 *
* Author: Ma Bingyao <andot@hprose.com> *
* *
\**********************************************************/

(function (global) {
'use strict';

var Tags = global.hprose.Tags;
var Exception = global.hprose.Exception;
var Client = global.hprose.Client;
var BytesIO = global.hprose.BytesIO;
var serialize = global.hprose.serialize;
var Completer = global.hprose.Completer;

function noop(){}
Expand All @@ -48,7 +45,7 @@
for (var name in _header) {
xhr.setRequestHeader(name, _header[name]);
}
var timeoutId;
var timeoutId = undefined;
xhr.onload = function () {
xhr.onload = function() {};
if (xhr.status) {
Expand All @@ -71,12 +68,14 @@
}
completer.completeError(new Exception('error'));
};
timeoutId = global.setTimeout(function () {
xhr.onload = function() {};
xhr.onerror = function() {};
xhr.abort();
completer.completeError(new Exception('timeout'));
}, _timeout);
if (_timeout > 0) {
timeoutId = global.setTimeout(function () {
xhr.onload = function() {};
xhr.onerror = function() {};
xhr.abort();
completer.completeError(new Exception('timeout'));
}, _timeout);
}
if (xhr.upload !== undefined) {
xhr.upload.onprogress = _onreqprogress;
}
Expand Down
162 changes: 162 additions & 0 deletions src/WebSocketClient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* WebSocketClient.js *
* *
* hprose websocket client for HTML5. *
* *
* LastModified: Apr 17, 2015 *
* Author: Ma Bingyao <andot@hprose.com> *
* *
\**********************************************************/

(function (global) {
'use strict';

var Exception = global.hprose.Exception;
var Client = global.hprose.Client;
var BytesIO = global.hprose.BytesIO;
var Completer = global.hprose.Completer;

function noop(){}
var s_id = 0;
var s_completers = [];
var s_timeoutId = [];
var s_messages = [];

global.hprose.WebSocketClient = function WebSocketClient(uri, functions) {
Client.call(this, uri, functions);
var _timeout = 0;
var self = this;
var ready = false;
var ws;
function send_message(id, request) {
var bytes = new BytesIO();
bytes.writeByte((id >> 24) & 0xff);
bytes.writeByte((id >> 16) & 0xff);
bytes.writeByte((id >> 8) & 0xff);
bytes.writeByte(id & 0xff);
if (request.constructor === String) {
bytes.writeString(request);
}
else {
bytes.write(request);
}
var message = bytes.bytes;
if (ArrayBuffer.isView) {
ws.send(message);
}
else if (message.buffer.slice) {
ws.send(message.buffer.slice(0, message.length));
}
else {
ws.send(message.buffer);
}
}
function onopen(e) {
ready = true;
if (s_messages.length > 0) {
for (var id in s_messages) {
send_message(id, s_messages[id]);
}
s_messages = [];
}
}
function onmessage(e) {
var bytes = new BytesIO(e.data);
var id = bytes.readByte() << 24;
id = id | bytes.readByte() << 16;
id = id | bytes.readByte() << 8;
id = id | bytes.readByte();
var timeoutId = s_timeoutId[id];
var completer = s_completers[id];
delete s_timeoutId[id];
delete s_completers[id];
if (timeoutId !== undefined) {
global.clearTimeout(timeoutId);
timeoutId = undefined;
}
completer.complete(bytes.read(bytes.length - 4));
}
function onclose(e) {
connect();
}
function onerror(e) {
self.onerror("WebSocket", new Exception(e.data));
}
function connect() {
ready = false;
ws = new WebSocket(self.uri);
ws.binaryType = "arraybuffer";
ws.onopen = onopen;
ws.onmessage = onmessage;
ws.onerror = onerror;
ws.onclose = onclose;
}
function send(request) {
var completer = new Completer();
var timeoutId = undefined;
if (_timeout > 0) {
timeoutId = global.setTimeout((function (id) {
return function() {
delete s_completers[id];
delete s_timeoutId[id];
delete s_messages[id];
ws.close();
completer.completeError(new Exception('timeout'));
}
})(s_id), _timeout);
}
s_completers[s_id] = completer;
s_timeoutId[s_id] = timeoutId;
if (ready) {
send_message(s_id, request);
}
else {
s_messages[s_id] = request;
}
if (s_id < 0x7fffffff) {
++s_id;
}
else {
s_id = 0;
}
return completer.future;
}
function setTimeout(value) {
if (typeof(value) === 'number') {
_timeout = value | 0;
}
else {
_timeout = 0;
}
}
function getTimeout() {
return _timeout;
}
Object.defineProperties(this, {
timeout: { get: getTimeout, set: setTimeout },
__send__: { value: send }
});
connect();
};

function create(uri, functions) {
var parser = document.createElement('a');
parser.href = uri;
if (parser.protocol === 'ws:' ||
parser.protocol === 'wss:') {
return new global.hprose.WebSocketClient(uri, functions);
}
throw new Exception('This client desn\'t support ' + parser.protocol + ' scheme.');
}

Object.defineProperty(global.hprose.WebSocketClient, 'create', { value: create });
})(this);
6 changes: 3 additions & 3 deletions test/Client.Test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

/**********************************************************\
* *
* Writer.Test.js *
* Client.Test.js *
* *
* hprose Writer test for HTML5. *
* hprose Client test for HTML5. *
* *
* LastModified: Mar 15, 2015 *
* LastModified: Apr 17, 2015 *
* Author: Ma Bingyao <andot@hprose.com> *
* *
\**********************************************************/
Expand Down
6 changes: 3 additions & 3 deletions test/Reader.Test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

/**********************************************************\
* *
* Writer.Test.js *
* Reader.Test.js *
* *
* hprose Writer test for HTML5. *
* hprose Reader test for HTML5. *
* *
* LastModified: Mar 28, 2014 *
* LastModified: Apr 17, 2014 *
* Author: Ma Bingyao <andot@hprose.com> *
* *
\**********************************************************/
Expand Down
51 changes: 51 additions & 0 deletions test/WebSocketClient.Test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.org/ |
| |
\**********************************************************/

/**********************************************************\
* *
* WebSocketClient.Test.js *
* *
* hprose websocket client test for HTML5. *
* *
* LastModified: Apr 17, 2015 *
* Author: Ma Bingyao <andot@hprose.com> *
* *
\**********************************************************/

/*global hprose */
/*jshint eqeqeq:true, devel:true */

(function() {
'use strict';
var client = new hprose.Client.create('ws://127.0.0.1:8080');
client.then(function(stub) {
stub.hello('World')
.then(function(result) {
console.info(result);
});
client.beginBatch();
stub.hello('World 1')
.then(function(result) {
console.info(result);
});
stub.hello('World 2')
.then(function(result) {
console.info(result);
});
stub.hello('World 3')
.then(function(result) {
console.info(result);
});
client.endBatch();
})
.catchError(function(e) {
console.error(e);
});

})();
1 change: 1 addition & 0 deletions test/test_dist.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<script type="text/javascript" src="Writer.Test.js"></script>
<script type="text/javascript" src="Reader.Test.js"></script>
<script type="text/javascript" src="Client.Test.js"></script>
<script type="text/javascript" src="WebSocketClient.Test.js"></script>
</head>
<body>

Expand Down
2 changes: 2 additions & 0 deletions test/test_src.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
<script type="text/javascript" src="../src/Formatter.js"></script>
<script type="text/javascript" src="../src/Client.js"></script>
<script type="text/javascript" src="../src/HttpClient.js"></script>
<script type="text/javascript" src="../src/WebSocketClient.js"></script>
<script type="text/javascript" src="HarmonyMaps.Test.js"></script>
<script type="text/javascript" src="BytesIO.Test.js"></script>
<script type="text/javascript" src="Writer.Test.js"></script>
<script type="text/javascript" src="Reader.Test.js"></script>
<script type="text/javascript" src="Client.Test.js"></script>
<script type="text/javascript" src="WebSocketClient.Test.js"></script>
</head>
<body>

Expand Down

0 comments on commit ee2359b

Please sign in to comment.