簡體   English   中英

客戶端的WCF服務器/客戶端數量

[英]WCF server/client count of clients

我在WCF中創建了服務器/客戶端應用程序。 如何獲得連接客戶的數量? 我怎樣才能向所有人發送oder工作? 例如:Serwer向每個客戶端發送要添加的其他號碼。

Client1 - 1+2=3
Client2 - 1+3=4
Client3 - 1+4=5

並將結果發送到服務器,從客戶端添加每個結果我返回值(12)。

我的簡單應用:

/////編輯/////

服務器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Interface;

namespace WCFapp
{
    class Program
    {
        static void Main(string[] args)
        {
            Klienci cust = new Klienci();
            cust.Connect();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Interface;

namespace WCFapp
{
     [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class Klienci : IMessage
{
    private static List<ImessageCallback> subscribers =
        new List<ImessageCallback>();

    public void lista()
    {
        string nm = Console.ReadLine();
        if (nm == "1")
        {
            Console.WriteLine("Number of conected clients: " + subscribers.Count());
            funkcja();

        }
    }

    public void Connect()
    {
        using (ServiceHost host = new ServiceHost(
            typeof(Klienci), new Uri("net.tcp://localhost:8000")))
        {
            host.AddServiceEndpoint(typeof(IMessage),
                new NetTcpBinding(), "ISubscribe");

            try
            {
                host.Open();
                lista();
                Console.ReadLine();
                host.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }

    public bool Subscribe()
    {
        try
        {
            ImessageCallback callback = OperationContext.Current.GetCallbackChannel<ImessageCallback>();
            if (!subscribers.Contains(callback))
                subscribers.Add(callback);
            Console.WriteLine("Client is conected ({0}).", callback.GetHashCode());
            return true;
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            return false;
        }
    }

    public bool Unsubscribe()
    {
        try
        {
            ImessageCallback callback = OperationContext.Current.GetCallbackChannel<ImessageCallback>();
            if (subscribers.Contains(callback))
                subscribers.Remove(callback);
            Console.WriteLine("Client is unconected ({0}).", callback.GetHashCode());
            return true;
        }
        catch
        {
            return false;
        }
    }

    public void funkcja()
    {
        int a = 1; int b = 3;
        subscribers.ForEach(delegate(ImessageCallback callback)
        {
            if (((ICommunicationObject)callback).State == CommunicationState.Opened)
            {
            Console.WriteLine("a= {0} , b= {1}", a, b);
            callback.klient_licz(a, b);
            a++;
            b++;
            }
        });

    }

    public void polacz(int S)
    {

        Console.WriteLine("Sum: {0}", S);
    }
  }
}

接口:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;


namespace Interface
{
     [ServiceContract(CallbackContract = typeof(ImessageCallback), SessionMode = SessionMode.Required)]
public interface IMessage
{
    [OperationContract]
    void funkcja();

    [OperationContract]
    void polacz(int S);

    [OperationContract]
    bool Subscribe();

    [OperationContract]
    bool Unsubscribe();

}
[ServiceContract]
public interface ImessageCallback
{
    [OperationContract]
    void klient_licz(int a, int b);
}

}

客戶:

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Interface;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            clients cl = new clients();
            if (cl.Conect() == true)
            {
                string tmp = Console.ReadLine();
                while (tmp != "EXIT")
                {
                    cl.SendMessage(tmp);
                    tmp = Console.ReadLine();
                }

            }
             cl.Close();
             Environment.Exit(0);
       }
   }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Interface;

namespace Client
{
    class clients : ImessageCallback, IDisposable
    {
        IMessage pipeProxy = null;
        public bool Conect()
        {
            DuplexChannelFactory<IMessage> pipeFactory =
                new DuplexChannelFactory<IMessage>(
                    new InstanceContext(this),
                    new NetTcpBinding(),
                    new EndpointAddress("net.tcp://localhost:8000/ISubscribe"));
            try
            {
                pipeProxy = pipeFactory.CreateChannel();
                pipeProxy.Subscribe();
               return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return false;
            }

        }

        public void Close()
        {
            pipeProxy.Unsubscribe();
        }


        public void klient_licz(int a, int b)
        {
            int S = a + b;
            Console.WriteLine("Sum= {0}", S);
            pipeProxy.polacz(S); //ERROR
        }

    }
}

我編輯了代碼。 現在我在pipeproxy.polacz(S)中遇到異常; 功能; /

This operation would deadlock because the reply cannot be received until the current Message completes processing. If you want to allow out-of-order message processing, specify ConcurrencyMode of Reentrant or Multiple on CallbackBehaviorAttribute.

服務器負責緩存客戶端列表。 通常,這將是客戶端回調接口列表:

List<IClientCallback> clients; 

通常,您從傳入的客戶端調用(通常在特定的服務器方法,如“RegisterClient”)中填寫此函數 - 但可以是服務器上的任何傳入呼叫:

IClientCallback callback = OperationContext.Current.GetCallbackChannel<IClientCallback>();              
if (!clients.Contains(callback))
    clients.Add(callback);

要管理對客戶端的廣播,您需要一個通用方法在客戶端列表中的所有客戶端上回調一個particualr方法:

void CallbackAllClients(Action<IClientCallback> action) {
    for (int i=clients.Count-1; i >= 0; i--) {
        IClientCallback callback = clients[i];
        if (((ICommunicationObject)callback).State == CommunicationState.Opened) {
            try {
                action(callback);
            }
            catch (Exception e) {
                clients.RemoveAt(i);
            }
        }
        else
            clients.RemovaAt(i);
    }
}

您可以從服務器代碼調用它來向所有客戶端廣播客戶端回調,如下所示:

void SomeServerSideEventHandler(MyObject my_obj) {
    CallbackAllClients(client => client.MyObjectChanged(my_obj));
} 

其中MyObjectChanged是客戶端回調接口IClientCallback上的一種方法。 這應該會讓你大部分時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM