1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 define("mojo/public/js/bindings/router", [
6 "mojo/public/js/bindings/codec",
7 "mojo/public/js/bindings/connector",
8 ], function(codec, connector) {
10 function Router(handle) {
11 this.connector_ = new connector.Connector(handle);
12 this.incomingReceiver_ = null;
13 this.nextRequestID_ = 0;
14 this.responders_ = {};
16 this.connector_.setIncomingReceiver({
17 accept: this.handleIncomingMessage_.bind(this),
19 this.connector_.setErrorHandler({
20 onError: this.handleConnectionError_.bind(this),
24 Router.prototype.close = function() {
25 this.responders_ = {}; // Drop any responders.
26 this.connector_.close();
29 Router.prototype.accept = function(message) {
30 this.connector_.accept(message);
33 Router.prototype.reject = function(message) {
34 // TODO(mpcomplete): no way to trasmit errors over a Connection.
37 Router.prototype.acceptWithResponder = function(message, responder) {
38 // Reserve 0 in case we want it to convey special meaning in the future.
39 var requestID = this.nextRequestID_++;
41 requestID = this.nextRequestID_++;
43 message.setRequestID(requestID);
44 var result = this.connector_.accept(message);
46 this.responders_[requestID] = responder;
48 // TODO(mpcomplete): accept should return a Promise too, maybe?
50 return Promise.resolve();
51 return Promise.reject(Error("Connection error"));
54 Router.prototype.setIncomingReceiver = function(receiver) {
55 this.incomingReceiver_ = receiver;
58 Router.prototype.encounteredError = function() {
59 return this.connector_.encounteredError();
62 Router.prototype.handleIncomingMessage_ = function(message) {
63 var flags = message.getFlags();
64 if (flags & codec.kMessageExpectsResponse) {
65 if (this.incomingReceiver_) {
66 this.incomingReceiver_.acceptWithResponder(message, this);
68 // If we receive a request expecting a response when the client is not
69 // listening, then we have no choice but to tear down the pipe.
72 } else if (flags & codec.kMessageIsResponse) {
73 var reader = new codec.MessageReader(message);
74 var requestID = reader.requestID;
75 var responder = this.responders_[requestID];
76 delete this.responders_[requestID];
77 responder.accept(message);
79 if (this.incomingReceiver_)
80 this.incomingReceiver_.accept(message);
84 Router.prototype.handleConnectionError_ = function(result) {
85 for (var each in this.responders_)
86 this.responders_[each].reject(result);
91 exports.Router = Router;