1

以下は、デュプレックス サービスとその WebConfig ファイルです。このサービスでは、送信クライアントはTransmitUserDataメソッドを介してデータを送信し、受信クライアントはCallBackContract からPublishUserDataを介してデータを受信します。

ここでの問題は、初めてクライアントを実行すると完全に機能しますが、クライアントを再実行すると while Transmittingで次のエラーが発生することです。

通信オブジェクト System.ServiceModel.Channels.ServiceChannel は中止されたため、通信に使用できません。

二重サービス契約

 [ServiceContract(CallbackContract=typeof(IContactManagerCallBackService))]
    public interface IContactManagerUserService
    {
        [OperationContract(IsOneWay = true)]
        void SubscribeAsReceiver();

        [OperationContract(IsOneWay = true)]
        void SubscribeAsTransmitter();

        [OperationContract]
        void TransmitUserData(UserInfo info);

    }

    [ServiceContract]
    public interface IContactManagerCallBackService
    {
        [OperationContract(IsOneWay = true)]
        void PublishUserData(UserInfo info);        
    }

    [DataContract]
    public class UserInfo
    {
        [DataMember]
        public bool PaidUser { get; set; }

        [DataMember]
        public string ProfileName{ get; set;}

        [DataMember]
        public string ComputerName { get; set; }

        [DataMember]
        public string IPAddress { get; set; }

        [DataMember]
        public string MACAddress { get; set; }
    }

サービスの実装

   [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
    public class ContactManagerUserService : IContactManagerUserService
    {
        SynchronizedCollection<IContactManagerCallBackService> receiverClients;

        public ContactManagerUserService()
        {
            receiverClients = new SynchronizedCollection<IContactManagerCallBackService>();
        }   

        public void SubscribeAsReceiver()
        {
            IContactManagerCallBackService client = OperationContext.Current.GetCallbackChannel<IContactManagerCallBackService>();
            receiverClients.Add(client);
        }   

        public void TransmitUserData(UserInfo info)
        {
            foreach (IContactManagerCallBackService receiverClient in receiverClients)
            {
                receiverClient.PublishUserData(info);                       
            }                
        }   

Web.config

 <system.serviceModel>
    <diagnostics>
      <messageLogging logEntireMessage="true" logMalformedMessages="true"
        logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
    </diagnostics>
    <bindings>
      <netTcpBinding>
        <binding name="NewBinding0" maxConnections="1000"
          portSharingEnabled="true">
          <security mode="None" />
        </binding>
      </netTcpBinding>
    </bindings>
    <services>
      <service name="ContactManagerService.ContactManagerUserService">
        <endpoint address="mex" binding="netTcpBinding" bindingConfiguration=""
          name="dataEndPoint" contract="ContactManagerService.IContactManagerUserService" />
        <endpoint binding="mexTcpBinding" bindingConfiguration="" name="mexHttp"
          contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost/ContactManagerUserService" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

編集:

コードは初めて完全に実行されます。実際、問題は送信機によって作成されます。送信機は、購読または購読解除することはありません。 ここに画像の説明を入力

4

2 に答える 2

1

1) IErrorHandleを使用して、この例外をキャッチできます (役立つ場合があります)。多くの場合、コールバック中に例外がスローされます (シリアル化/(un)KnownType(s) の問題)。

2) サーバー/サービス側 (svclog) に問題が見られない場合 - 通信アボートの根本的な原因はクライアントにある可能性があります。クライアントでのコールバックの実装を見てください。コールバック メソッドで例外がスローされ (イベント ハンドラーの発生など)、それが飲み込まれた場合 (または、何らかの理由で例外を見逃した場合、おそらく UI スレッドなどでスローされなかったために例外が発生した場合...デバッガーは通知しませんでした) - それは(またはその可能性があります) 通信を中止します (クライアント プロキシに障害が発生します)。

于 2013-03-01T10:32:27.403 に答える