[英]C# WCF pass data from Task running on Server to Client
我是WCF地区的新手。 我想在服务器上制作屏幕截图,并使用WCF nettcpbinding将其发送给客户端。 在客户端上,我想使用这些数据更新UI。 但是我不知道我需要什么以及如何做到这一点。 我读了有关带回调的全双工合同,但我不知道这是否确实需要。
WPFClient.cs
namespace WPFClient
{
[ServiceContract]
interface IService
{
[OperationContract]
byte[] GetData();
}
public class ViewModel : INotifyPropertyChanged
{
private string bytesSum;
public string BytesSum
{
get { return bytesSum; }
set { bytesSum = value; this.NotifyPropertyChanged("BytesSum"); }
}
public ViewModel()
{
ChannelFactory<IService> channel = new ChannelFactory<IService>(new NetTcpBinding(), new EndpointAddress(@"net.tcp://localhost:8554/"));
IService s = channel.CreateChannel();
//How to get data from server and update UI?
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Server.cs
namespace Server
{
[ServiceContract]
interface IService
{
[OperationContract]
byte[] GetData();
}
public class Service : IService
{
public byte[] GetData()
{
byte[] result = new byte[5000];
return result;
}
}
public class ScreenLogger
{
public byte[] GenerateImage()
{
byte[] result = new byte[5000];
Random rnd = new Random();
for (int i = 0; i < result.Length; i++)
{
result[i] = (byte)rnd.Next();
}
return result;
}
public void Start()
{
var imageTask = Task.Factory.StartNew(() =>
{
byte[] GeneratedBytes = GenerateImage();
//How to send GeneratedBytes to client?
});
}
public void Stop()
{
}
}
class Program
{
static void Main(string[] args)
{
ScreenLogger screenLogger = new ScreenLogger();
screenLogger.Start();
ServiceHost host = new ServiceHost(typeof(Service));
host.AddServiceEndpoint(typeof(IService), new NetTcpBinding(), new Uri(@"net.tcp://localhost:8554/"));
Console.WriteLine("Server start");
host.Open();
Console.ReadLine();
host.Close();
}
}
}
您的IService
接口不是双工合同。 它应该指定客户端(即客户端应用程序中的视图模型)实现的回调协定。 然后,服务器端的服务实现将在回调上调用操作。
您可以在服务实现中使用OperationContext
类获得对回调的引用,如下所示:
var callback = OperationContext.Current.GetCallbackChannel<IYourDuplexCallback>();
然后,您调用回调方法将数据从服务器传递到客户端。 还有就是如何创建和安装MSDN上提供双工WCF服务的例子在这里 。
如何:创建双工合同: https : //docs.microsoft.com/zh-cn/dotnet/framework/wcf/feature-details/how-to-create-a-duplex-contract
在我看来,根据您的示例所执行的操作,看起来您只需要在服务实例可用的空间中获取Task
的结果即可。
我的简化版本具有服务合同和实施的属性:
[ServiceContract]
public interface IService
{
// not exposed
byte[] TaskResults { get; set; }
[OperationContract]
byte[] GetData();
}
public class Service : IService
{
public byte[] TaskResults { get; set; }
public byte[] GetData()
{
//byte[] result = new byte[5000];
//return result;
return TaskResults;
}
}
然后将ScreenLogger.Start()
签名更改为ScreenLogger.Start(Action<byte[]> bytesAction)
,以任务工作的结果调用该动作。
public void Start(Action<byte[]> bytesAction)
{
var imageTask = Task.Factory.StartNew(() =>
{
//var GeneratedBytes = GenerateImage();
//How to send GeneratedBytes to client?
bytesAction(GenerateImage());
});
}
最后传递一个将任务结果分配给service属性的动作。
static void Main(string[] args)
{
ScreenLogger screenLogger = new ScreenLogger();
ServiceHost host = new ServiceHost(typeof(Service));
screenLogger.Start(ba => ((Service)host.SingletonInstance).TaskResults = ba);
host.AddServiceEndpoint(typeof(IService), new NetTcpBinding(), new Uri(@"net.tcp://localhost:8554/"));
Console.WriteLine("Server start");
host.Open();
Console.ReadLine();
host.Close();
}
客户端代码(简化)如下所示。
public class ViewModel
{
private string bytesSum;
public string BytesSum
{
get { return bytesSum; }
set { bytesSum = value; this.NotifyPropertyChanged("BytesSum"); }
}
public ViewModel()
{
ChannelFactory<IService> channel = new ChannelFactory<IService>(new NetTcpBinding(), new EndpointAddress(@"net.tcp://localhost:8554/"));
IService s = channel.CreateChannel();
//How to get data from server and update UI?
s.GetData().ToList().ForEach(b => Console.Write(b));
}
private void NotifyPropertyChanged(String propertyName = "")
{
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.