Piszę projekt wykrywania wzorców obrazów, wykonując obliczenia na wileu komputerach i utknąłem w martwym punkcie. Nie mogę przesłać dużego obrazka przy pomocy WCF. Wszystko inne mam już zaimplementowane.
Połączenie między klientem a serwerem ogólnie działa, mogę przesyłać tekst i liczby ale jak chcę przesłać strumień to go gubi, przesyłą pusty. Do przesyłania plików stworzyłem sobie MessageContract i Filename jest przesyłane a FileByteStream jest gubione po drodze.
[MessageContract]
public class FileUploadMessage
{
[MessageHeader(MustUnderstand = true)]
public string Filename;
[MessageBodyMember(Order = 1)]
public Stream FileByteStream;
}
Mój serwis (interfejs):
[ServiceContract]
public interface ISlaveService
{
[OperationContract]
FileUploadMessage SendPattern(FileUploadMessage image);
}
Implementacja serwisu. Dla testu zwróciłem sobie też FileUploadMessage i w drugą stronę też nie działa (przechodzi tylko Filename).
public FileUploadMessage SendPattern(FileUploadMessage image)
{
try
{
ImageSource source = BitmapFrame.Create(image.FileByteStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
MainWindow.Instance.imagePattern.Source = source;
Stream imageStream2 = File.OpenRead(@"C:\aaa.jpg");
image.FileByteStream = imageStream2;
return image;
}
catch (Exception ex)
{
// TODO: add log
return null;
}
}
Tak u mnie wygląda uruchomienie serwisu. Wolałem zrobić to w kodzie niż przy pomocy app.config bo chciałem móc dynamicznie decydować jaki ma być adres i port używany:
public static void StartService()
{
try
{
Uri tcpUrl = new Uri("net.tcp://localhost:" + Config.Instance().LocalPort + "/SlaveService");
host = new ServiceHost(typeof(SlaveService), tcpUrl);
NetTcpBinding tcpbinding = new NetTcpBinding();
tcpbinding.Security.Mode = SecurityMode.None;
tcpbinding.TransferMode = TransferMode.Streamed;
tcpbinding.MaxReceivedMessageSize = 2147483647;
tcpbinding.ReaderQuotas.MaxArrayLength = 2147483647;
tcpbinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
tcpbinding.ReaderQuotas.MaxStringContentLength = 2147483647;
tcpbinding.ReaderQuotas.MaxDepth = 2147483647;
host.AddServiceEndpoint(typeof(ISlaveService), tcpbinding, "net.tcp://localhost:" + Config.Instance().LocalPort + "/SlaveService");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
host.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexTcpBinding(),
"net.tcp://localhost:" + Config.Instance().LocalPort + "/SlaveService/mex");
host.Open();
}
catch (Exception ex)
{
//TO DO: Logger.Add("Failed to start Slave service. " + ex.Message);
}
}
Klient łączy się w taki sposób:
public bool Connect(string address)
{
NetTcpBinding tcpbinding = new NetTcpBinding();
tcpbinding.Security.Mode = SecurityMode.None;
tcpbinding.TransferMode = TransferMode.Streamed;
tcpbinding.MaxReceivedMessageSize = 2147483647;
tcpbinding.ReaderQuotas.MaxArrayLength = 2147483647;
tcpbinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
tcpbinding.ReaderQuotas.MaxStringContentLength = 2147483647;
tcpbinding.ReaderQuotas.MaxDepth = 2147483647;
EndpointAddress endpoint = new EndpointAddress("net.tcp://" + address + "/SlaveService");
var channelFactory = new ChannelFactory<ISlaveService>(tcpbinding, endpoint);
client = null;
try
{
client = channelFactory.CreateChannel();
}
catch (Exception e)
{
Logger.Add("Exception occured while trying to connect. " + e.Message);
if (client != null)
{
((ICommunicationObject)client).Abort();
}
return false;
}
return true;
}
Na różnych forach czytałem, że problemem może być MaxReceivedMessageSize, ale zwiększyłe u siebie tą wartość i nie pomogło