WCF广播消息给所有客户端

时间:2016-08-05 18:19:25

标签: c# wcf message broadcast

我有一个WCF服务和客户端应用程序 - 我在这种情况下使用命名管道。服务和客户能够相互通信。我想做的就是使用回调方法向所有客户端广播消息。

在服务中,我有两种方法可以让客户在服务中注册自己:

存储有关特定客户的信息的字典:

private static Dictionary<Guid, ICallbacks> clients = new Dictionary<Guid, ICallbacks>();

在服务中注册客户端的方法:

public void RegisterInService(Guid clientID)
{
            ICallbacks callback = OperationContext.Current.GetCallbackChannel<ICallbacks>();

            lock (clients)
            {
                if (!clients.ContainsKey(clientID))
                {
                    clients.Add(clientID, callback);
                }
            }
}

取消注册客户端的方法:

public void UnregisterFromService(Guid clientID)
{
            lock(clients)
            {
                if (clients.ContainsKey(clientID))
                    clients.Remove(clientID);
            }
}

WCF服务行为已按以下方式配置:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]

现在,在服务中我有另一种方法,让我们说更多&#34; advanced&#34;操作。在这个方法中,我想执行另一种方法来向所有注册的客户端广播消息。

以下是代码:

public void MainProcessActions()
{

            SendMessageToAllClients("Send to all clients ...");
}

private void SendMessageToAllClients(string data)
{
            StreamWriter file = new System.IO.StreamWriter(@"E:\Temp\ClientsInvokingEvidence.txt", true);

            lock (clients)
            {
                foreach (KeyValuePair<Guid, ICallbacks> client in clients)
                {

                    client.Value.UpdateClientData(data);

                    file.WriteLine("Invoking method for client ID : {0}", client.Key);

                }
            }

            file.Close();

}

这是接口中的回调方法声明:

public interface ICallbacks
{
        [OperationContract(IsOneWay = true)]
        void UpdateClientData(string data);
}

现在,让我们说我在内存中有三个客户端实例(一个应用程序执行三次)。一旦我从其中一个客户端调用方法MainProcessActions(),就只为该特定客户端执行回调方法。似乎其他客户端忽略了回调方法UpdateClientData(string data)

你能给我一些提示,我该如何解决这个问题?

简而言之,我想将服务中的数据发送给所有注册客户。

#edit

我有一些更新。 UpdateClientData(string data)方法实际上是由所有客户端执行的...问题在于使用从服务接收的数据来设置Windows窗体中的TextBox控件。

以下是此方法的主体:

public void UpdateClientData(string data)
{
     this.DataFromService = data;
}

稍后在代码I中使用属性DataFromService在MainForm类的TextBox控件中设置文本。

看起来TextBox控件的文本只能由一个客户端实例...

设置

有趣的是,当我将对TextBox控件的引用传递给实现UpdateClientData方法的类时,我可以同时在所有客户端的TextBox控件中设置文本。

有什么建议吗?

#edit

以下是我使用DataFromService属性的代码部分。

此属性是以下类的成员:

[CallbackBehavior(UseSynchronizationContext = false)]
class WCFServiceCommunication : ICallbacks
{
    public string DataFromService;

    ...

    public WCFServiceCommunication()
    {
        binding = new NetNamedPipeBinding();

        pipeFactory = new DuplexChannelFactory<IGeneralContract>(this, binding, new EndpointAddress("net.pipe://localhost/SomeName"));

        pipeProxy = pipeFactory.CreateChannel();

        ClientID = Guid.NewGuid();
    }

    public void ExecuteOnServiceSide()
    {
        pipeProxy.MainProcessActions();
    }

    public void RegisterClient()
    {
        pipeProxy.RegisterInService(ClientID);
    }

    public void UnregisterClient()
    {
        pipeProxy.UnregisterFromService(ClientID);
    }

    public void UpdateClientData(string data)
    {
        // here I'm able to verify that this method actually has been invoked by service for each instance of the client

        DataFromService = data;
    }

}

在UI代码(Windows窗体)中:

class MainForm : Form
{
    private WCFServiceCommunication wcfCommunication;
    ....

    public MainForm()
    {
        InitalizeComponent();

        wcfCommunication = new WCFServiceCommunication();

        wcfCommunication.RegisterClient();

    }

    ...

    private void btnCheckForUpdates_Click(object sender, EventArgs e)
    {
        // here, on service side method MainProcessActions() is called
        // in this method I'm calling broadcast method
        wcfCommunication.ExecuteOnServiceSide();

        textBox1.Text = wcfCommunication.DataFromService;
    }
}

另一个有趣的事情。当我将整个服务通信配置(创建通道,回调方法的实现)移动到MainForm类中时,一切正常 - 我能够为客户端的所有实例设置TextBox。

问候!

0 个答案:

没有答案