6

バイト配列バッファを取り、ストレージとアーカイブのために外部ファイル サービスにストリーミングする Web サービス (asmx) があります。これは、かなり小さなファイル (3 ~ 5M) を生成する Windows サービスによって呼び出されるため、そのサイズのバイト配列を作成し、それをパラメーターとして Web サービス呼び出しに渡すことは、今までうまく機能していました。

私は、70M を超えるファイルを生成する可能性があるファイル キューに新しいジョブを追加する任務を負っています。明らかに、byte[]そのサイズはシステム メモリを圧倒するので、解決策を探しています。FileStreamWeb サービスには、の代わりに をパラメーターとして取る内部メソッドがあるbyte[]ため、FileStream メソッドを WebMethod として表面化してみました。CallingWindowsService.ExternalWebServiceFileManager.FileStreamWindows サービスの参照を更新しましたが、奇妙なことが起こります: FileStream パラメーターには名前空間指定子 (. .

私はこれにどのようにアプローチするかについて完全に海にいます。大量のデータWeb サービスにストリーミングするなど、他の誰かがこれを行ったことがありますか?もしそうなら、最良の方法は何ですか? Web サービスには または のいずれかが必要byte[]ですFileStream

他のいくつかのメッセージを見ると、MTOM (よく知られていない) が解決策のように見えますが、Web メソッドで設定する方法や動作させる方法がわかりません。

4

3 に答える 3

3

いくつかのことを試すことができます。使用しているプロトコルやホスティング方法については言及していないので、IIS7 と SOAP を使用している可能性があると想定します。Web サービスの web.config ファイルに次を追加すると、404 エラーなしで転送できるファイル サイズを増やすことができます。

  <system.web>
     <httpRuntime executionTimeout="999999" maxRequestLength="2097151" />
     ...
  </system.web>

大きなファイルの転送を許可するために、Web サービスの web.config ファイルに対して行う必要がある 2 番目のこと:

  <system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="2000000000" />
      </requestFiltering>
    </security>
  </system.webServer>

別の可能性:

<location path="Copy.asmx"> <!-- Name of you asmx -->
    <system.webServer>
      <security>
        <requestFiltering>
          <requestLimits maxAllowedContentLength="104857600"/> <!-- 100 megs -->
        </requestFiltering>
      </security>
    </system.webServer>
  </location>

byte[] を Web サービス経由で送信する際の主な問題は、base 64 文字列としてエンコードされる SOAP 本文に入れられることです。このようにファイルをエンコードすると、soap 本体でファイルのサイズが 3 分の 2 も大きくなります (つまり、6 MB のファイルがネットワーク経由で 9 MB のファイルになります)。

もう1つの可能性は、送信前にデータを小さなセグメントに分割する「チャンク」です。これで十分かもしれません。チャンク サイズ (500KB に設定) は、ネットワーク速度、サーバー リソースなどの要因に基づいて、アップロードのパフォーマンスを向上させる重要な要因になる可能性があります。

/// <summary>
/// Chunk the file and upload
/// </summary>
/// <param name="filename"></param>
private void UploadVideo(string filename)
{
    #region Vars
    const int chunkSize = 512000;
    byte[] bytes = null;
    int startIndex, endIndex, length, totalChunks;           

    WS.UploadRequest objRequest = new WS.UploadRequest();            
    #endregion

    try
    {
        if (File.Exists(filename))
        {
            using (WS.UploadService objService = new WS.UploadService())
            {
                using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    //// Calculate total chunks to be sent to service
                    totalChunks = (int)Math.Ceiling((double)fs.Length / chunkSize);

                    //// Set up Upload request object
                    objRequest.FileName = filename;
                    objRequest.FileSize = fs.Length;

                    for (int i = 0; i < totalChunks; i++)
                    {
                        startIndex = i * chunkSize;
                        endIndex = (int)(startIndex + chunkSize > fs.Length ? fs.Length : startIndex + chunkSize);
                        length = endIndex - startIndex;
                        bytes = new byte[length];

                        //// Read bytes from file, and send upload request
                        fs.Read(bytes, 0, bytes.Length);
                        objRequest.FileBytes = bytes;
                        objService.UploadVideo(objRequest);
                    }
                }

            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(string.Format("Error- {0}", ex.Message));
    }
于 2012-04-12T01:47:00.473 に答える
1

ASMXWebサービスは、新しい開発に使用すべきではないレガシーテクノロジーです。

欠けている機能の1つは、ストリーミングと大きなファイルのサポートです。特に、メッセージは、クライアントに送信される途中で最大4回メモリに複製されます。

WCF真のストリーミングをサポートします。

于 2012-04-11T23:17:37.300 に答える
-1

@John Saundersが言ったように、Webサービスはストリーミングと大きなファイルサイズの処理のサポートが不十分です。未加工のファイルを送信する代わりに、圧縮を使用してWebサービスを介してファイルを送信できます。

于 2012-04-12T01:19:59.550 に答える