#wcf #web-services #jax-ws #mtom
#wcf #веб-сервисы #jax-ws #mtom
Вопрос:
Мои веб-службы работали отлично, трудно сказать, что я делал, что время от времени приводило к их сбою. Я добавил базовую аутентификацию HTTP и поменял поставщиков баз данных с ObjectDB на MySQL, поэтому производительность снизилась, но это кажется неуместным.
У меня есть защищенные SSL веб-службы Java Metro, размещенные на GlassFish v3.1 с включенной потоковой передачей MTOM. Я вызываю их с помощью клиента WCF. Исключение время от времени возникает случайным образом, даже когда я вызываю одну и ту же службу с одинаковыми параметрами.
ОБНОВЛЕНИЕ Иногда он просто ведет себя так, как будто выполняет успешный вызов, и тогда независимо от того, какую службу я вызываю, даже с helloWorld
, я получаю исключение. Если я вызываю только один из прокси-серверов, вызовы выполняются нормально, но, например, я получаю исключение, если я делаю вызов dataMiningClient
и затем dataStoreClient
. Безопасность потоков?
Смотрите:
private void button1_Click(object sender, EventArgs e)
{
richTextBox1.Text = "";
DataStoreWSClient dataStoreClient = getDataStoreClient(email, password);
DataMiningWSClient dataMiningClient = getDataMiningClient(email, password);
byte[] dataSet = File.ReadAllBytes(textBox1.Text);
string dataSetName = Path.GetFileName(textBox1.Text);
long checkSum = getCheckSumForDataSet(dataSet);
//WS Call
try
{
//Example:
//The second time I click on this button,
//this is the point where I get the ProtocolException
bool checkSumResponse = dataStoreClient.checkDataSet(checkSum);
//checkSumResponse was always true when I was debugging this
//So no MTOM streaming involved
if (checkSumResponse)
{
richTextBox1.Text = dataMiningClient.kNearestNeighbour(checkSum, notifyByEmail);
}
else
{
richTextBox1.Text = dataMiningClient.kNearestNeighbourMTOM(dataSetName, notifyByEmail, dataSet);
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.ToString());
richTextBox1.Text = ex.ToString();
}
dataMiningClient.Close();
dataStoreClient.Close();
}
У меня нет никаких сообщений об ошибках на стороне сервера.
Это сообщение об исключении, которое я получаю:
Система.ServiceModel.Исключение ProtocolException: тип содержимого multipart/related;start=»»;type=»application/xop xml»;boundary=»uuid:d64b0098-0dcb-4da4-a047-d305b55da9f5″;start-info=»text/xml » ответное сообщение не соответствует типу содержимого привязки (текст / xml; кодировка = utf-8). При использовании пользовательского кодировщика убедитесь, что метод IsContentTypeSupported реализован правильно. Первыми 1024 байтами ответа были: ‘—uuid: d64b0098-0dcb-4da4-a047-d305b55da9f5 Идентификатор содержимого: Тип содержимого: приложение / xop xml; кодировка = utf-8; тип=»текст / xml» Кодировка для передачи содержимого: двоичный
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<S:Header>
<To xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</To>
<Action xmlns="http://www.w3.org/2005/08/addressing"
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
S:mustUnderstand="1">http://webServices/DataStoreWS/checkDataSetResponse</Action>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:1cbcfdc6-01e4-4ddc-960d-a9a2d4e3021a</MessageID>
<RelatesTo xmlns="http://www.w3.org/2005/08/addressin'. sender, EventArgs e) in F:2.0WSClient3.5ServiceRefWSClient3.5Form1.cs:line 51
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory factory, WebException responseException, ChannelBinding channelBinding)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageDataamp; msgData, Int32 type)
at WSClient3._5.DataStore.DataStoreWS.checkDataSet(checkDataSetRequest request)
at WSClient3._5.DataStore.DataStoreWSClient.WSClient3._5.DataStore.DataStoreWS.checkDataSet(checkDataSetRequest request) in F:DropboxSuliMScDIPLOMA_MScJavaWSJMX2.0WSClient3.5ServiceRefWSClient3.5Service ReferencesDataStoreReference.cs:line 1227
at WSClient3._5.DataStore.DataStoreWSClient.checkDataSet(Int64 checkSum) in F:DropboxSuliMScDIPLOMA_MScJavaWSJMX2.0WSClient3.5ServiceRefWSClient3.5Service ReferencesDataStoreReference.cs:line 1233
at WSClient3._5.Form1.button1_Click(Object sender, EventArgs e) in F:DropboxSuliMScDIPLOMA_MScJavaWSJMX2.0WSClie
Клиентский код:
DataMiningWSClient getDataMiningClient(String username, String password)
{
//IMPORTANT - THIS LINE IS ONLY FOR TESTING PURPOSES!
//This code is for accepting self-signed server certificate
ServicePointManager.ServerCertificateValidationCallback = (sender_ws, cert, chain, sslPolicyErrors) => true;
//instantiate transport binding element, leave the defaults
HttpsTransportBindingElement transport = new HttpsTransportBindingElement();
transport.MaxReceivedMessageSize = 2147483647;
transport.AuthenticationScheme = AuthenticationSchemes.Basic;
//instantiate message encoding element, where message version must be Soap11WSAddressing10 to match metro web service requirement.
MtomMessageEncodingBindingElement mtom = new MtomMessageEncodingBindingElement();
mtom.WriteEncoding = System.Text.Encoding.UTF8;
mtom.MessageVersion = MessageVersion.Soap11WSAddressing10;
mtom.MaxBufferSize = 2147483647;
mtom.ReaderQuotas.MaxStringContentLength = 2147483647;
//instantiate transport security binding element, with all the suggested values in app.config
TransportSecurityBindingElement b_element = new TransportSecurityBindingElement();
b_element.DefaultAlgorithmSuite = new Basic128SecurityAlgorithmSuite();
b_element.IncludeTimestamp = true;
b_element.KeyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy;
b_element.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11;
b_element.SecurityHeaderLayout = SecurityHeaderLayout.Lax;
//instantiate the custom binding and add the elements created above
CustomBinding customBinding = new CustomBinding();
customBinding.Name = "myOwnPersonalCustomBinding";
customBinding.Elements.Add(b_element);
customBinding.Elements.Add(mtom);
customBinding.Elements.Add(transport);
//instantiate the client
DataMiningWSClient DMclient = new DataMiningWSClient(customBinding, new EndpointAddress(new Uri("https://localhost:8181/DataMiner/DataMiner")));
setCredentials(username, password, DMclient.ClientCredentials);
return DMclient;
}
Любые подсказки, в чем может быть проблема здесь? Пожалуйста, скажите мне, должен ли я расширить этот вопрос дополнительной информацией; Я могу покопаться в журналах сообщений WCF.
Ответ №1:
Причина ProtocolException
: я НЕ настраивал оба прокси с помощью MtomMessageEncodingBindingElement
, однако обе службы были определены с @MTOM
аннотацией.
После определения его для обоих прокси все работало нормально:
//instantiate message encoding element, where message version must be Soap11WSAddressing10 to match metro web service requirement.
MtomMessageEncodingBindingElement mtom = new MtomMessageEncodingBindingElement();
mtom.WriteEncoding = System.Text.Encoding.UTF8;
mtom.MessageVersion = MessageVersion.Soap11WSAddressing10;
mtom.MaxBufferSize = 2147483647;
mtom.ReaderQuotas.MaxStringContentLength = 2147483647;