【问题标题】:Unable to read bytes in WCF Streamed transfer mode in UWP无法在 UWP 中的 WCF 流传输模式下读取字节
【发布时间】:2021-01-05 18:31:55
【问题描述】:

我有一个 UWP 客户端应用程序,它使用 WCF 流传输模式与 Windows 服务应用程序通信:

var bnd = new NetTcpBinding(SecurityMode.None) { TransferMode = TransferMode.Streamed }

我在契约方法中使用了 Stream 对象作为请求和响应参数。

[OperationContract]
Stream RequestEncrypt(Stream data);

但我无法从 UWP 代码中的 Stream 对象响应中读取字节数组:

using (var memStream = new MemoryStream())
{
    sourceStream.CopyTo(memStream);
    byteArray = memStream.ToArray();
}

在上面的代码中,CopyTo 方法永远挂起。控制永远不会返回到下一行。 但这在 Windows 控制台客户端应用程序中运行良好。

有人有想法吗?

【问题讨论】:

  • 默认情况下阻止 UWP 与本地主机的连接。查看 MSDN 中的“环回 UWP”
  • UWP 客户端和服务应用程序之间的连接工作正常。上例中调用 RequestEncrypt 方法后,客户端收到一个 Stream 对象。但我无法从收到的 Stream 对象中读取字节数组。仅当我在绑定中将 TransferMode 设置为 Streamed 时才会出现此问题。

标签: c# wcf uwp


【解决方案1】:

CopyTo 方法永远挂起是什么意思?有没有遇到异常?我测试并没有发现任何问题。这是我的演示:

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface ICalculator
    {
        [OperationContract]
        Stream RequestEncrypt();
    }
    public class Calcuator : ICalculator
    {
        public Stream RequestEncrypt()
        {
             
            string str = "i am a string";
            byte[] array = Encoding.ASCII.GetBytes(str);
            MemoryStream stream = new MemoryStream(array);
            StreamReader reader = new StreamReader(stream);
            return stream;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            // Step 1: Create a URI to serve as the base address.
            Uri baseAddress = new Uri("net.tcp://localhost:8000/GettingStarted/");

            // Step 2: Create a ServiceHost instance.
            ServiceHost selfHost = new ServiceHost(typeof(Calcuator), baseAddress);

            try
            {
                NetTcpBinding netTcpBinding = new NetTcpBinding(SecurityMode.None) { TransferMode = TransferMode.Streamed };
               
               
                // Step 3: Add a service endpoint.
                selfHost.AddServiceEndpoint(typeof(ICalculator), netTcpBinding, "CalculatorService");

                // Step 4: Enable metadata exchange.
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                // smb.HttpGetEnabled = true;
                selfHost.Description.Behaviors.Add(smb);

                Binding mexbinding = MetadataExchangeBindings.CreateMexTcpBinding();
                selfHost.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");

                // Step 5: Start the service.
                selfHost.Open();
                Console.WriteLine("The service is ready.");

                // Close the ServiceHost to stop the service.
                Console.WriteLine("Press <Enter> to terminate the service.");
                Console.WriteLine();
                Console.ReadLine();
                selfHost.Close();
            }
            catch (CommunicationException ce)
            {
                Console.WriteLine("An exception occurred: {0}", ce.Message);
                selfHost.Abort();
            }
        }
    }

这是 WCF 服务。

在UWP中,我成功获取到Stream,并转换成字符串。

更新:

您可以尝试增加邮件大小配额:

<bindings>
    <NetTcpBinding>
        <binding name="NetTcpBinding"
                 maxReceivedMessageSize="20000000" 
                 maxBufferSize="20000000"
                 maxBufferPoolSize="20000000">
            <readerQuotas maxDepth="32" 
                 maxArrayLength="200000000"
                 maxStringContentLength="200000000"/>
        </binding>
    </NetTcpBinding>
</bindings>

【讨论】:

  • 问题不是很一致。它通常在数据太小时起作用。您能否让我知道当您发送大小为 10KB 或更大的文件的文件流时它是否适合您? (注意:我已将 MaxReceivedMessageSize 设置为 int.Max 值,当问题发生时,它不会抛出任何异常。但控制永远不会来自 CopyTo 或 stream.Read 方法)
  • 所以现在的问题是Stream太小可以正常运行,但是Stream太大就会出现这个问题吧?
  • 是的,当流数据超过 10kb 时会出现问题。
  • 我发现了问题。我的 UWP 应用程序仍然面向周年纪念版。在最新版本中,相同的代码可以正常工作。非常感谢您的努力!
猜你喜欢
  • 2012-04-15
  • 2015-01-26
  • 2022-09-27
  • 2011-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多