[英]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.