123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>JSDoc: Source: src/server.js</title>
- <script src="scripts/prettify/prettify.js"> </script>
- <script src="scripts/prettify/lang-css.js"> </script>
- <!--[if lt IE 9]>
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
- <![endif]-->
- <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
- <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
- </head>
- <body>
- <div id="main">
- <h1 class="page-title">Source: src/server.js</h1>
-
-
- <section>
- <article>
- <pre class="prettyprint source linenums"><code>/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- /**
- * Server module
- *
- * This module contains all the server code for Node gRPC: both the Server
- * class itself and the method handler code for all types of methods.
- *
- * For example, to create a Server, add a service, and start it:
- *
- * var server = new server_module.Server();
- * server.addProtoService(protobuf_service_descriptor, service_implementation);
- * server.bind('address:port', server_credential);
- * server.start();
- *
- * @module
- */
- 'use strict';
- var _ = require('lodash');
- var grpc = require('bindings')('grpc_node');
- var common = require('./common');
- var Metadata = require('./metadata');
- var stream = require('stream');
- var Readable = stream.Readable;
- var Writable = stream.Writable;
- var Duplex = stream.Duplex;
- var util = require('util');
- var EventEmitter = require('events').EventEmitter;
- /**
- * Handle an error on a call by sending it as a status
- * @access private
- * @param {grpc.Call} call The call to send the error on
- * @param {Object} error The error object
- */
- function handleError(call, error) {
- var statusMetadata = new Metadata();
- var status = {
- code: grpc.status.UNKNOWN,
- details: 'Unknown Error'
- };
- if (error.hasOwnProperty('message')) {
- status.details = error.message;
- }
- if (error.hasOwnProperty('code')) {
- status.code = error.code;
- if (error.hasOwnProperty('details')) {
- status.details = error.details;
- }
- }
- if (error.hasOwnProperty('metadata')) {
- statusMetadata = error.metadata;
- }
- status.metadata = statusMetadata._getCoreRepresentation();
- var error_batch = {};
- if (!call.metadataSent) {
- error_batch[grpc.opType.SEND_INITIAL_METADATA] =
- (new Metadata())._getCoreRepresentation();
- }
- error_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status;
- call.startBatch(error_batch, function(){});
- }
- /**
- * Send a response to a unary or client streaming call.
- * @access private
- * @param {grpc.Call} call The call to respond on
- * @param {*} value The value to respond with
- * @param {function(*):Buffer=} serialize Serialization function for the
- * response
- * @param {Metadata=} metadata Optional trailing metadata to send with status
- * @param {number=} flags Flags for modifying how the message is sent.
- * Defaults to 0.
- */
- function sendUnaryResponse(call, value, serialize, metadata, flags) {
- var end_batch = {};
- var statusMetadata = new Metadata();
- var status = {
- code: grpc.status.OK,
- details: 'OK'
- };
- if (metadata) {
- statusMetadata = metadata;
- }
- status.metadata = statusMetadata._getCoreRepresentation();
- if (!call.metadataSent) {
- end_batch[grpc.opType.SEND_INITIAL_METADATA] =
- (new Metadata())._getCoreRepresentation();
- call.metadataSent = true;
- }
- var message = serialize(value);
- message.grpcWriteFlags = flags;
- end_batch[grpc.opType.SEND_MESSAGE] = message;
- end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status;
- call.startBatch(end_batch, function (){});
- }
- /**
- * Initialize a writable stream. This is used for both the writable and duplex
- * stream constructors.
- * @access private
- * @param {Writable} stream The stream to set up
- * @param {function(*):Buffer=} Serialization function for responses
- */
- function setUpWritable(stream, serialize) {
- stream.finished = false;
- stream.status = {
- code : grpc.status.OK,
- details : 'OK',
- metadata : new Metadata()
- };
- stream.serialize = common.wrapIgnoreNull(serialize);
- function sendStatus() {
- var batch = {};
- if (!stream.call.metadataSent) {
- stream.call.metadataSent = true;
- batch[grpc.opType.SEND_INITIAL_METADATA] =
- (new Metadata())._getCoreRepresentation();
- }
- if (stream.status.metadata) {
- stream.status.metadata = stream.status.metadata._getCoreRepresentation();
- }
- batch[grpc.opType.SEND_STATUS_FROM_SERVER] = stream.status;
- stream.call.startBatch(batch, function(){});
- }
- stream.on('finish', sendStatus);
- /**
- * Set the pending status to a given error status. If the error does not have
- * code or details properties, the code will be set to grpc.status.UNKNOWN
- * and the details will be set to 'Unknown Error'.
- * @param {Error} err The error object
- */
- function setStatus(err) {
- var code = grpc.status.UNKNOWN;
- var details = 'Unknown Error';
- var metadata = new Metadata();
- if (err.hasOwnProperty('message')) {
- details = err.message;
- }
- if (err.hasOwnProperty('code')) {
- code = err.code;
- if (err.hasOwnProperty('details')) {
- details = err.details;
- }
- }
- if (err.hasOwnProperty('metadata')) {
- metadata = err.metadata;
- }
- stream.status = {code: code, details: details, metadata: metadata};
- }
- /**
- * Terminate the call. This includes indicating that reads are done, draining
- * all pending writes, and sending the given error as a status
- * @param {Error} err The error object
- * @this GrpcServerStream
- */
- function terminateCall(err) {
- // Drain readable data
- setStatus(err);
- stream.end();
- }
- stream.on('error', terminateCall);
- /**
- * Override of Writable#end method that allows for sending metadata with a
- * success status.
- * @param {Metadata=} metadata Metadata to send with the status
- */
- stream.end = function(metadata) {
- if (metadata) {
- stream.status.metadata = metadata;
- }
- Writable.prototype.end.call(this);
- };
- }
- /**
- * Initialize a readable stream. This is used for both the readable and duplex
- * stream constructors.
- * @access private
- * @param {Readable} stream The stream to initialize
- * @param {function(Buffer):*=} deserialize Deserialization function for
- * incoming data.
- */
- function setUpReadable(stream, deserialize) {
- stream.deserialize = common.wrapIgnoreNull(deserialize);
- stream.finished = false;
- stream.reading = false;
- stream.terminate = function() {
- stream.finished = true;
- stream.on('data', function() {});
- };
- stream.on('cancelled', function() {
- stream.terminate();
- });
- }
- util.inherits(ServerUnaryCall, EventEmitter);
- function ServerUnaryCall(call) {
- EventEmitter.call(this);
- this.call = call;
- }
- util.inherits(ServerWritableStream, Writable);
- /**
- * A stream that the server can write to. Used for calls that are streaming from
- * the server side.
- * @constructor
- * @param {grpc.Call} call The call object to send data with
- * @param {function(*):Buffer=} serialize Serialization function for writes
- */
- function ServerWritableStream(call, serialize) {
- Writable.call(this, {objectMode: true});
- this.call = call;
- this.finished = false;
- setUpWritable(this, serialize);
- }
- /**
- * Start writing a chunk of data. This is an implementation of a method required
- * for implementing stream.Writable.
- * @access private
- * @param {Buffer} chunk The chunk of data to write
- * @param {string} encoding Used to pass write flags
- * @param {function(Error=)} callback Callback to indicate that the write is
- * complete
- */
- function _write(chunk, encoding, callback) {
- /* jshint validthis: true */
- var batch = {};
- var self = this;
- if (!this.call.metadataSent) {
- batch[grpc.opType.SEND_INITIAL_METADATA] =
- (new Metadata())._getCoreRepresentation();
- this.call.metadataSent = true;
- }
- var message = this.serialize(chunk);
- if (_.isFinite(encoding)) {
- /* Attach the encoding if it is a finite number. This is the closest we
- * can get to checking that it is valid flags */
- message.grpcWriteFlags = encoding;
- }
- batch[grpc.opType.SEND_MESSAGE] = message;
- this.call.startBatch(batch, function(err, value) {
- if (err) {
- self.emit('error', err);
- return;
- }
- callback();
- });
- }
- ServerWritableStream.prototype._write = _write;
- util.inherits(ServerReadableStream, Readable);
- /**
- * A stream that the server can read from. Used for calls that are streaming
- * from the client side.
- * @constructor
- * @param {grpc.Call} call The call object to read data with
- * @param {function(Buffer):*=} deserialize Deserialization function for reads
- */
- function ServerReadableStream(call, deserialize) {
- Readable.call(this, {objectMode: true});
- this.call = call;
- setUpReadable(this, deserialize);
- }
- /**
- * Start reading from the gRPC data source. This is an implementation of a
- * method required for implementing stream.Readable
- * @access private
- * @param {number} size Ignored
- */
- function _read(size) {
- /* jshint validthis: true */
- var self = this;
- /**
- * Callback to be called when a READ event is received. Pushes the data onto
- * the read queue and starts reading again if applicable
- * @param {grpc.Event} event READ event object
- */
- function readCallback(err, event) {
- if (err) {
- self.terminate();
- return;
- }
- if (self.finished) {
- self.push(null);
- return;
- }
- var data = event.read;
- var deserialized;
- try {
- deserialized = self.deserialize(data);
- } catch (e) {
- e.code = grpc.status.INVALID_ARGUMENT;
- self.emit('error', e);
- return;
- }
- if (self.push(deserialized) && data !== null) {
- var read_batch = {};
- read_batch[grpc.opType.RECV_MESSAGE] = true;
- self.call.startBatch(read_batch, readCallback);
- } else {
- self.reading = false;
- }
- }
- if (self.finished) {
- self.push(null);
- } else {
- if (!self.reading) {
- self.reading = true;
- var batch = {};
- batch[grpc.opType.RECV_MESSAGE] = true;
- self.call.startBatch(batch, readCallback);
- }
- }
- }
- ServerReadableStream.prototype._read = _read;
- util.inherits(ServerDuplexStream, Duplex);
- /**
- * A stream that the server can read from or write to. Used for calls with
- * duplex streaming.
- * @constructor
- * @param {grpc.Call} call Call object to proxy
- * @param {function(*):Buffer=} serialize Serialization function for requests
- * @param {function(Buffer):*=} deserialize Deserialization function for
- * responses
- */
- function ServerDuplexStream(call, serialize, deserialize) {
- Duplex.call(this, {objectMode: true});
- this.call = call;
- setUpWritable(this, serialize);
- setUpReadable(this, deserialize);
- }
- ServerDuplexStream.prototype._read = _read;
- ServerDuplexStream.prototype._write = _write;
- /**
- * Send the initial metadata for a writable stream.
- * @param {Metadata} responseMetadata Metadata to send
- */
- function sendMetadata(responseMetadata) {
- /* jshint validthis: true */
- var self = this;
- if (!this.call.metadataSent) {
- this.call.metadataSent = true;
- var batch = {};
- batch[grpc.opType.SEND_INITIAL_METADATA] =
- responseMetadata._getCoreRepresentation();
- this.call.startBatch(batch, function(err) {
- if (err) {
- self.emit('error', err);
- return;
- }
- });
- }
- }
- ServerUnaryCall.prototype.sendMetadata = sendMetadata;
- ServerWritableStream.prototype.sendMetadata = sendMetadata;
- ServerReadableStream.prototype.sendMetadata = sendMetadata;
- ServerDuplexStream.prototype.sendMetadata = sendMetadata;
- /**
- * Get the endpoint this call/stream is connected to.
- * @return {string} The URI of the endpoint
- */
- function getPeer() {
- /* jshint validthis: true */
- return this.call.getPeer();
- }
- ServerUnaryCall.prototype.getPeer = getPeer;
- ServerReadableStream.prototype.getPeer = getPeer;
- ServerWritableStream.prototype.getPeer = getPeer;
- ServerDuplexStream.prototype.getPeer = getPeer;
- /**
- * Wait for the client to close, then emit a cancelled event if the client
- * cancelled.
- */
- function waitForCancel() {
- /* jshint validthis: true */
- var self = this;
- var cancel_batch = {};
- cancel_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
- self.call.startBatch(cancel_batch, function(err, result) {
- if (err) {
- self.emit('error', err);
- }
- if (result.cancelled) {
- self.cancelled = true;
- self.emit('cancelled');
- }
- });
- }
- ServerUnaryCall.prototype.waitForCancel = waitForCancel;
- ServerReadableStream.prototype.waitForCancel = waitForCancel;
- ServerWritableStream.prototype.waitForCancel = waitForCancel;
- ServerDuplexStream.prototype.waitForCancel = waitForCancel;
- /**
- * Fully handle a unary call
- * @access private
- * @param {grpc.Call} call The call to handle
- * @param {Object} handler Request handler object for the method that was called
- * @param {Metadata} metadata Metadata from the client
- */
- function handleUnary(call, handler, metadata) {
- var emitter = new ServerUnaryCall(call);
- emitter.on('error', function(error) {
- handleError(call, error);
- });
- emitter.metadata = metadata;
- emitter.waitForCancel();
- var batch = {};
- batch[grpc.opType.RECV_MESSAGE] = true;
- call.startBatch(batch, function(err, result) {
- if (err) {
- handleError(call, err);
- return;
- }
- try {
- emitter.request = handler.deserialize(result.read);
- } catch (e) {
- e.code = grpc.status.INVALID_ARGUMENT;
- handleError(call, e);
- return;
- }
- if (emitter.cancelled) {
- return;
- }
- handler.func(emitter, function sendUnaryData(err, value, trailer, flags) {
- if (err) {
- if (trailer) {
- err.metadata = trailer;
- }
- handleError(call, err);
- } else {
- sendUnaryResponse(call, value, handler.serialize, trailer, flags);
- }
- });
- });
- }
- /**
- * Fully handle a server streaming call
- * @access private
- * @param {grpc.Call} call The call to handle
- * @param {Object} handler Request handler object for the method that was called
- * @param {Metadata} metadata Metadata from the client
- */
- function handleServerStreaming(call, handler, metadata) {
- var stream = new ServerWritableStream(call, handler.serialize);
- stream.waitForCancel();
- stream.metadata = metadata;
- var batch = {};
- batch[grpc.opType.RECV_MESSAGE] = true;
- call.startBatch(batch, function(err, result) {
- if (err) {
- stream.emit('error', err);
- return;
- }
- try {
- stream.request = handler.deserialize(result.read);
- } catch (e) {
- e.code = grpc.status.INVALID_ARGUMENT;
- stream.emit('error', e);
- return;
- }
- handler.func(stream);
- });
- }
- /**
- * Fully handle a client streaming call
- * @access private
- * @param {grpc.Call} call The call to handle
- * @param {Object} handler Request handler object for the method that was called
- * @param {Metadata} metadata Metadata from the client
- */
- function handleClientStreaming(call, handler, metadata) {
- var stream = new ServerReadableStream(call, handler.deserialize);
- stream.on('error', function(error) {
- handleError(call, error);
- });
- stream.waitForCancel();
- stream.metadata = metadata;
- handler.func(stream, function(err, value, trailer, flags) {
- stream.terminate();
- if (err) {
- if (trailer) {
- err.metadata = trailer;
- }
- handleError(call, err);
- } else {
- sendUnaryResponse(call, value, handler.serialize, trailer, flags);
- }
- });
- }
- /**
- * Fully handle a bidirectional streaming call
- * @access private
- * @param {grpc.Call} call The call to handle
- * @param {Object} handler Request handler object for the method that was called
- * @param {Metadata} metadata Metadata from the client
- */
- function handleBidiStreaming(call, handler, metadata) {
- var stream = new ServerDuplexStream(call, handler.serialize,
- handler.deserialize);
- stream.waitForCancel();
- stream.metadata = metadata;
- handler.func(stream);
- }
- var streamHandlers = {
- unary: handleUnary,
- server_stream: handleServerStreaming,
- client_stream: handleClientStreaming,
- bidi: handleBidiStreaming
- };
- /**
- * Constructs a server object that stores request handlers and delegates
- * incoming requests to those handlers
- * @constructor
- * @param {Object=} options Options that should be passed to the internal server
- * implementation
- */
- function Server(options) {
- this.handlers = {};
- var handlers = this.handlers;
- var server = new grpc.Server(options);
- this._server = server;
- this.started = false;
- /**
- * Start the server and begin handling requests
- * @this Server
- */
- this.start = function() {
- if (this.started) {
- throw new Error('Server is already running');
- }
- this.started = true;
- server.start();
- /**
- * Handles the SERVER_RPC_NEW event. If there is a handler associated with
- * the requested method, use that handler to respond to the request. Then
- * wait for the next request
- * @param {grpc.Event} event The event to handle with tag SERVER_RPC_NEW
- */
- function handleNewCall(err, event) {
- if (err) {
- return;
- }
- var details = event.new_call;
- var call = details.call;
- var method = details.method;
- var metadata = Metadata._fromCoreRepresentation(details.metadata);
- if (method === null) {
- return;
- }
- server.requestCall(handleNewCall);
- var handler;
- if (handlers.hasOwnProperty(method)) {
- handler = handlers[method];
- } else {
- var batch = {};
- batch[grpc.opType.SEND_INITIAL_METADATA] =
- (new Metadata())._getCoreRepresentation();
- batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
- code: grpc.status.UNIMPLEMENTED,
- details: '',
- metadata: {}
- };
- batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
- call.startBatch(batch, function() {});
- return;
- }
- streamHandlers[handler.type](call, handler, metadata);
- }
- server.requestCall(handleNewCall);
- };
- /**
- * Gracefully shuts down the server. The server will stop receiving new calls,
- * and any pending calls will complete. The callback will be called when all
- * pending calls have completed and the server is fully shut down. This method
- * is idempotent with itself and forceShutdown.
- * @param {function()} callback The shutdown complete callback
- */
- this.tryShutdown = function(callback) {
- server.tryShutdown(callback);
- };
- /**
- * Forcibly shuts down the server. The server will stop receiving new calls
- * and cancel all pending calls. When it returns, the server has shut down.
- * This method is idempotent with itself and tryShutdown, and it will trigger
- * any outstanding tryShutdown callbacks.
- */
- this.forceShutdown = function() {
- server.forceShutdown();
- };
- }
- /**
- * Registers a handler to handle the named method. Fails if there already is
- * a handler for the given method. Returns true on success
- * @param {string} name The name of the method that the provided function should
- * handle/respond to.
- * @param {function} handler Function that takes a stream of request values and
- * returns a stream of response values
- * @param {function(*):Buffer} serialize Serialization function for responses
- * @param {function(Buffer):*} deserialize Deserialization function for requests
- * @param {string} type The streaming type of method that this handles
- * @return {boolean} True if the handler was set. False if a handler was already
- * set for that name.
- */
- Server.prototype.register = function(name, handler, serialize, deserialize,
- type) {
- if (this.handlers.hasOwnProperty(name)) {
- return false;
- }
- this.handlers[name] = {
- func: handler,
- serialize: serialize,
- deserialize: deserialize,
- type: type
- };
- return true;
- };
- /**
- * Add a service to the server, with a corresponding implementation. If you are
- * generating this from a proto file, you should instead use
- * addProtoService.
- * @param {Object<String, *>} service The service descriptor, as
- * {@link module:src/common.getProtobufServiceAttrs} returns
- * @param {Object<String, function>} implementation Map of method names to
- * method implementation for the provided service.
- */
- Server.prototype.addService = function(service, implementation) {
- if (this.started) {
- throw new Error('Can\'t add a service to a started server.');
- }
- var self = this;
- _.each(service, function(attrs, name) {
- var method_type;
- if (attrs.requestStream) {
- if (attrs.responseStream) {
- method_type = 'bidi';
- } else {
- method_type = 'client_stream';
- }
- } else {
- if (attrs.responseStream) {
- method_type = 'server_stream';
- } else {
- method_type = 'unary';
- }
- }
- if (implementation[name] === undefined) {
- throw new Error('Method handler for ' + attrs.path +
- ' not provided.');
- }
- var serialize = attrs.responseSerialize;
- var deserialize = attrs.requestDeserialize;
- var register_success = self.register(attrs.path,
- _.bind(implementation[name],
- implementation),
- serialize, deserialize, method_type);
- if (!register_success) {
- throw new Error('Method handler for ' + attrs.path +
- ' already provided.');
- }
- });
- };
- /**
- * Add a proto service to the server, with a corresponding implementation
- * @param {Protobuf.Reflect.Service} service The proto service descriptor
- * @param {Object<String, function>} implementation Map of method names to
- * method implementation for the provided service.
- */
- Server.prototype.addProtoService = function(service, implementation) {
- this.addService(common.getProtobufServiceAttrs(service), implementation);
- };
- /**
- * Binds the server to the given port, with SSL enabled if creds is given
- * @param {string} port The port that the server should bind on, in the format
- * "address:port"
- * @param {ServerCredentials=} creds Server credential object to be used for
- * SSL. Pass an insecure credentials object for an insecure port.
- */
- Server.prototype.bind = function(port, creds) {
- if (this.started) {
- throw new Error('Can\'t bind an already running server to an address');
- }
- return this._server.addHttp2Port(port, creds);
- };
- /**
- * @see module:src/server~Server
- */
- exports.Server = Server;
- </code></pre>
- </article>
- </section>
- </div>
- <nav>
- <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-src_client.html">src/client</a></li><li><a href="module-src_common.html">src/common</a></li><li><a href="module-src_credentials.html">src/credentials</a></li><li><a href="module-src_metadata.html">src/metadata</a></li><li><a href="module-src_server.html">src/server</a></li></ul><h3>Classes</h3><ul><li><a href="module-src_client.makeClientConstructor-Client.html">Client</a></li><li><a href="module-src_client-ClientDuplexStream.html">ClientDuplexStream</a></li><li><a href="module-src_client-ClientReadableStream.html">ClientReadableStream</a></li><li><a href="module-src_client-ClientWritableStream.html">ClientWritableStream</a></li><li><a href="module-src_metadata-Metadata.html">Metadata</a></li><li><a href="module-src_server-Server.html">Server</a></li><li><a href="module-src_server-ServerDuplexStream.html">ServerDuplexStream</a></li><li><a href="module-src_server-ServerReadableStream.html">ServerReadableStream</a></li><li><a href="module-src_server-ServerWritableStream.html">ServerWritableStream</a></li></ul><h3>Global</h3><ul><li><a href="global.html#callError">callError</a></li><li><a href="global.html#credentials">credentials</a></li><li><a href="global.html#getClientChannel">getClientChannel</a></li><li><a href="global.html#load">load</a></li><li><a href="global.html#loadObject">loadObject</a></li><li><a href="global.html#makeGenericClientConstructor">makeGenericClientConstructor</a></li><li><a href="global.html#Metadata">Metadata</a></li><li><a href="global.html#propagate">propagate</a></li><li><a href="global.html#Server">Server</a></li><li><a href="global.html#ServerCredentials">ServerCredentials</a></li><li><a href="global.html#status">status</a></li><li><a href="global.html#waitForClientReady">waitForClientReady</a></li><li><a href="global.html#writeFlags">writeFlags</a></li></ul>
- </nav>
- <br class="clear">
- <footer>
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Thu Jan 14 2016 16:17:15 GMT-0800 (PST)
- </footer>
- <script> prettyPrint(); </script>
- <script src="scripts/linenumber.js"> </script>
- </body>
- </html>
|