1 | (function() {
|
2 | var Client, Linda, Tuple, TupleSpace, debug, events, fs, http, path, socketio, url,
|
3 | __hasProp = {}.hasOwnProperty,
|
4 | __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
5 |
|
6 | http = require('http');
|
7 |
|
8 | path = require('path');
|
9 |
|
10 | url = require('url');
|
11 |
|
12 | fs = require('fs');
|
13 |
|
14 | events = require('eventemitter2');
|
15 |
|
16 | socketio = require('socket.io');
|
17 |
|
18 | debug = require('debug')('linda');
|
19 |
|
20 | TupleSpace = require(path.join(__dirname, 'tuplespace'));
|
21 |
|
22 | Tuple = require(path.join(__dirname, 'tuple'));
|
23 |
|
24 | Client = require(path.join(__dirname, 'linda-client'));
|
25 |
|
26 | module.exports.TupleSpace = TupleSpace;
|
27 |
|
28 | module.exports.Tuple = Tuple;
|
29 |
|
30 | module.exports.Client = Client;
|
31 |
|
32 | Linda = (function(_super) {
|
33 | __extends(Linda, _super);
|
34 |
|
35 | function Linda() {
|
36 | this.spaces = {};
|
37 | fs.readFile(path.join(__dirname, 'linda-client.js'), (function(_this) {
|
38 | return function(err, data) {
|
39 | if (err) {
|
40 | throw new Error("client js load error");
|
41 | }
|
42 | return _this.client_js_code = data;
|
43 | };
|
44 | })(this));
|
45 | setInterval((function(_this) {
|
46 | return function() {
|
47 | var name, space, _ref;
|
48 | debug("TupleSpace\tcheck expire");
|
49 | _ref = _this.spaces;
|
50 | for (name in _ref) {
|
51 | space = _ref[name];
|
52 | if (space != null) {
|
53 | space.check_expire();
|
54 | }
|
55 | }
|
56 | return debug("TupleSpace\tcheck expire done");
|
57 | };
|
58 | })(this), 60 * 3 * 1000);
|
59 | }
|
60 |
|
61 | Linda.prototype.tuplespace = function(name) {
|
62 | return this.spaces[name] || (this.spaces[name] = new TupleSpace(name));
|
63 | };
|
64 |
|
65 | Linda.prototype.listen = function(opts) {
|
66 | if (opts == null) {
|
67 | opts = {
|
68 | io: null,
|
69 | server: null
|
70 | };
|
71 | }
|
72 | if (opts.io == null) {
|
73 | throw new Error('"io" must be instance of Socket.IO');
|
74 | }
|
75 | if (!(opts.server instanceof http.Server)) {
|
76 | throw new Error('"server" must be instance of http.Server');
|
77 | }
|
78 | this.io = opts.io;
|
79 | this.server = opts.server;
|
80 | this.oldListeners = this.server.listeners('request').splice(0);
|
81 | this.server.removeAllListeners('request');
|
82 | this.server.on('request', (function(_this) {
|
83 | return function(req, res) {
|
84 | var listener, _i, _len, _ref, _results, _url;
|
85 | _url = url.parse(decodeURI(req.url), true);
|
86 | if (_url.pathname === "/linda/linda.js") {
|
87 | debug("GET\t" + _url.pathname);
|
88 | res.setHeader('Content-Type', 'application/javascript');
|
89 | res.writeHead(200);
|
90 | res.end(_this.client_js_code);
|
91 | return;
|
92 | }
|
93 | _ref = _this.oldListeners;
|
94 | _results = [];
|
95 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
96 | listener = _ref[_i];
|
97 | _results.push(listener.call(_this.server, req, res));
|
98 | }
|
99 | return _results;
|
100 | };
|
101 | })(this));
|
102 | this.io.sockets.on('connection', (function(_this) {
|
103 | return function(socket) {
|
104 | var cids, info, watch_cids;
|
105 | cids = {};
|
106 | info = {
|
107 | from: socket.handshake.headers['x-forwarded-for'] || socket.handshake.address.address
|
108 | };
|
109 | socket.on('__linda_write', function(data) {
|
110 | var _ref;
|
111 | if ((_ref = data.options) != null) {
|
112 | _ref.from = info.from;
|
113 | }
|
114 | _this.tuplespace(data.tuplespace).write(data.tuple, data.options);
|
115 | debug("write\t" + (JSON.stringify(data)) + " from " + info.from);
|
116 | return _this.emit('write', data);
|
117 | });
|
118 | socket.on('__linda_take', function(data) {
|
119 | var cid;
|
120 | cid = _this.tuplespace(data.tuplespace).take(data.tuple, function(err, tuple) {
|
121 | cid = null;
|
122 | return socket.emit("__linda_take_" + data.id, err, tuple);
|
123 | });
|
124 | cids[data.id] = cid;
|
125 | debug("take\t" + (JSON.stringify(data)) + " from " + info.from);
|
126 | _this.emit('take', data);
|
127 | return socket.once('disconnect', function() {
|
128 | if (cid) {
|
129 | return _this.tuplespace(data.tuplespace).cancel(cid);
|
130 | }
|
131 | });
|
132 | });
|
133 | socket.on('__linda_read', function(data) {
|
134 | var cid;
|
135 | cid = _this.tuplespace(data.tuplespace).read(data.tuple, function(err, tuple) {
|
136 | cid = null;
|
137 | return socket.emit("__linda_read_" + data.id, err, tuple);
|
138 | });
|
139 | cids[data.id] = cid;
|
140 | debug("read\t" + (JSON.stringify(data)) + " from " + info.from);
|
141 | _this.emit('read', data);
|
142 | return socket.once('disconnect', function() {
|
143 | if (cid) {
|
144 | return _this.tuplespace(data.tuplespace).cancel(cid);
|
145 | }
|
146 | });
|
147 | });
|
148 | watch_cids = {};
|
149 | socket.on('__linda_watch', function(data) {
|
150 | var cid;
|
151 | debug("watch\t" + (JSON.stringify(data)) + " from " + info.from);
|
152 | _this.emit('watch', data);
|
153 | if (watch_cids[data.id]) {
|
154 | return;
|
155 | }
|
156 | watch_cids[data.id] = true;
|
157 | cid = _this.tuplespace(data.tuplespace).watch(data.tuple, function(err, tuple) {
|
158 | return socket.emit("__linda_watch_" + data.id, err, tuple);
|
159 | });
|
160 | cids[data.id] = cid;
|
161 | return socket.once('disconnect', function() {
|
162 | if (cid) {
|
163 | return _this.tuplespace(data.tuplespace).cancel(cid);
|
164 | }
|
165 | });
|
166 | });
|
167 | return socket.on('__linda_cancel', function(data) {
|
168 | debug("cancel\t" + (JSON.stringify(data)) + " from " + info.from);
|
169 | _this.emit('cancel', data);
|
170 | _this.tuplespace(data.tuplespace).cancel(cids[data.id]);
|
171 | return watch_cids[data.id] = false;
|
172 | });
|
173 | };
|
174 | })(this));
|
175 | return this;
|
176 | };
|
177 |
|
178 | return Linda;
|
179 |
|
180 | })(events.EventEmitter2);
|
181 |
|
182 | module.exports.Linda = new Linda;
|
183 |
|
184 | }).call(this);
|