1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | "use strict";
|
16 |
|
17 | var fluid = require("infusion"),
|
18 | kettle = fluid.registerNamespace("kettle");
|
19 |
|
20 | fluid.require("ws", require, "kettle.npm.ws");
|
21 |
|
22 | fluid.defaults("kettle.test.request.ws", {
|
23 | gradeNames: ["kettle.test.request"],
|
24 | receiveJSON: true,
|
25 | sendJSON: true,
|
26 |
|
27 | webSocketsProtocols: [],
|
28 | invokers: {
|
29 | connect: {
|
30 | funcName: "kettle.test.request.ws.connect",
|
31 | args: ["{that}", "{cookieJar}", "{arguments}.0"]
|
32 | },
|
33 | send: {
|
34 | funcName: "kettle.test.request.ws.send",
|
35 | args: [
|
36 | "{that}",
|
37 | "{arguments}.0",
|
38 | "{arguments}.1"
|
39 | ]
|
40 | },
|
41 | disconnect: {
|
42 | funcName: "kettle.test.request.ws.disconnect",
|
43 | args: "{that}.ws"
|
44 | }
|
45 | },
|
46 | events: {
|
47 | onConnect: null,
|
48 | onReceiveMessage: null,
|
49 | onError: null,
|
50 | onClose: null
|
51 | },
|
52 | listeners: {
|
53 | onDestroy: "{that}.disconnect"
|
54 | }
|
55 | });
|
56 |
|
57 |
|
58 | fluid.defaults("kettle.test.request.wsCookie", {
|
59 | gradeNames: ["kettle.test.request.ws"],
|
60 | storeCookies: true
|
61 | });
|
62 |
|
63 |
|
64 | kettle.test.request.ws.requestOptions = ["protocol", "agent", "headers", "protocolVersion", "hostname", "port", "path", "termMap"];
|
65 |
|
66 | kettle.test.request.ws.connect = function (that, cookieJar, directOptions) {
|
67 | if (that.ws) {
|
68 | fluid.fail("You cannot reuse a kettle.test.request.ws object once it has connected - please construct a fresh component for this request");
|
69 | }
|
70 | var requestOptions = kettle.dataSource.URL.prepareRequestOptions(that.options, cookieJar, directOptions, kettle.test.request.ws.requestOptions, that.resolveUrl);
|
71 |
|
72 | var url = "ws://" + requestOptions.hostname + ":" + requestOptions.port + requestOptions.path;
|
73 | fluid.log("connecting ws.WebSocket to: " + url + " with request options ", requestOptions);
|
74 |
|
75 | that.ws = new kettle.npm.ws(url, that.options.webSocketsProtocols, requestOptions);
|
76 | that.ws.on("open", function () {
|
77 | that.events.onConnect.fire(that);
|
78 | });
|
79 | that.ws.on("unexpected-response", function (req, res) {
|
80 | that.nativeResponse = {
|
81 | statusCode: res.statusCode
|
82 | };
|
83 | that.events.onError.fire(
|
84 | JSON.stringify({statusCode: res.statusCode,
|
85 | isError: true,
|
86 | message: "Unexpected HTTP response where WebSockets response was expected"}), that, res);
|
87 | });
|
88 | that.ws.on("error", function (err) {
|
89 | fluid.log("kettle.test.request.ws client error", err);
|
90 | that.events.onError.fire(that, err);
|
91 | });
|
92 | that.ws.on("message", function (data) {
|
93 | fluid.log("kettle.test.request.ws client message", data);
|
94 | that.events.onReceiveMessage.fire(that.options.receiveJSON ? kettle.JSON.parse(data) : data, that);
|
95 | });
|
96 | that.ws.on("close", function (code, reason) {
|
97 | fluid.log("kettle.test.request.ws closed, response code: ", code, ", reason: ", reason);
|
98 | that.events.onClose.fire(that, {
|
99 | code: code,
|
100 | reason: reason
|
101 | });
|
102 | });
|
103 | };
|
104 |
|
105 | kettle.test.request.ws.disconnect = function (ws) {
|
106 | if (ws) {
|
107 | ws.terminate();
|
108 | }
|
109 | };
|
110 |
|
111 | kettle.test.request.ws.send = function (that, model, directOptions) {
|
112 | if (!that.ws) {
|
113 | fluid.fail("Error in kettle.test.request.ws.send - you must first call connect() on this request object before calling send()");
|
114 | }
|
115 | var togo = fluid.promise();
|
116 | var text = that.options.sendJSON ? JSON.stringify(model) : model;
|
117 | that.ws.send(text, directOptions, function (err) {
|
118 | if (err) {
|
119 | that.events.onError.fire(that, err);
|
120 | togo.reject(err);
|
121 | } else {
|
122 | togo.resolve();
|
123 | }
|
124 | });
|
125 | return togo;
|
126 | };
|