WCFRESTサービスで実装されたAzureWebroleがあります。HTTP POSTリクエストを使用して、このサービスに小さな画像ファイル(50KB未満)をアップロードしようとしています。
次の方法で機能します。
- を使用してWindowsフォームアプリケーションからアップロードします
WebRequest
。 - Fiddlerプロキシを通過するときにAndroid携帯からアップロードします。
Azure Webroleに直接POSTしようとすると、同じAndroidフォンの同じAndroidコードで失敗します。
この場合、SocketException
and detailMessage="接続がピアによってリセットされました"でタイムアウトが発生します。Azureで(RDPを使用して)VMインスタンスを調べると、この呼び出しのステータス400が表示されます。
Androidコードは次のとおりです。
DefaultHttpClient httpclient = new DefaultHttpClient();
String requestStr = "http://servername.cloudapp.net/Rest/RestAPI?action_type=upload_file&user_id=5";
HttpPost httpPost = new HttpPost(requestStr);
HttpParams httpParams = new BasicHttpParams();
// Set the default connection timeout
// in milliseconds which is the timeout for waiting for a connection.
int timeoutConnection = 60000;
HttpConnectionParams.setConnectionTimeout(httpParams, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 60000;
HttpConnectionParams.setSoTimeout(httpParams, timeoutSocket);
httpPost.setParams(httpParams);
httpPost.addHeader("Content-Type", "application/x-data-png");
httpPost.addHeader("FileName", fileName);
ByteArrayEntity byteArrayEntity = new ByteArrayEntity(bytes);
httpPost.setEntity(byteArrayEntity);
//Execute HTTP Post Request
HttpResponse response = httpclient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String responseStr = EntityUtils.toString(entity);
これが私のWebRoleコードです(この問題のテストに使用します):
[OperationContract]
[WebInvoke(UriTemplate = "?action_type=upload_file&user_id={userID}", Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
public void UploadFile(string userID, Stream fileContents)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;
}
さらに詳しい情報:同じ方法を試しましたが、次のような短いバイト配列を送信しましたが、機能しました。
String someString = "some string";
byte[] byteArray = someString.getBytes();
そのため、ファイルを正しく読み取っていないか、バイト配列が長すぎる可能性があります(50KBが問題になるはずですか?)
ファイルのバイトを取得するために使用するAndroidコードは次のとおりです。
FileInputStream fileStream = new FileInputStream(fileToUpload);
fileStream.read(bytes);
fileStream.close();
私は何が間違っているのですか?
更新:サーバーに直接投稿するAndroidエミュレーターでまったく同じコードを試しましたが、機能しました...これが電話から機能しないのはなぜですか?!
更新:ルーターのWiFiに奇妙な問題があったことが判明しました(!)
他のすべては正常に機能し、Android電話から特定のサイズを超えるAzureへのアップロードのみが失敗しました...(同じ電話からの他のアップロードは機能しました...)ルーターを新しいルーターに変更すると、すべてが再び機能します。
また、1週間私を放棄せず、最終的に問題を理解するのを手伝ってくれたAzureサポート担当者を称賛したいと思います。
私はこれを異常な事故として扱い、私の人生を続けるべきだと思います:-)
それはまた、上記のコードが物事を行う方法の良い例であることを意味します。それが誰かを助けることを願っています...