1

問題があります。

プロセスを 1 人のユーザーに関連付けたい (ユーザーからのすべてのリクエストは 1 つのプロセスを受け取り、HTTP 1.1 ではデフォルトでキープアライブがオンになっており、すべてのリクエストは 1 つのソケットを介して送信されます)。

私は次のコードを持っています:

loop(Sock, Reg_pid) ->

    {ok, Conn} = gen_tcp:accept(Sock),

    Pid = spawn(fun () -> client_socket(Conn,Reg_pid) end),
    gen_tcp:controlling_process(Conn, Pid),

    Pid ! {take, Conn}, %% race condition 

loop(Sock, Reg_pid).

client_socket(S,Reg_pid) ->

    io:format("in~n"),

receive

    {take, So} ->
        inet:setopts(So, [{active, once}]),
        client_socket(So, Reg_pid);

    {http, Socket, {http_request, _Method, {abs_path, _Path}, _Vers}} ->

        case http_uri2:parse_path_query(_Path) of

            {"/",[]} -> 

                io:format("Main pid - ~p ~n", [self()]),                
                gen_tcp:send(Socket, response("<a href='http://127.0.0.1:8080/register?name=Max'>Click</a>"));              

            {"/register",[{"name", Player_name}]} ->

                io:format("Register pid - ~p ~n", [self()]);



            _-> ok

        end,

        inet:setopts(Socket, [{active, once}]),

        client_socket(Socket, Reg_pid);

     {tcp_closed, Socket} ->

        io:format("Socket ~w closed [~w]~n",[Socket,self()]);
    %   gen_tcp:close(Socket);

      {tcp_error, Socket, Reason} ->
            io:format("Error ~w closed [~w]~n",[Socket,self()]);


    _-> ok


end.

ブラウザを介してサーバー(インデックスページ)に接続し、サーバーを返すリンクをクリックすると、次の結果が得られます:

3> server:start(8080).
<0.43.0>
in 
Main pid - <0.45.0> 
in 
in 
Register pid - <0.46.0> 
in 

次のリクエスト (クリックしてリンク) が他のプロセス (Register pid - <0.46.0>) を受け取る理由がわかりません。

このように、1 人のユーザーからのすべてのリクエストが新しいプロセスを生成します。1 人のユーザーからのすべてのリクエストが 1 つのプロセスを処理するようにしたいのですが、これをどのように実装できますか?

ありがとうございました!

4

1 に答える 1

0

ブラウザは、Keep-Aliveに準拠せず、代わりに新しいソケットを作成することを選択できます。Keep-Aliveを信頼する代わりに、セッションCookieをブラウザに送信して、現在のセッションを特定のプロセスに関連付けることを検討できます。セッションCookieは、リクエストごとにブラウザから送信されます。新しいリクエストの新しいプロセスを作成する前に、セッションCookieを確認し、そのセッションに関連付けられているプロセスがすでに存在するかどうかを確認してください。

于 2012-06-03T10:11:37.340 に答える