25

サーバーとクライアントを使用して Web アプリを作成しているとします。

  • サーバーはAPI として機能し、expressフレームワークを使用します。
  • クライアントは、node-static静的な javascript/html ファイルを提供する単なるアプリです。

それらを個別に、互いに独立して、または同時に両方を展開できるようにしたいと考えています。

ディレクトリ構造をどのように想定するかを次に示します。

 /my-app
     app.js
     /server
         server.js
     /client
         client.js

これを3つの異なる方法で実行できるようにしたいと思います。

  1. 一部のポート (3000 など) でサーバー (API) のみを実行します。

    my-app/server> node server.js
    ...Server listening on localhost:3000/api
    
  2. クライアントのみを実行します (つまり、/client ディレクトリから静的ファイルを提供します):

    my-app/client> node client.js
    ...Server listening on localhost:4000/client
    
  3. サーバーとクライアントの両方を同じポートで (単一の node.js インスタンスで) 実行します。

    my-app> node app.js
    ...Server listening on localhost:5000
    

これはノードで可能ですか?それを構成する適切な方法は何ですか?

私は次のように始めました:

/////////////
// server.js
/////////////
// Run the server if this file is run as script
if(module.parent){
   app.listen("3000/client")  
}

/////////////
// client.js
/////////////
var static = require('node-static');
var file = new(static.Server)('.');
var app = require('http').createServer(function (request, response) {
  request.addListener('end', function () {
    file.serve(request, response);
  });
});
if(module.parent){
   app.listen("4000/client");
}

/////////////
// app.js
/////////////
server = require("server/server.js")
server.app.listen("5000/api")

client = require("client/client.js")
client.app.listen("5000/client")  <--- ?????

app.js内でクライアントサーバーの両方を接続して、両方が同じポート/プロセス/スレッドなどから提供されるようにする方法がわかりません...

注: 申し訳ありませんが、コードはテストされておらず、おそらく正しくありません。私はnode.jsが初めてです

ヒントをいただければ幸いです。

4

3 に答える 3

10

サーバーとクライアントの両方を同じスクリプトから起動するときにサーバーインスタンスconnect(の内臓)をインスタンス化し、URLがで始まるときとそうでないときにリクエストをルーティングすることができます。expressnode-staticpublicconnect

何かのようなもの

var connect = require('connect');
server = connect.createServer();
server.use('/public', client.handler_function);
server.use(server.express_handler_function);

する必要があります。function(request, response)inを公開して、Expressアプリclient.jsで参照できるようにする必要があります(ドキュメントを参照してください)。client.handler_function

たとえば、で関数をエスポーズするには、次のclient.jsようなものが含まれます。

var static = require('node-static');
var file = new(static.Server)('.');
var handler = function (request, response) {
  request.addListener('end', function () {
    file.serve(request, response);
  });
};
var app = require('http').createServer(handler);
if(module.parent){
   app.listen(4000);
   console.log("Server (static) listening on 4000")
}
module.exports = { handler_function: handler };

あなたがすることhandlerによって到達できるように:

var client = require('client'); // this returns the object you've set to `module.exports` in `client.js`
[...]
server.use('/public', client.handler_function);

その他のアプローチ

上で詳しく説明したものは、(前回の編集での説明に基づいて)必要なものに最も近いようです。ただし、他のオプションがあります。

  • example.com/a_statically_served_script.jsおよびなどのサイトルートに基づいて静的およびエクスプレス生成されたURLを保持しexample.com/api_endpointます。静的ファイルの提供が最初に試行されます。静的ファイルが見つからない場合は、エクスプレスベースのアプリにリクエストをディスパッチします

  • スクリプトを使用して、app.js両方のサーバーを異なるポート(またはunixドメインソケット)で起動し、それらの前でノードプロキシ(または同様のもの、あるいはリバースプロキシとしてnginx / apache )を使用します

同じルート

file.serve最初のアプローチでは、次のようなエラーハンドラを追加する必要があります。

file.serve(request, response, function(e, res) {
    if (e && (e.status == 404)) {
        // if the file wasn't found
        if (next) {
            next(request, response);
        }
    }
}

nextclient.jsスクリプトを直接実行する場合は設定されないが、スクリプトが必要な場合はスクリプト内の変数である必要があります(ノードでのモジュールとエクスポートの動作についてはドキュメントを参照してください)-設定nextすると、次の関数を参照します表現するためにそれらを(req, res)取得してフィードします(これを行う方法については、表現ドキュメントを参照してください)。

備考

これは完全な答えではないことに注意してください。これは、検索するドキュメントと、問題を解決するために使用できる手法に関する一連のポインタにすぎません。

覚えておく価値のあることは、多くの場合、ノードでは要求ハンドラーがで表され、実装されていることfunction(request, response)です。このイディオムはconnect/で拡張さexpressfunciton(request, response, next)ます:ここでは、を介してサーバーにマウントされたハンドラーのチェーン内のnext(形式の)次の使用可能なハンドラーを表します。function(request, response)server.use(handler)

于 2013-01-14T01:08:19.983 に答える
8

OPと同様の要件がありましたが、サブセクションを個別に実行する必要はありませんでした...サーバーのコードフォルダー内にクライアントコードをネストするのが好きではないため、個別のフォルダーのみが必要でした。技術的にはそうするのを避けることは不可能なので、代わりにファイルシステムに抽象化のレベルを作成して、問題を抱えた魂を和らげました。これが私のプロジェクトのルートです:

-client
-server
-node_modules
-app.js

client通常はすべてpublic(提供されるすべてのクライアント側ファイル) が含まれます。つまり、少なくともindex.html.

serverNodeモジュールである場合とそうでない場合があります(私の場合はそうである必要はありませんでした)。ここにアプリ固有のサーバー コードがあります。違いはなく、問題なく動作するため、require基になるファイルと同じファイルを再作成できます。app.js

node_modulesNode.js では明らかに必要であり、プロジェクトのルートに残しておくのが最善です。これは、プロジェクト フォルダー階層を上方向に検索requireて、ルートにあるモジュールのこの共通リポジトリを見つけることができるためです。server

app.js単純に次のものが含まれます。

var path = require('path');
var express = require('express');
app = express();
require('./server/server.js');

app.use(express.directory(path.join(__dirname, '/'))); //optional, directory browsing
app.use(express.static(path.join(__dirname, '/')));
app.use(express.errorHandler());

app.listen(process.env.PORT || 5000);

...ご覧のとおり、ルート スクリプトには最小限のコードしかありません。すべてが非常に重要で、アプリケーション固有

変数appはを使用して宣言されていないvarことに注意してください。を回避することで、それをグローバルにし、手間をかけずvarにアクセスできるようにします。server.js

したがってnode app、それがまだ明確でない場合は、これを実行するために実行します。

于 2013-09-28T18:50:24.570 に答える
4

のようなリバース プロキシを使用するのはどうNginxですか?

1 つのポートで 2 つのノード アプリを簡単にバインドでき、他にも多くの利点があります。

http://wiki.nginx.org/Main

于 2013-01-14T01:27:38.950 に答える