Skip to content

Commit e0dd960

Browse files
authored
Merge pull request #4 from oxygens/master
Made websockets work in the browser and made the node code compatible with browser exported code.
2 parents 0bf398b + 0171d68 commit e0dd960

File tree

15 files changed

+235
-105
lines changed

15 files changed

+235
-105
lines changed

.vscode/settings.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Place your settings in this file to overwrite default and user settings.
2+
{
3+
// Configure glob patterns for excluding files and folders.
4+
"files.exclude": {
5+
"**/.git": true,
6+
"**/.svn": true,
7+
"**/.hg": true,
8+
"**/CVS": true,
9+
"**/.DS_Store": true,
10+
"*.min.js": true,
11+
"*.js.map": true
12+
}
13+
}

README.MD

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
[![Version npm](https://img.shields.io/npm/v/ws.svg)](https://www.npmjs.com/package/jsonrpc-bidirectional)
44
[![Build Status](https://travis-ci.org/oxygens/jsonrpc-bidirectional.svg?branch=master)](https://travis-ci.org/oxygens/jsonrpc-bidirectional)
55

6-
A main goal of this project is to have the JSONRPC server and client support __bidirectional JSON-RPC requests over a single WebSocket connection.__
6+
A main goal of this project is to have the JSON-RPC server and client support __bidirectional JSON-RPC requests over a single WebSocket connection.__
77

8-
Both the server and client support two __transports, HTTP and WebSocket__ ([websockets/ws](https://github.com/websockets/ws) compatible API), and allow more through plugin extensibility.
8+
This library is tested in __browsers__ (at least Internet Explorer 10) and in __Node.js__ (at least 7.8, or 7.x with the --harmony flag.).
9+
10+
Both the server and client support two __transports, HTTP and WebSocket__, and allow more through plugin extensibility.
11+
12+
For WebSocket client support it expects W3C compatible WebSocket class instances (browser `WebSocket` and Node.js [websockets/ws](https://github.com/websockets/ws) `WebSocket`). On the Node.js side it is tested to work with [websockets/ws](https://github.com/websockets/ws). `WebSocketServer` implementations are supported only if 100% API compatible with `websockets/ws`, or made compatible through an adapter.
913

1014
Plugins are allowed to replace the JSON-RPC protocol altogether, extend the protocol or wrap it.
1115

builds/browser/es5/jsonrpc.js

Lines changed: 0 additions & 8 deletions
This file was deleted.

builds/browser/es5/jsonrpc.js.map

Lines changed: 0 additions & 1 deletion
This file was deleted.

builds/browser/es5/jsonrpc.min.js

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builds/browser/es5/jsonrpc.min.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index_webpack.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
11
// Do not use const here, webpack/babel issues.
2-
var objExports = {
2+
module.exports = {
33
JSONRPC: require("./index")
44
};
5-
6-
delete objExports.JSONRPC.Plugins.Client.WebSocketTransport;
7-
delete objExports.JSONRPC.Plugins.Client.ProcessStdIOTransport;
8-
9-
module.exports = objExports;

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "jsonrpc-bidirectional",
33
"description": "Bidirectional JSONRPC over web sockets or HTTP with extensive plugin support.",
4-
"version": "2.1.3",
4+
"version": "2.1.11",
55
"scripts": {
66
"build": "node build.js",
77
"test": "node tests/main.js",
@@ -37,7 +37,6 @@
3737
},
3838
"dependencies": {
3939
"crypto-js": "^3.1.9-1",
40-
"jssha": "^2.2.0",
4140
"node-fetch": "^1.6.3",
4241
"ws": "^2.2.3"
4342
},
@@ -57,5 +56,9 @@
5756
"phantom": "^4.0.2",
5857
"webpack": "*",
5958
"sleep-promise": "*"
59+
},
60+
"optionalDependencies": {
61+
"bufferutil": "^3.0.0",
62+
"utf-8-validate": "^3.0.1"
6063
}
61-
}
64+
}

src/BidirectionalWebsocketRouter.js

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ JSONRPC.Utils = require("./Utils");
1212

1313
const EventEmitter = require("events");
1414

15+
const WebSocket = require("ws");
16+
1517

1618
/**
1719
* The "madeReverseCallsClient" event offers automatically instantiated API clients (API clients are instantiated for each connection, lazily).
@@ -57,7 +59,7 @@ class BidirectionalWebsocketRouter extends EventEmitter
5759
*/
5860
async addWebSocket(webSocket)
5961
{
60-
if(webSocket.readyState === webSocket.constructor.CLOSED)
62+
if(webSocket.readyState === WebSocket.CLOSED)
6163
{
6264
// WebSocket.CLOSING should be followed by a closed event.
6365
// WebSocket.OPEN is desired.
@@ -81,33 +83,37 @@ class BidirectionalWebsocketRouter extends EventEmitter
8183

8284
this._objSessions[nWebSocketConnectionID] = objSession;
8385

84-
webSocket.on(
86+
webSocket.addEventListener(
8587
"close",
86-
(code, message) => {
88+
(closeEvent) => {
89+
//closeEvent.code;
90+
//closeEvent.reason;
91+
//closeEvent.wasClean;
92+
8793
delete this._objSessions[nWebSocketConnectionID];
8894
}
8995
);
9096

91-
webSocket.on(
97+
webSocket.addEventListener(
9298
"error",
9399
(error) => {
94100
delete this._objSessions[nWebSocketConnectionID];
95101

96-
if(webSocket.readyState === webSocket.constructor.OPEN)
102+
if(webSocket.readyState === WebSocket.OPEN)
97103
{
98104
webSocket.close(
99-
/* CloseEvent.Internal Error */ 1011,
105+
/*CLOSE_NORMAL*/ 1000, // Chrome only supports 1000 or the 3000-3999 range ///* CloseEvent.Internal Error */ 1011,
100106
error.message
101107
);
102108
}
103109
}
104110
);
105111

106-
webSocket.on(
112+
webSocket.addEventListener(
107113
"message",
108-
async (strMessage) =>
114+
async (messageEvent) =>
109115
{
110-
await this._routeMessage(strMessage, objSession);//.then(() => {}).catch(console.error);
116+
await this._routeMessage(messageEvent.data, objSession);//.then(() => {}).catch(console.error);
111117
}
112118
);
113119

@@ -222,7 +228,7 @@ class BidirectionalWebsocketRouter extends EventEmitter
222228

223229
console.log("[" + process.pid + "] Unclean state. Unable to match WebSocket message to an existing Promise or qualify it as a request or response.");
224230
webSocket.close(
225-
/* CloseEvent.Internal Error */ 1011,
231+
/*CLOSE_NORMAL*/ 1000, // Chrome only supports 1000 or the 3000-3999 range ///* CloseEvent.Internal Error */ 1011,
226232
"Unclean state. Unable to match WebSocket message to an existing Promise or qualify it as a request or response."
227233
);
228234

@@ -235,7 +241,7 @@ class BidirectionalWebsocketRouter extends EventEmitter
235241
{
236242
if(!this._jsonrpcServer)
237243
{
238-
if(webSocket.readyState === webSocket.constructor.OPEN)
244+
if(webSocket.readyState === WebSocket.OPEN)
239245
{
240246
webSocket.send(JSON.stringify({
241247
id: null,
@@ -290,7 +296,7 @@ class BidirectionalWebsocketRouter extends EventEmitter
290296

291297
await this._jsonrpcServer.processRequest(incomingRequest);
292298

293-
if(webSocket.readyState !== webSocket.constructor.OPEN)
299+
if(webSocket.readyState !== WebSocket.OPEN)
294300
{
295301
console.error("webSocket.readyState: " + JSON.stringify(webSocket.readyState) + ". Request was " + strMessage + ". Attempted responding with " + JSON.stringify(incomingRequest.callResultToBeSerialized, undefined, "\t") + ".");
296302
}
@@ -306,7 +312,7 @@ class BidirectionalWebsocketRouter extends EventEmitter
306312
{
307313
if(!this._jsonrpcServer)
308314
{
309-
if(webSocket.readyState === webSocket.constructor.OPEN)
315+
if(webSocket.readyState === WebSocket.OPEN)
310316
{
311317
webSocket.send(JSON.stringify({
312318
id: null,
@@ -319,10 +325,10 @@ class BidirectionalWebsocketRouter extends EventEmitter
319325
}
320326
}
321327

322-
if(webSocket.readyState === webSocket.constructor.OPEN)
328+
if(webSocket.readyState === WebSocket.OPEN)
323329
{
324330
webSocket.close(
325-
/* CloseEvent.Internal Error */ 1011,
331+
/*CLOSE_NORMAL*/ 1000, // Chrome only supports 1000 or the 3000-3999 range ///* CloseEvent.Internal Error */ 1011,
326332
"How can the client be not initialized, and yet getting responses from phantom requests? Closing websocket."
327333
);
328334
}
@@ -355,7 +361,7 @@ class BidirectionalWebsocketRouter extends EventEmitter
355361
&& this._objSessions[nWebSocketConnectionID].clientWebSocketTransportPlugin === null
356362
)
357363
{
358-
if(webSocket.readyState === webSocket.constructor.OPEN)
364+
if(webSocket.readyState === WebSocket.OPEN)
359365
{
360366
webSocket.send(JSON.stringify({
361367
id: null,
@@ -368,11 +374,11 @@ class BidirectionalWebsocketRouter extends EventEmitter
368374
}
369375
}
370376

371-
if(webSocket.readyState === webSocket.constructor.OPEN)
377+
if(webSocket.readyState === WebSocket.OPEN)
372378
{
373379
console.log("[" + process.pid + "] Unclean state. Closing websocket.");
374380
webSocket.close(
375-
/* CloseEvent.Internal Error */ 1011,
381+
/*CLOSE_NORMAL*/ 1000, // Chrome only supports 1000 or the 3000-3999 range ///* CloseEvent.Internal Error */ 1011,
376382
"Unclean state. Closing websocket."
377383
);
378384
}

src/Plugins/Client/WebSocketTransport.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ JSONRPC.Utils = require("../../Utils");
44

55
const assert = require("assert");
66

7+
const WebSocket = require("ws");
8+
9+
710
module.exports =
811
class WebSocketTransport extends JSONRPC.ClientPluginBase
912
{
@@ -57,7 +60,7 @@ class WebSocketTransport extends JSONRPC.ClientPluginBase
5760
console.error(error);
5861
console.error("Unable to parse JSON. RAW remote response: " + strResponse);
5962
this._webSocket.close(
60-
/* CloseEvent.Internal Error */ 1011,
63+
/*CLOSE_NORMAL*/ 1000, // Chrome only supports 1000 or the 3000-3999 range ///* CloseEvent.Internal Error */ 1011,
6164
"Unable to parse JSON. RAW remote response: " + strResponse
6265
);
6366

@@ -74,7 +77,7 @@ class WebSocketTransport extends JSONRPC.ClientPluginBase
7477
console.error(new Error("RAW remote message: " + strResponse));
7578
console.log("[" + process.pid + "] Unclean state. Unable to match WebSocket message to an existing Promise or qualify it as a request.");
7679
this.webSocket.close(
77-
/* CloseEvent.Internal Error */ 1011,
80+
/*CLOSE_NORMAL*/ 1000, // Chrome only supports 1000 or the 3000-3999 range ///* CloseEvent.Internal Error */ 1011,
7881
"Unclean state. Unable to match WebSocket message to an existing Promise or qualify it as a request."
7982
);
8083

@@ -105,7 +108,7 @@ class WebSocketTransport extends JSONRPC.ClientPluginBase
105108
return;
106109
}
107110

108-
if(this.webSocket.readyState !== this.webSocket.constructor.OPEN)
111+
if(this.webSocket.readyState !== WebSocket.OPEN)
109112
{
110113
throw new Error("WebSocket not connected.");
111114
}
@@ -161,14 +164,14 @@ class WebSocketTransport extends JSONRPC.ClientPluginBase
161164
{
162165
//assert(webSocket.constructor.name === "WebSocket");
163166

164-
this._webSocket.on(
167+
this._webSocket.addEventListener(
165168
"close",
166-
(code, message) => {
167-
this.rejectAllPromises(new Error("WebSocket closed. Code: " + JSON.stringify(code) + ". Message: " + JSON.stringify(message) + "."));
169+
(closeEvent) => {
170+
this.rejectAllPromises(new Error("WebSocket closed. Code: " + JSON.stringify(closeEvent.code) + ". Message: " + JSON.stringify(closeEvent.reason) + ". wasClean: " + JSON.stringify(closeEvent.wasClean)));
168171
}
169172
);
170173

171-
this._webSocket.on(
174+
this._webSocket.addEventListener(
172175
"error",
173176
(error) => {
174177
this.rejectAllPromises(error);
@@ -177,10 +180,10 @@ class WebSocketTransport extends JSONRPC.ClientPluginBase
177180

178181
if(!this._bBidirectionalWebSocketMode)
179182
{
180-
this._webSocket.on(
183+
this._webSocket.addEventListener(
181184
"message",
182-
async (strMessage) => {
183-
await this.processResponse(strMessage);
185+
async (messageEvent) => {
186+
await this.processResponse(messageEvent.data);
184187
}
185188
);
186189
}

0 commit comments

Comments
 (0)