在 <url> 没有侦听端点可以接受消息

There was no endpoint listening at <url> that could accept the message

我正在尝试创建一个 self-hosted WCF 服务来促进同一台机器上两个 MS-Office 插件之间的通信。这个想法是他们将在他们之间传递文档 meta-data。

我把运行改成了标题中的错误。

合同/执行:

namespace test.intermediaryservicehost
{
    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IIntermediaryObject
    {
        [OperationContract]
        bool GetIsWorking();
        [OperationContract]
        void SetIsWorking(bool working);


        [OperationContract]
        Dictionary<string, string> GetDocInfo();
        [OperationContract]
        void SetDocInfo(Dictionary<string, string> doc_info);

        [OperationContract]
        Dictionary<string, string> GetIndices();
        [OperationContract]
        void SetIndices(Dictionary<string, string> index_dict);

    }
}

namespace test.intermediaryservicehost
{

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class IntermediaryObject : IIntermediaryObject
    {
        private bool isWorking;

        private string Doc_Location;
        private string Doc_Name;

        private string Template_CorrespondenceType;
        private string Template_Reference;
        private string Template_Type; // "I" == Inbound, "O" == Outbound
        private string Template_Name;


        public bool GetIsWorking()
        {
            return this.isWorking;
        }
        public void SetIsWorking(bool working)
        {
            this.isWorking = working;
        }

        public Dictionary<string, string> GetDocInfo()
        {            
            Dictionary<string, string> doc_info = new Dictionary<string, string>();
            doc_info.Add("Doc_Location", this.Doc_Location);
            doc_info.Add("Doc_Name", this.Doc_Name);
            return doc_info;
        }
        public void SetDocInfo(Dictionary<string, string> doc_info)
        {
            this.Doc_Location = doc_info["Doc_Location"];
            this.Doc_Name = doc_info["Doc_Name"];         
        }

        public Dictionary<string, string> GetIndices()
        {
            Dictionary<string, string> indices = new Dictionary<string, string>();
            indices.Add("Template_CorrespondenceType", this.Template_CorrespondenceType);
            indices.Add("Template_Reference", this.Template_Reference);
            indices.Add("Template_Type", this.Template_Type);
            indices.Add("Template_Name", this.Template_Name);
            return indices;            
        }

        public void SetIndices(Dictionary<string, string> indices)
        {
            this.Template_CorrespondenceType = indices["Template_CorrespondenceType"];
            this.Template_Reference = indices["Template_Reference"];
            this.Template_Type = indices["Template_Type"];
            this.Template_Name = indices["Template_Name"];            
        }
    }
} 

这里是服务主机的代码(project/namespace 中的 windows 形式):

    private void Form1_Load(object sender, EventArgs e)
    {
        this.Visible = false;
        string svcLocation = "";
        try
        {
            svcLocation = ConfigurationManager.AppSettings["serviceUrl"] == null ? "http://localhost:1112/IntermediaryObject" : ConfigurationManager.AppSettings["serviceUrl"].ToString();
            SvcHost = new ServiceHost(typeof(test.intermediaryservicehost.IntermediaryObject), new Uri(svcLocation));
            SvcHost.Open();
        }
        catch (Exception ex)
        {
        }
    }

我在主机的 app.config 中使用以下配置:

  <appSettings>
    <add key="serviceUrl" value="http://localhost:1112/IntermediaryObject"/>
  </appSettings>  

<bindings>
  <wsDualHttpBinding>
    <binding name="WsHttpBinding_IIntermediaryObject" closeTimeout="00:01:00"/>
  </wsDualHttpBinding>
</bindings>

<services>
  <service name="test.intermediaryservicehost.IntermediaryObject" behaviorConfiguration="metaDataBehavior">
    <endpoint address="http://localhost:1112/IntermediaryObject"
              binding="wsDualHttpBinding"
              bindingConfiguration="WsHttpBinding_IIntermediaryObject"
              contract="test.intermediaryservicehost.IIntermediaryObject"/>
  </service>
</services>

<behaviors>
  <serviceBehaviors>
    <behavior name="metaDataBehavior">
      <serviceMetadata httpGetEnabled="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

客户端配置如下:

  <system.serviceModel>
<bindings>
  <wsDualHttpBinding>
    <binding name="WSDualHttpBinding_IIntermediaryObject" />
  </wsDualHttpBinding>
</bindings>

<client>
  <endpoint     address="http://localhost:1112/IntermediaryObject"
                binding="wsDualHttpBinding" 
                bindingConfiguration="WSDualHttpBinding_IIntermediaryObject"
                contract="IIntermediaryObject" 
                name="WSDualHttpBinding_IIntermediaryObject">        
  </endpoint>
</client>

<diagnostics>
  <messageLogging   logMessagesAtTransportLevel="true"
                    logMessagesAtServiceLevel="false"
                    logMalformedMessages="true"
                    logEntireMessage="true"
                    maxSizeOfMessageToLog="65535000"
                    maxMessagesToLog="1000"/>
</diagnostics>

关于该服务的其他一些事实: 它在 ServiceContract 上使用 SessionMode.Required,因此状态将被存储。 ServiceBehavior 属性

中的实现InstanceContextMode.Single

跟踪信息:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
    <EventID>131075</EventID>
    <Type>3</Type>
    <SubType Name="Error">0</SubType>
    <Level>2</Level>
    <TimeCreated SystemTime="2018-06-18T11:01:42.4511686Z" />
    <Source Name="System.ServiceModel" />
    <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
    <Execution ProcessName="OUTLOOK" ProcessID="1724" ThreadID="1" />
    <Channel />
    <Computer>[<COMP-NAME></Computer>
</System>
<ApplicationData>
    <TraceData>
        <DataItem>
            <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
                <TraceIdentifier>http://msdn.microsoft.com/en-IE/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
                <Description>Throwing an exception.</Description>
                <AppDomain>test.outlookaddin.vsto|vstolocal</AppDomain>
                <Exception>
                    <ExceptionType>System.ServiceModel.EndpointNotFoundException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
                    <Message>There was no endpoint listening at http://localhost:1112/IntermediaryObject that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.</Message>
                    <StackTrace>   at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStream()
                                   at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
                                   at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout)
                                   at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
                                   at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
                                   at System.ServiceModel.Security.SspiNegotiationTokenProvider.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Security.CommunicationObjectSecurityTokenProvider.Open(TimeSpan timeout)
                                   at System.ServiceModel.Security.SymmetricSecurityProtocol.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
                                   at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
                                   at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
                                   at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.SyncWaiter.TryGetChannel()
                                   at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.SyncWaiter.TryWait(TChannel&amp;amp; channel)
                                   at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.TryGetChannel(Boolean canGetChannel, Boolean canCauseFault, TimeSpan timeout, MaskingMode maskingMode, TChannel&amp;amp; channel)
                                   at System.ServiceModel.Channels.ReliableChannelBinder`1.Send(Message message, TimeSpan timeout, MaskingMode maskingMode)
                                   at System.ServiceModel.Channels.SendReceiveReliableRequestor.OnRequest(Message request, TimeSpan timeout, Boolean last)
                                   at System.ServiceModel.Channels.ReliableRequestor.Request(TimeSpan timeout)
                                   at System.ServiceModel.Channels.ClientReliableSession.Open(TimeSpan timeout)
                                   at System.ServiceModel.Channels.ClientReliableDuplexSessionChannel.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
                                   at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
                                   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
                                   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
                                   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
                                   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp;amp; msgData, Int32 type)
                                   at IIntermediaryObject.SetIndices(Dictionary`2 index_dict)
                                   at IntermediaryObjectClient.SetIndices(Dictionary`2 index_dict)
                                   at test.pluginforms.frmTemplateData.CallWord()
                                   at test.pluginforms.frmTemplateData.btnGenerate_Click(Object sender, EventArgs e)
                                   at System.Windows.Forms.Control.OnClick(EventArgs e)
                                   at System.Windows.Forms.Button.OnClick(EventArgs e)
                                   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
                                   at System.Windows.Forms.Control.WmMouseUp(Message&amp;amp; m, MouseButtons button, Int32 clicks)
                                   at System.Windows.Forms.Control.WndProc(Message&amp;amp; m)
                                   at System.Windows.Forms.ButtonBase.WndProc(Message&amp;amp; m)
                                   at System.Windows.Forms.Button.WndProc(Message&amp;amp; m)
                                   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp;amp; m)
                                   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp;amp; m)
                                   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
                    </StackTrace>
                    <ExceptionString>
                                    System.ServiceModel.EndpointNotFoundException: There was no endpoint listening at http://localhost:1112/IntermediaryObject that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details. ---&amp;gt; System.Net.WebException: Unable to connect to the remote server ---&amp;gt; System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:1112
                                        at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
                                        at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket&amp;amp; socket, IPAddress&amp;amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&amp;amp; exception)
                                    --- End of inner exception stack trace ---
                                    at System.Net.HttpWebRequest.GetRequestStream(TransportContext&amp;amp; context)
                                    at System.Net.HttpWebRequest.GetRequestStream()
                                    at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStream()
                                    --- End of inner exception stack trace ---
                    </ExceptionString>
                    <InnerException>
                        <ExceptionType>System.Net.WebException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
                        <Message>Unable to connect to the remote server</Message>
                        <StackTrace>    at System.Net.HttpWebRequest.GetRequestStream(TransportContext&amp;amp; context)
                                        at System.Net.HttpWebRequest.GetRequestStream()
                                        at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStream()
                        </StackTrace>
                        <ExceptionString>
                                        System.Net.WebException: Unable to connect to the remote server ---&amp;gt; System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:1112
                                       at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
                                       at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket&amp;amp; socket, IPAddress&amp;amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&amp;amp; exception)
                                       --- End of inner exception stack trace ---
                                       at System.Net.HttpWebRequest.GetRequestStream(TransportContext&amp;amp; context)
                                       at System.Net.HttpWebRequest.GetRequestStream()
                                       at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStream()
                        </ExceptionString>
                        <InnerException>
                            <ExceptionType>System.Net.Sockets.SocketException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
                            <Message>No connection could be made because the target machine actively refused it 127.0.0.1:1112</Message>
                            <StackTrace>   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
                                            at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket&amp;amp; socket, IPAddress&amp;amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&amp;amp; exception)</StackTrace>
                            <ExceptionString>System.Net.Sockets.SocketException (0x80004005): No connection could be made because the target machine actively refused it 127.0.0.1:1112
                                               at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
                                               at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket&amp;amp; socket, IPAddress&amp;amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&amp;amp; exception)
                            </ExceptionString>
                            <NativeErrorCode>274D</NativeErrorCode>
                        </InnerException>
                    </InnerException>
                </Exception>
            </TraceRecord>
        </DataItem>
    </TraceData>
</ApplicationData>

问题最终是绑定。 wsDualHttpBinding 要求端点在请求和响应结束时进行监听。我的客户端应用程序(两个办公室插件)都没有在任何 url 监听,因此我的错误。怀疑这是CodeCaster想拖着我,又踢又叫的结论!

我切换到更适合我的应用程序的绑定; netNamedPipeBinding.

我的新主机配置:

  <system.serviceModel>    
    <bindings>
      <netNamedPipeBinding>
        <binding name="NetNamedPipeBinding_IIntermediaryObject" closeTimeout="00:01:00"/>
      </netNamedPipeBinding>
    </bindings>    
    <services>
      <service name="test.intermediaryservicehost.IntermediaryObject" >
        <endpoint address="net.pipe://localhost/IntermediaryObject"
              binding="netNamedPipeBinding"
              bindingConfiguration="NetNamedPipeBinding_IIntermediaryObject"
              contract="test.intermediaryservicehost.IIntermediaryObject"/>
        <endpoint binding="mexNamedPipeBinding" name="mex" address="mex" contract="IMetadataExchange"/>
        </service>
   </services>    
   <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata />
        </behavior>
      </serviceBehaviors>
   </behaviors>   

和客户端配置示例:

<system.serviceModel>
    <bindings>
      <netNamedPipeBinding>
        <binding name="NetNamedPipeBinding_IIntermediaryObject" />
      </netNamedPipeBinding>
    </bindings>
    <client>
      <endpoint address="net.pipe://localhost/IntermediaryObject" binding="netNamedPipeBinding"
      bindingConfiguration="NetNamedPipeBinding_IIntermediaryObject"
      contract="IIntermediaryObject" name="NetNamedPipeBinding_IIntermediaryObject">       
      </endpoint>
    </client>    
    <diagnostics>
        <!-- Unrelated tracing info, removed for brevity -->
    </diagnostics>
</system.serviceModel>

This answer 帮助我为 netNamedPipeBinding

生成了所需的客户端 configuration/proxy class