WCF聊天。客户端多次收到消息

时间:2014-09-17 06:11:31

标签: wpf wcf nettcpbinding

我是WCF和WPF的新手。我正在使用WCF和WPF开发客户端服务器聊天应用程序。我用过Nettcpbinding。客户端连接到聊天服务并在服务器上创建会话。然后,他们可以开始与所有连接的用户聊天。一段时间后,当几个人聊天时,一些客户会收到两次或三次聊天消息。 我搜索了类似的案例,但没有发现任何问题。 有谁知道会导致这个问题的原因是什么?

这是服务器上的app.config:

<?xml version="1.0" encoding="utf-8"?><configuration>
<system.serviceModel>
    <services>
        <service name="WCFService.Service" behaviorConfiguration="behaviorConfig">

            <host>
                <baseAddresses>
                    <add baseAddress="net.tcp://localhost:7997/LetsTalkHost/"/>
                    <add baseAddress="http://localhost:7998/LetsTalkHost/"/>
                </baseAddresses>
            </host>
            <endpoint bindingConfiguration="tcpBinding" address="tcp" binding="netTcpBinding" contract="ServiceAssembly.IChat"/>

            <endpoint address="net.tcp://localhost:7996/LetsTalkHost/mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="behaviorConfig">
                <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <bindings>
        <netTcpBinding>
            <binding name="tcpBinding" maxBufferSize="1073741824"     maxReceivedMessageSize="1073741824" maxBufferPoolSize="1073741824" transferMode="Buffered" closeTimeout="00:05:00" openTimeout="00:05:00" sendTimeout="00:05:00" maxConnections="1000" portSharingEnabled="false">
                <security mode="None">
                </security>
                <readerQuotas maxDepth="1073741824" maxNameTableCharCount="1073741824" maxArrayLength="1073741824" maxBytesPerRead="1073741824" maxStringContentLength="1073741824"/>
                <reliableSession enabled="true"/>
            </binding>
        </netTcpBinding>
    </bindings>
</system.serviceModel>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>

这是客户端上的app.config:

<?xml version="1.0" encoding="utf-8"?><configuration>
<system.serviceModel>
    <bindings>
        <netTcpBinding>
            <binding name="NetTcpBinding_IChat" closeTimeout="00:02:00" openTimeout="00:02:00"
               receiveTimeout="00:10:00" sendTimeout="00:02:00" transactionFlow="false"
               transferMode="Buffered" transactionProtocol="OleTransactions"
               hostNameComparisonMode="StrongWildcard" listenBacklog="10"
               maxBufferPoolSize="1073741824" maxBufferSize="1073741824" maxConnections="100"
               maxReceivedMessageSize="1073741824">
               <readerQuotas maxDepth="1073741824" maxStringContentLength="1073741824" maxArrayLength="1073741824"
                 maxBytesPerRead="1073741824" maxNameTableCharCount="1073741824" />
               <reliableSession enabled="true" />
               <security mode="None" />
            </binding>
        </netTcpBinding>
    </bindings>
    <client>
        <endpoint 
            binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IChat"
            contract="SVC.IChat" name="NetTcpBinding_IChat" />
    </client>
</system.serviceModel>  
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>

我使用以下项目作为示例:http://www.codeproject.com/Articles/25261/A-WCF-WPF-Chat-Application

主机(服务器)启动服务。该服务的代码如下:

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Runtime.Serialization;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls;

命名空间ServiceAssembly {

[DataContract]
public class Client
{
    private string _name; 
    private string _forname;
    private string _surname;
    private string _fullname;
    private string _nickname;
    private string _team;
    private string _telephone;
    private string _designation;
    private DateTime _time;

    [DataMember]
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
    [DataMember]
    public string Forname
    {
        get { return _forname; }
        set { _forname = value; }
    }
    [DataMember]
    public string Surname
    {
        get { return _surname; }
        set { _surname = value; }
    }
    [DataMember]
    public string Fullname
    {
        get { return _fullname; }
        set { _fullname = value; }
    }
    [DataMember]
    public string Nickname
    {
        get { return _nickname; }
        set { _nickname = value; }
    }
    [DataMember]
    public string Team
    {
        get { return _team; }
        set { _team = value; }
    }

    [DataMember]
    public string Telephone
    {
        get { return _telephone; }
        set { _telephone = value; }
    }

    [DataMember]
    public string Designation
    {
        get { return _designation; }
        set { _designation = value; }
    }

    [DataMember]
    public DateTime Time
    {
        get { return _time; }
        set { _time = value; }
    }
}

[DataContract]
public class Message
{
    private string _sender;
    private string _type;
    private string _content;
    private DateTime _time;

    [DataMember]
    public string Sender
    {
        get { return _sender; }
        set { _sender = value; }
    }
    [DataMember]
    public string Type
    {
        get { return _type; }
        set { _type = value; }
    }
    [DataMember]
    public string Content
    {
        get { return _content; }
        set { _content = value; }
    }
    [DataMember]
    public DateTime Time
    {
        get { return _time; }
        set { _time = value; }
    }
}

[DataContract]
public class FileMessage
{
    private string sender;
    private string fileName;
    private byte[] data;
    private DateTime time;

    [DataMember]
    public string Sender
    {
        get { return sender; }
        set { sender = value; }
    }

    [DataMember]
    public string FileName
    {
        get { return fileName; }
        set { fileName = value; }
    }

    [DataMember]
    public byte[] Data
    {
        get { return data; }
        set { data = value; }
    }

    [DataMember]
    public DateTime Time
    {
        get { return time; }
        set { time = value; }
    }
}

[ServiceContract(CallbackContract = typeof(IChatCallback), SessionMode = SessionMode.Required)]
public interface IChat
{
    [OperationContract(IsInitiating = true)]
    bool Connect(Client client);

    [OperationContract(IsOneWay = true)]
    void Say(Message msg);

    [OperationContract(IsOneWay = true)]
    void Whisper(Message msg, Client receiver);

    [OperationContract(IsOneWay = false)]
    bool SendFile(FileMessage fileMsg, Client receiver);

    [OperationContract(IsOneWay = true, IsTerminating = true)]
    void Disconnect(Client client);
}

public interface IChatCallback
{
    [OperationContract(IsOneWay = true)]
    void RefreshClients(List<Client> clients);

    [OperationContract(IsOneWay = true)]
    void Receive(Message msg);

    [OperationContract(IsOneWay = true)]
    void ReceiveWhisper(Message msg, Client receiver);


    [OperationContract(IsOneWay = true)]
    void ReceiverFile(FileMessage fileMsg, Client receiver);

    [OperationContract(IsOneWay = true)]
    void UserJoin(Client client);

    [OperationContract(IsOneWay = true)]
    void UserLeave(Client client);
}


[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
public class ChatService : IChat
{
    Dictionary<Client, IChatCallback> clients = new Dictionary<Client, IChatCallback>();

    List<Client> clientList = new List<Client>();

    public IChatCallback CurrentCallback
    {
        get
        {
            return OperationContext.Current.GetCallbackChannel<IChatCallback>();

        }
    }

    object syncObj = new object();

    private bool SearchClientsByName(string name)
    {
        foreach (Client c in clients.Keys)
        {
            if (c.Name == name)
            {
                return true;
            }
        }
        return false;
    }



    #region IChat Members

    public bool Connect(Client client)
    {
        if (!clients.ContainsValue(CurrentCallback) && !SearchClientsByName(client.Name))
        {
            lock (syncObj)
            {
                clients.Add(client, CurrentCallback);
                clientList.Add(client);

                foreach (Client key in clients.Keys)
                {
                    IChatCallback callback = clients[key];
                    try
                    {
                        callback.RefreshClients(clientList);
                        callback.UserJoin(client);
                    }
                    catch
                    {
                        clients.Remove(key);
                        return false;
                    }

                }

            }
            return true;
        }
        return false;
    }

    public void Say(Message msg)
    {
        lock (syncObj)
        {
            foreach (IChatCallback callback in clients.Values)
            {
                callback.Receive(msg);
            }
        }
    }

    public void Whisper(Message msg, Client receiver)
    {
        foreach (Client rec in clients.Keys)
        {
            if (rec.Forname == receiver.Forname)
            {
                IChatCallback callback = clients[rec];
                callback.ReceiveWhisper(msg, rec);

                foreach (Client sender in clients.Keys)
                {
                    if (sender.Forname == msg.Sender)
                    {
                        IChatCallback senderCallback = clients[sender];
                        senderCallback.ReceiveWhisper(msg, rec);
                        return;
                    }
                }
            }
        }
    }


    public bool SendFile(FileMessage fileMsg, Client receiver)
    {
        foreach (Client rcvr in clients.Keys)
        {
            if (rcvr.Name == receiver.Name)
            {
                Message msg = new Message();
                msg.Sender = fileMsg.Sender;
                msg.Content = "I'M SENDING FILE.. " + fileMsg.FileName;

                IChatCallback rcvrCallback = clients[rcvr];
                rcvrCallback.ReceiveWhisper(msg, receiver);
                rcvrCallback.ReceiverFile(fileMsg, receiver);

                foreach (Client sender in clients.Keys)
                {
                    if (sender.Name == fileMsg.Sender)
                    {
                        IChatCallback sndrCallback = clients[sender];
                        sndrCallback.ReceiveWhisper(msg, receiver);
                        return true;
                    }
                }
            }
        }
        return false;
    }


    public void Disconnect(Client client)
    {
        foreach (Client c in clients.Keys)
        {
            if (client.Name == c.Name)
            {
                lock (syncObj)
                {
                    this.clients.Remove(c);
                    this.clientList.Remove(c);
                    foreach (IChatCallback callback in clients.Values)
                    {
                        callback.RefreshClients(this.clientList);
                        callback.UserLeave(client);
                    }
                }
                return;
            }
        }
    }

    #endregion
}

}

0 个答案:

没有答案