2012-05-14 3 views
4

Im пытается получить изображение от службы WCF
У меня есть функция OperationContract, которая возвращает изображение к клиенту,
но когда я называю его от клиента я получаю это исключение: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.9619978'.возвращения изображение из метода OperationContract (службы WCF)

Клиент:

private void btnNew_Click(object sender, EventArgs e) 
    { 
     picBox.Picture = client.GetScreenShot(); 
    } 

Service.cs:

public Image GetScreenShot() 
    { 
     Rectangle bounds = Screen.GetBounds(Point.Empty); 
     using (Bitmap bmp = new Bitmap(bounds.Width,bounds.Height)) 
     { 
      using (Graphics g = Graphics.FromImage(bmp)) 
      { 
       g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size); 
      } 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png); 
       return Image.FromStream(ms); 
      } 
     } 
    } 

IScreenShot Интерфейс:

[ServiceContract] 
public interface IScreenShot 
{ 
    [OperationContract] 
    System.Drawing.Image GetScreenShot(); 
} 

так почему это происходит и как это исправить?

+0

Вы можете захотеть взглянуть на WCF [больших объемов данных и потокового] ​​(http://msdn.microsoft.com/en-us/library/ms733742.aspx). –

+0

@JoshuaDrake Я ранее читал об этом, но я не мог все понять, я только понял, что я должен использовать Streamed вместо буферизации, если я хочу передать большой объем данных! но что это, я меняю буферизацию на потоковое, тогда я получил изображение? –

+0

Можете ли вы попытаться изменить формат изображения на jpg, а не на png. Иногда потоки png имеют проблемы. – Rajesh

ответ

6

Я понял это.

  • Первое использование TransferMode.Streamed // или StreamedResponse зависит от ваших потребностей.
  • верните поток и не забудьте установить Stream.Postion = 0, поэтому начните читать поток с самого начала.

в обслуживании:

public Stream GetStream() 
    { 
     Rectangle bounds = Screen.GetBounds(Point.Empty); 
     using (Bitmap bmp = new Bitmap(bounds.Width, bounds.Height)) 
     { 
      using (Graphics g = Graphics.FromImage(bmp)) 
      { 
       g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size); 
      } 
      MemoryStream ms = new MemoryStream(); 
      bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 
      ms.Position = 0; //This's a very important 
      return ms; 
     } 
    } 

интерфейс:

[ServiceContract] 
public interface IScreenShot 
{ 
    [OperationContract] 
    Stream GetStream(); 
} 

на стороне клиента:

public partial class ScreenImage : Form 
{ 
    ScreenShotClient client; 
    public ScreenImage(string baseAddress) 
    { 
     InitializeComponent(); 
     NetTcpBinding binding = new NetTcpBinding(SecurityMode.None); 
     binding.TransferMode = TransferMode.StreamedResponse; 
     binding.MaxReceivedMessageSize = 1024 * 1024 * 2; 
     client = new ScreenShotClient(binding, new EndpointAddress(baseAddress)); 
    } 

    private void btnNew_Click(object sender, EventArgs e) 
    { 
     picBox.Image = Image.FromStream(client.GetStream()); 
    } 
} 
+1

Извините, могу я задать вам вопрос о коде выше? Что такое «img» в строке кода «img = Image.FromStream (ms);»? –

+0

@ NguyễnHuy Извините, что я не видел этот комментарий до сих пор, я забыл его удалить, теперь исправлено –

1

Вам нужно будет определить что-то сериализуемое. System.Drawing.Image есть, но не в cotnext из WCF (с использованием DataContractSerializer) по умолчанию. Это может варьироваться от возврата необработанных байтов в виде массива или сериализации до строки (base64, JSON) или реализации DataContract, который является сериализуемым и может переносить данные с ним.

Как говорили другие, WCF поддерживает потоковое вещание, но здесь дело не в этом. В зависимости от размера данных, которые вы, возможно, захотите сделать, и это уменьшит проблему сама по себе, так как вы будете передавать потоки (из очевидного верхнего уровня).

Вы также можете использовать take a look at this answer, чтобы помочь вам получить фактические данные об исключении, например, полную стеклу, а не только информацию об ошибке.

+0

, поэтому мне нужно объявить новый класс, который содержит изображение и вернуть его клиенту? –

+0

Я бы или альтернатива, как предполагалось. Я бы не попытался нажать на экземпляр изображения с помощью крючка или мошенника. –

+0

Я хочу, чтобы избежать использования сокетов для получения изображения, я хочу, чтобы вернуть его в хорошем смысле, у вас есть хорошая идея? –

Смежные вопросы