2012-05-14 3 views
4

Im essayant d'obtenir une image du service WCF
j'ai une fonction OperationContract qui renvoie une image au client,
mais quand je l'appelle du client i obtenir cette exception: 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'.retour Image de méthode OperationContract (service WCF)

client:

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 Interface:

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

alors pourquoi est que cela se produise et comment puis-je résoudre ce problème?

+0

Vous voudrez peut-être jeter un oeil à WCF [grandes quantités de données et Streaming] (http://msdn.microsoft.com/en-us/library/ms733742.aspx). –

+0

@JoshuaDrake j'ai déjà lu à ce sujet, mais je ne comprenais pas tout, j'ai seulement compris que je devrais utiliser Streamed au lieu de tamponné si je veux transférer une grande quantité de données! mais est-ce, je change tamponné à streamed alors j'ai eu l'image? –

+0

Pouvez-vous essayer de changer le format de l'image en jpg plutôt qu'en png. Parfois, le streaming png a des problèmes. – Rajesh

Répondre

6

Je l'ai compris.

  • Première utilisation TransferMode.Streamed // ou StreamedResponse dépend de votre besoin.
  • retourner le flux, et n'oubliez pas de définir Stream.Postion = 0 alors commencez à lire le flux depuis le début.

au service:

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; 
     } 
    } 

Interface:

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

sur le côté client:

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

désolé, puis-je vous poser une question sur le code ci-dessus? Qu'est-ce que 'img' dans la ligne de code "img = Image.FromStream (ms);"? –

+0

@ NguyễnHuy Désolé, je n'ai pas vu ce commentaire jusqu'à maintenant, j'ai oublié de l'enlever, c'est réglé maintenant –

1

Vous devrez définir quelque chose qui est sérialisable. System.Drawing.Image est, mais pas dans le cotnext de WCF (using DataContractSerializer) par défaut. Cela peut aller du retour des octets bruts sous la forme d'un tableau, ou de la sérialisation à une chaîne (base64, JSON) ou de l'implémentation d'un DataContract sérialisable pouvant transporter les données.

Comme d'autres l'ont dit, WCF prend en charge le streaming, mais ce n'est pas le noeud du problème ici. En fonction de la taille des données, vous souhaiterez peut-être le faire, ce qui réduira le problème en lui-même puisque vous diffuserez des octets (à partir d'une vue visible de haut niveau).

Vous pouvez également take a look at this answer pour vous aider à obtenir les détails de l'exception réelle, comme une pile complète au lieu de simplement l'information de défaut.

+0

alors je dois déclarer une nouvelle classe qui contient l'image et la renvoie au client? –

+0

Je le ferais, ou une alternative comme suggéré. Je n'essaierais pas d'appuyer sur une occurrence d'Image par un crochet ou un escroc. –

+0

Je veux éviter d'utiliser Sockets pour recevoir l'image, je veux la retourner d'une manière agréable, avez-vous une bonne idée? –

Questions connexes