0

C# でphp デスクトッププロジェクトを作成したいのですが、C# で見つけた利用可能な組み込み Web サーバーがありません (Mongoose を試しましたが、そのファイルを dll にコンパイルできませんでした)。そのため、C# で単純な Web サーバーを構築します。NET HTTP Serverを組み込み、php-cgi の処理コードを自作しました。

しかし、サーバーを完成させた後、Mongoose と私のサーバーで同じ PHP プロジェクト (Laravel) を実行します。応答速度において、Mongoose サーバーが私のサーバーよりも高速に動作することがわかりました。

どの点を見逃したのかわかりません。

HTTP サーバーは、このSystem.Net.Sockets.Socketクラスを使用して非同期ネットワーク通信を実行します。

コードの一部 (Init サーバー) は次のようになります。

ss = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
ss.Bind(new IPEndPoint(IPAddress.Any, port));
ss.Listen(100);
ss.BeginAccept(new AsyncCallback(AcceptCallback), ss);

PHP ハンドラー メソッド:

    bool phpHandler(HttpRequest request, HttpResponse response)
    {
        string phpScript = rootScriptPath + "\\index.php";
        Dictionary<string, string> envs = new Dictionary<string, string>();

        setEnvs(envs, request);
        PHPProcess pp = new PHPProcess(phpScript, envs);

        pp.start();
        if (request.Method == "POST")
        {

            pp.process.StandardInput.AutoFlush = true;
            pp.process.StandardInput.Write(request.Content);

            pp.process.StandardInput.Close();
        }
        string outPutContent = pp.readRes();

        //separate header and body in php-cgi output
        string[] outPutSlices = outPutContent.Split(new String[] { "\r\n" }, StringSplitOptions.None);

        bool headerEndFlag = false;

        string bodyContent = "";
        foreach (string outPutSlice in outPutSlices)
        {

            if (outPutSlice.Length > 0)
            {
                if (headerEndFlag)
                {
                    bodyContent += outPutSlice + "\r\n";

                }
                else
                {
                    if (outPutSlice.IndexOf(':') > 0)
                    {
                        string[] headerSingleSlices = outPutSlice.Split(new Char[] { ':' });
                        if (!response.Header.ContainsKey(headerSingleSlices[0]))
                            response.Header.Add(headerSingleSlices[0], headerSingleSlices[1]);
                    }
                }

            }
            else
            {
                headerEndFlag = true;
            }

        }
        if (bodyContent.Length > 2)
        {
            bodyContent = bodyContent.Remove(bodyContent.Length - 2);
        }

        response.Content = bodyContent;
        response.ReturnCode = 200;
        pp.destory();
        return true;
    }

PHP プロセス クラス:

class PHPProcess
{
    private string phpDir = System.Environment.CurrentDirectory + "\\" + Properties.HcParams.Default.php_path;
    public Process process;

    public PHPProcess(string entranceScript,Dictionary<string,string> envs){
        process = new Process();
        string scriptName = "\\" + entranceScript.Split(new Char[]{'\\'}).Last();
        Console.WriteLine("ScriptName:" + scriptName);
        process.StartInfo.FileName = phpDir + "\\php-cgi.exe";
        process.StartInfo.Arguments = entranceScript;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
        process.StartInfo.RedirectStandardInput = true;
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.EnvironmentVariables.Add("REDIRECT_STATUS", "200");
        process.StartInfo.EnvironmentVariables.Add("SCRIPT_NAME", scriptName);
        process.StartInfo.EnvironmentVariables.Add("SCRIPT_FILENAME", entranceScript);
        process.StartInfo.EnvironmentVariables.Add("SERVER_INTERFACE", "CGI/1.1");
        process.StartInfo.EnvironmentVariables.Add("GETWAY_INTERFACE", "CGI/1.1");
        process.StartInfo.EnvironmentVariables.Add("SERVER_PROTOCOL", "HTTP/1.1");
        process.StartInfo.EnvironmentVariables.Add("SERVER_PORT", Bmain.StartPort.ToString());
        foreach (var env in envs)
        {
            process.StartInfo.EnvironmentVariables.Add(env.Key, env.Value);
        }
    }

    public void start(){
        process.Start();

    }
    public string readRes()
    {
        string OutputText = process.StandardOutput.ReadToEnd();
        return OutputText;
    }

    public void destory(){
        process.WaitForExit();
        process.Close();
    }
}

速度を最適化するにはどうすればよいですか?

4

0 に答える 0