我在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.
答案 0 :(得分:4)
服务器负责缓存客户端列表。通常,这将是客户端回调接口列表:
List<IClientCallback> clients;
通常,您从传入的客户端调用(通常在特定的服务器方法,如“RegisterClient”中)填充此函数 - 但可以是服务器上的任何传入呼叫:
IClientCallback callback = OperationContext.Current.GetCallbackChannel<IClientCallback>();
if (!clients.Contains(callback))
clients.Add(callback);
要管理对客户端的广播,您需要一个通用方法在客户端列表中的所有客户端上回调一个particalr方法:
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
上的方法。
这应该会让你大部分时间。