none
求助一下。TCP双工WCF。添加了mex之后,就报错,无法启动服务。 RRS feed

  • 问题

  •  <system.serviceModel>
      <services>
       <service behaviorConfiguration="Service2Behavior" name="SevenPrincess.Server.WCF.Service.Service.IM.IMConnect">
        <endpoint address="IMConnect" binding="netTcpBinding"
             bindingConfiguration="netTcpConnectConfigration" contract="SevenPrincess.Server.WCF.Service.Interface.IM.IIMConnect"/>
        <endpoint address="IMConnect/mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
        <host>
         <baseAddresses>
          <add baseAddress="net.tcp://localhost:601/IM/"/>
         </baseAddresses>
        </host>
       </service>
      </services>
      <behaviors>
       <serviceBehaviors>
        <behavior name="Service2Behavior">
         <serviceMetadata httpGetEnabled="false"/>
         <serviceDebug includeExceptionDetailInFaults="False"/>
         <serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000" maxConcurrentInstances="1000"/>
         <serviceCredentials>
          <serviceCertificate storeName="My" findValue="WCFService" storeLocation="LocalMachine" x509FindType="FindBySubjectName"/>
         </serviceCredentials>
        </behavior>
       </serviceBehaviors>
      </behaviors>
      <bindings>
       <netTcpBinding>
        <binding name="netTcpConnectConfigration" maxConnections="5000" receiveTimeout="00:10:00" sendTimeout="00:10:00" portSharingEnabled="true">
         <reliableSession inactivityTimeout="01:10:00" enabled="true"/>
         <security mode="Transport">
          <transport clientCredentialType="None"/>
         </security>
        </binding>
       </netTcpBinding>
      </bindings>
     </system.serviceModel>
    

    先来贴上配置文件内容。

    2张截图。

     






    我并没有创建host服务,而是直接使用wcf项目自带的test host。项目中使用发现服务来自动创建客户端代码。

     

    但是现在遇到的问题是,只要在配置中添加了mex,就会出错了。出错内容如下:

     

    System.ServiceModel.AddressAlreadyInUseException: There is already a listener on IP endpoint 0.0.0.0:10001.  Make sure that you are not trying to use this endpoint multiple times in your application and that there are no other applications listening on this endpoint. ---> System.Net.Sockets.SocketException: 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。
       at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
       at System.Net.Sockets.Socket.Bind(EndPoint localEP)
       at System.ServiceModel.Channels.SocketConnectionListener.Listen()
       --- End of inner exception stack trace ---
       at System.ServiceModel.Channels.SocketConnectionListener.Listen()
       at System.ServiceModel.Channels.ConnectionAcceptor.StartAccepting()
       at System.ServiceModel.Channels.ExclusiveTcpTransportManager.OnOpen()
       at System.ServiceModel.Channels.TransportManager.Open(TransportChannelListener channelListener)
       at System.ServiceModel.Channels.TransportManagerContainer.Open(SelectTransportManagersCallback selectTransportManagerCallback)
       at System.ServiceModel.Channels.TcpChannelListener`2.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)
    System.Net.Sockets.SocketException (0x80004005): 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。
       at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
       at System.Net.Sockets.Socket.Bind(EndPoint localEP)
       at System.ServiceModel.Channels.SocketConnectionListener.Listen()

    如果不添加mex,则服务能够启动。但是没法自动生成代码。


    2010年8月23日 7:06

全部回复

  • 服务器端的代码:

     

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.ServiceModel;
    using Microsoft.Practices.EnterpriseLibrary.Logging;
    using SevenPrincess.Server.WCF.Service.Interface.IM;
    using IMBLL = SevenPrincess.Server.Database.BLL.IM;
    using IMModel = SevenPrincess.Server.WCF.Entity.IM;
    
    namespace SevenPrincess.Server.WCF.Service.Service.IM
    {
      /// <summary>
      /// IM账号登录信息WCF方法
      /// </summary>
      [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
      public class IMConnect : IIMConnect
      {
        private static Dictionary<IIMConnectCallback, object[]> dic_Client;
    
        static IMConnect()
        {
          dic_Client = new Dictionary<IIMConnectCallback, object[]>();
        }
    
        public IMConnect()
        {
          OperationContext.Current.Channel.Faulted += ClientClosed;
        }
    
        void ClientClosed(object sender, EventArgs e)
        {
          Disconnect();
        }
    
        object[] GetClient(IIMConnectCallback p_CallbackEventHandler)
        {
          if (dic_Client.ContainsKey(p_CallbackEventHandler))
          {
            return dic_Client[p_CallbackEventHandler];
          }
          else
          {
            return null;
          }
        }
    
        /// <summary>
        /// 添加登录记录
        /// </summary>
        /// <param name="p_IMConnect">IM登录信息</param>
        /// <param name="p_EmployeeNickname">员工昵称</param>
        /// <param name="p_EmployeeName">员工姓名</param>
        /// <param name="p_Token">登录验证票据</param>
        public void Add(IMModel.IMConnect p_IMConnect, string p_EmployeeNickname, string p_EmployeeName, string p_Token)
        {
          IIMConnectCallback callbackEventHandler = OperationContext.Current.GetCallbackChannel<IIMConnectCallback>();
    
          try
          {
            p_IMConnect.ConnectTime = DateTime.Now;
            p_IMConnect.LastActiveTime = p_IMConnect.ConnectTime;
            IMBLL.IMConnect bll_IMConnect = new IMBLL.IMConnect();
            int[] int_IDs = bll_IMConnect.Add(p_IMConnect);
    
            if (int_IDs[1] > 0)
            {
              p_IMConnect.ID = int_IDs[0];
    
              object[] obj_Client = new object[3];
              obj_Client[0] = p_IMConnect;
              obj_Client[1] = p_EmployeeNickname;
              obj_Client[2] = p_EmployeeName;
    
              dic_Client.Add(callbackEventHandler, obj_Client);
    
              callbackEventHandler.ResponseAdd(int_IDs[0], p_IMConnect.ConnectTime);
            }
            else
            {
              callbackEventHandler.ResponseAdd(int_IDs[0], p_IMConnect.ConnectTime);
            }
          }
          catch (Exception e)
          {
            LogEntry log = new LogEntry
            {
              EventId = 1,
              Priority = 1,
              Severity = TraceEventType.Error,
              Title = "添加登录记录",
              TimeStamp = DateTime.Now,
              Message = e.Message
            };
    
            ICollection<string> coll = new List<string>();
            coll.Add("IM.IMConnect");
            log.Categories = coll;
    
            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("EmployeeID", p_IMConnect.EmployeeID);
            dic.Add("IMAccountID", p_IMConnect.IMAccountID);
            dic.Add("IMID", p_IMConnect.IMID);
            dic.Add("EmployeeNickname", p_EmployeeNickname);
            dic.Add("EmployeeName", p_EmployeeName);
    
            log.ExtendedProperties = dic;
    
            Logger.Write(log);
    
            callbackEventHandler.ResponseAdd(-1, p_IMConnect.ConnectTime);
          }
        }
    
        /// <summary>
        /// 更新最后活动时间
        /// </summary>
        /// <param name="p_ID">ID</param>
        /// <param name="p_Token">登录验证票据</param>
        /// <returns>更新状态</returns>
        public int? UpdateLastActiveTime(int p_ID, string p_Token)
        {
          try
          {
            IMBLL.IMConnect bll_IMConnect = new IMBLL.IMConnect();
            return bll_IMConnect.UpdateLastActiveTime(p_ID, DateTime.Now);
          }
          catch (Exception e)
          {
            LogEntry log = new LogEntry
            {
              EventId = 2,
              Priority = 1,
              Severity = TraceEventType.Error,
              Title = "更新最后活动时间",
              TimeStamp = DateTime.Now,
              Message = e.Message
            };
    
            ICollection<string> coll = new List<string>();
            coll.Add("IM.IMConnect");
            log.Categories = coll;
    
            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("p_ID", p_ID);
    
            log.ExtendedProperties = dic;
    
            Logger.Write(log);
    
            return null;
          }
        }
    
        /// <summary>
        /// 断开连接
        /// </summary>
        public void Disconnect()
        {
          IIMConnectCallback callbackEventHandler = OperationContext.Current.GetCallbackChannel<IIMConnectCallback>();
          object[] client = GetClient(callbackEventHandler);
    
          if (client != null)
          {
            IMModel.IMConnect mol_IMConnect = client[0] as IMModel.IMConnect;
            string str_EmployeeNickname = client[1] as string;
            string str_EmployeeName = client[2] as string;
    
            try
            {
              IMBLL.IMConnect bll_IMConnect = new IMBLL.IMConnect();
              bll_IMConnect.UpdateDisconnectTime(mol_IMConnect.ID, DateTime.Now, str_EmployeeNickname, str_EmployeeName);
    
              dic_Client.Remove(callbackEventHandler);
            }
            catch (Exception e)
            {
              LogEntry log = new LogEntry
              {
                EventId = 3,
                Priority = 1,
                Severity = TraceEventType.Error,
                Title = "断开连接",
                TimeStamp = DateTime.Now,
                Message = e.Message
              };
    
              ICollection<string> coll = new List<string>();
              coll.Add("IM.IMConnect");
              log.Categories = coll;
    
              Dictionary<string, object> dic = new Dictionary<string, object>();
              dic.Add("ID", mol_IMConnect.ID);
              dic.Add("DisconnectTime", DateTime.Now);
              dic.Add("EmployeeNickname", str_EmployeeNickname);
              dic.Add("EmployeeName", str_EmployeeName);
    
              log.ExtendedProperties = dic;
    
              Logger.Write(log);
            }
          }
        }
    
        /// <summary>
        /// 取得IM登录信息记录列表
        /// <param name="p_EmployeeID">员工ID</param>
        /// <param name="p_BeginTime">开始时间</param>
        /// <param name="p_EndTime">结束时间</param>
        /// <param name="p_Token">登录验证票据</param>
        /// <returns>IM登录信息记录列表</returns>
        /// </summary>
        public List<IMModel.IMConnect> GetList(int p_EmployeeID, DateTime p_BeginTime, DateTime p_EndTime, string p_Token)
        {
          try
          {
            IMBLL.IMConnect bll_IMConnect = new IMBLL.IMConnect();
            return bll_IMConnect.GetList(p_EmployeeID, p_BeginTime, p_EndTime);
          }
          catch (Exception e)
          {
            LogEntry log = new LogEntry
            {
              EventId = 4,
              Priority = 1,
              Severity = TraceEventType.Error,
              Title = "取得IM登录信息记录列表",
              TimeStamp = DateTime.Now,
              Message = e.Message
            };
    
            ICollection<string> coll = new List<string>();
            coll.Add("IM.IMConnect");
            log.Categories = coll;
    
            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("p_EmployeeID", p_EmployeeID);
            dic.Add("p_BeginTime", p_BeginTime);
            dic.Add("p_EndTime", p_EndTime);
    
            log.ExtendedProperties = dic;
    
            Logger.Write(log);
    
            return null;
          }
        }
      }
    }
    
    using System;
    using System.Collections.Generic;
    using System.ServiceModel;
    using IMModel = SevenPrincess.Server.WCF.Entity.IM;
    
    namespace SevenPrincess.Server.WCF.Service.Interface.IM
    {
      /// <summary>
      /// IM账号登录信息WCF接口
      /// </summary>
      [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IIMConnectCallback))]
      public interface IIMConnect
      {
        /// <summary>
        /// 添加登录记录
        /// </summary>
        /// <param name="p_IMConnect">IM登录信息</param>
        /// <param name="p_EmployeeNickname">员工昵称</param>
        /// <param name="p_EmployeeName">员工姓名</param>
        /// <param name="p_Token">登录验证票据</param>
        [OperationContract(IsOneWay = true)]
        void Add(IMModel.IMConnect p_IMConnect, string p_EmployeeNickname, string p_EmployeeName, string p_Token);
    
        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="p_ID">ID</param>
        /// <param name="p_DisconnectTime">离线时间</param>
        /// <param name="p_EmployeeNickname">员工昵称</param>
        /// <param name="p_EmployeeName">员工姓名</param>
        /// <param name="p_Token">登录验证票据</param>
        /// <returns>更新状态</returns>
        [OperationContract(IsOneWay = true)]
        void Disconnect();
    
        /// <summary>
        /// 更新最后活动时间
        /// </summary>
        /// <param name="p_ID">ID</param>
        /// <param name="p_Token">登录验证票据</param>
        /// <returns>更新状态</returns>
        [OperationContract]
        int? UpdateLastActiveTime(int p_ID, string p_Token);
    
        /// <summary>
        /// 取得IM登录信息记录列表
        /// <param name="p_EmployeeID">员工ID</param>
        /// <param name="p_BeginTime">开始时间</param>
        /// <param name="p_EndTime">结束时间</param>
        /// <param name="p_Token">登录验证票据</param>
        /// <returns>IM登录信息记录列表</returns>
        /// </summary>
        [OperationContract]
        List<IMModel.IMConnect> GetList(int p_EmployeeID, DateTime p_BeginTime, DateTime p_EndTime, string p_Token);
      }
    }
    
    

    2010年8月23日 7:08
  • 这个问题 怎么搞定的?

    你把解决办法给大家说一下

    我记得Console托管是没问题的。


    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
     

    老徐的网站】:http://www.frankxulei.com/

    老徐的博客】:http://www.cnblogs.com/frank_xl/

    微软WCF中文技术论坛
    微软WCF英文技术论坛

    2010年8月25日 12:50
    版主
  • 你提供的config文件是否有错?错误信息显示10001端口有问题,而配置节使用的是601.

    你尝试换个端口,有时端口占用状态不能被立即释放。


    Mog Liang
    2010年8月26日 7:56