erlang 连接php-fpm

WBOY
WBOYoriginal
2016-06-23 14:31:34873parcourir

前端时间在网上看见erlang 连接php-fpm的例子,自己跟到弄了一下,下面给我调试后的代码贴出来

我修正了原来代码的2处bug:

1、参数超过128字符出错

2、当php返回超过1024字节时候出错

文件名fastcgi.erl

                  <p class="sycode">                 -     module(fastcgi).     -     compile(export_all).do_request(Argv)      ->       Env      =      [ {     "     SCRIPT_FILENAME     "     ,     "     E:/phpGame/game/gateway.php     "     }, {     "     websocket     "     ,Argv} ], io:format(     "     Argv msg: ~ts~n     "     , [Argv]), {ok, Socket}     =     gen_tcp:connect(     "     127.0.0.1     "     ,     9000     ,[binary, {packet, 0}, {active,true}],     10000     ), fcgi_send_record(Socket,     1     ,     1     ,     <<     1     :     16     ,0:     8     ,0:     40     >>     ), fcgi_send_record(Socket,      4     ,     1     , Env),  fcgi_send_record(Socket,      4     ,     1     , []),  Bin      =      phpRespone(Socket,[]), gen_tcp:close(Socket),      %%     原报文     <<     Version:     8     , Type:     8     , RequestId:     16     , ContentLength:     16     ,PaddingLength:     8     , Reserved:     8     ,Str     /     binary      >>           =      Bin,       <<     _:     32     ,ContentLength:     16     ,_:     16     ,Str     /     binary      >>           =      Bin,       %%     计算输出内容长度  Dlen     =     ContentLength     -     52     ,       %%     获取内容       <<      _H:     52     /     binary,Data:Dlen     /     binary,_Other     /     binary      >>           =      Str,  io:fwrite(     "     rs:~p~n     "     ,[Data]), {ok,Data}.recv_msg(Sock)      ->      receive  {tcp, Sock, Bin}      ->      io:format(     "     Bin msg: ~p~n     "     , [Bin]),      %%     原报文     <<     Version:     8     , Type:     8     , RequestId:     16     , ContentLength:     16     ,PaddingLength:     8     , Reserved:     8     ,Str     /     binary      >>           =      Bin,       <<     _:     32     ,ContentLength:     16     ,_:     16     ,Str     /     binary      >>           =      Bin,       %%     计算输出内容长度  Dlen     =     ContentLength     -     52     ,       %%     获取内容       <<      _H:     52     /     binary,Data:Dlen     /     binary,_Other     /     binary      >>           =      Str,  io:fwrite(     "     rs:~p~n     "     ,[Data]), {ok,Data}; {tcp_closed,Sock}      ->      io:format(     "     socket close: ~p~n     "     , [Sock]); _Other      ->       io:format(     "     Other msg: ~p~n     "     , [_Other]),  recv_msg(Sock)  after      3000           ->     io:format(     "     Time out.~n     "     )  end. phpRespone(Sock,SoFar)      ->      receive  {tcp, Sock, Bin}      ->      phpRespone(Sock,[Bin     |     SoFar]); {tcp_closed,Sock}      ->      list_to_binary(lists:reverse(SoFar)); _Other      ->       io:format(     "     Other msg: ~p~n     "     , [_Other]),  phpRespone(Sock,SoFar)  after      3000           ->     io:format(     "     Time out.~n     "     )  end.      %%     发送选项 fcgi_send_record(Socket, Type, RequestId, NameValueList)      ->       EncodedRecord      =      fcgi_encode_record(Type, RequestId,NameValueList),  gen_tcp:send(Socket, EncodedRecord).         %%     组包 fcgi_encode_record(Type, RequestId, NameValueList) when is_list(NameValueList)      ->       fcgi_encode_record(Type, RequestId,fcgi_encode_name_value_list(NameValueList));      %%     判断ContentData是否满8字节,否则填充 fcgi_encode_record(Type, RequestId, ContentData) when is_binary(ContentData)      ->       ContentLength      =      size(ContentData),  PaddingLength      =           if       ContentLength rem      8           ==      0      ->       0;  true      ->            8           -      (ContentLength rem      8     )  end,       %%     填充数据,每8字节组包 不足用0填充  PaddingData      =           <<     0:(PaddingLength     *     8     )     >>     ,  Version      =           1     ,  Reserved      =      0,       <<     Version:     8     ,  Type:     8     ,  RequestId:     16     ,  ContentLength:     16     ,  PaddingLength:     8     ,  Reserved:     8     ,  ContentData     /     binary,  PaddingData     /     binary      >>     .       %%     将环境变量组成binary fcgi_encode_name_value_list(_NameValueList      =      [])      ->            <<           >>     ; fcgi_encode_name_value_list(_NameValueList      =      [{Name, Value}      |      Tail])      ->            <<     (fcgi_encode_name_value(Name,Value))     /     binary,(fcgi_encode_name_value_list(Tail))     /     binary      >>     . fcgi_encode_name_value(Name, _Value      =      undefined)      ->       fcgi_encode_name_value(Name,      ""     ); fcgi_encode_name_value(Name, Value) when is_list(Name)      and      is_list(Value)      ->       NameSize      =      length(Name),  NameSizeData      =           <<      NameSize:     8     >>     ,  ValueSize      =      length(Value),       if      ValueSize      <           128           ->      ValueSizeData      =           <<     ValueSize:     8     >>     ; ValueSize      >           127           ->      ValueSizeData      =           <<     (ValueSize bor      16     #     80000000):32>>           end,       <<      NameSizeData     /     binary,ValueSizeData     /     binary,(list_to_binary(Name))     /     binary,(list_to_binary(Value))     /     binary      >>     .                   </p>

在windows 下启动php cgi可以这样做

php-cgi.exe -b 127.0.0.1:9000

在erlang shell中调用:

2> c(fastcgi).
{ok,fastcgi}
3> fastcgi:do_request("{'uid':1}").

文笔不好,请大家多多包含

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:PHP学习方法Article suivant:nginx+php的配置