WCF Websocket服务“找不到与架构http匹配的基址”错误

时间:2015-01-31 14:28:00

标签: wcf websocket web-config basic-authentication

我的问题是让我的WCF websocket服务正常运行。到现在为止,我找不到如何建立连接。客户端和服务器端都非常简单。所以我觉得我错过了一些明显的东西。

我目前在我的解决方案中有一个正常运行的WCF服务。 Web服务托管在IIS下,使用https和使用基本身份验证正确处理连接。

这是我的web.config文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <authentication mode="Forms" />
  </system.web>
  <system.serviceModel>
    <!--webHttpBinding allows exposing service methods in a RESTful manner-->
    <services>
      <service behaviorConfiguration="secureRESTBehavior" name="MyApp.Services.MyService">
        <endpoint address="" behaviorConfiguration="RESTfulBehavior" binding="webHttpBinding" bindingConfiguration="webHttpTransportSecurity" contract="MyApp.Services.IMyService" />
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <!--WCF Service Behavior Configurations-->
    <behaviors>
      <endpointBehaviors>
        <behavior name="RESTfulBehavior">
          <webHttp defaultBodyStyle="WrappedRequest" defaultOutgoingResponseFormat="Json" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="secureRESTBehavior">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceAuthorization principalPermissionMode="Custom" serviceAuthorizationManagerType="MyApp.Security.CustomAuthorizationManager, MyApp">
            <authorizationPolicies>
              <add policyType=" MyApp.Security.AuthorizationPolicy, MyApp" />
            </authorizationPolicies>
          </serviceAuthorization>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <!--WCF Service Binding Configurations-->
    <bindings>
      <webHttpBinding>
        <binding name="webHttpTransportSecurity" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" transferMode="Streamed" sendTimeout="00:05:00">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="Transport" />
        </binding>
      </webHttpBinding>
    </bindings>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="CORSModule" type="Security.CORSModule" />
    </modules>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true" />
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="http://myapp.com" />
        <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
        <add name="Access-Control-Allow-Methods" value="GET, DELETE, POST, PUT, OPTIONS" />
        <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>

现在我正在尝试使用WebSocketHost将WebSocket服务器托管为WCF服务。

这是我的工厂:

public class TRWebSocketServiceFactory: ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            try
            {
                WebSocketHost host = new WebSocketHost(serviceType, baseAddresses);

                host.AddWebSocketEndpoint();
                return host;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw ex;
            }
        }
    }

这是服务:

public class EchoWSService : WebSocketService
    {
        public override void OnOpen()
        {
            this.Send("Welcome!");
        }

        public override void OnMessage(string message)
        {
            string msgBack = string.Format(
                "You have sent {0} at {1}", message, DateTime.Now.ToLongTimeString());
            this.Send(msgBack);
        }

        protected override void OnClose()
        {
            base.OnClose();
        }

        protected override void OnError()
        {
            base.OnError();
        }
    }

这是我的Global.asax文件:

public class Global : System.Web.HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
            RouteTable.Routes.Add(new ServiceRoute(
                "Echo", new TRWebSocketServiceFactory(), typeof(EchoWSService)));
        }
    }

以下是尝试建立连接的客户端:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>WebSocket Chat</title>
    <script type="text/javascript" src="Scripts/jquery-2.0.2.js"></script>
    <script type="text/javascript">
        var ws;
        $().ready(function () {
            $("#btnConnect").click(function () {
                $("#spanStatus").text("connecting");
                ws = new WebSocket("wss://MyServer/Echo");
                ws.onopen = function () {
                    $("#spanStatus").text("connected");
                };
                ws.onmessage = function (evt) {
                    $("#spanStatus").text(evt.data);
                };
                ws.onerror = function (evt) {
                    $("#spanStatus").text(evt.message);
                };
                ws.onclose = function () {
                    $("#spanStatus").text("disconnected");
                };
            });
            $("#btnSend").click(function () {
                if (ws.readyState == WebSocket.OPEN) {
                    ws.send($("#textInput").val());
                }
                else {
                    $("#spanStatus").text("Connection is closed");
                }
            });
            $("#btnDisconnect").click(function () {
                ws.close();
            });
        });
    </script>
</head>
<body>
    <input type="button" value="Connect" id="btnConnect" /><input type="button" value="Disconnect" id="btnDisconnect" /><br />
    <input type="text" id="textInput" />
    <input type="button" value="Send" id="btnSend" /><br />
    <span id="spanStatus">(display)</span>
</body>
</html>

在线:

host.AddWebSocketEndpoint();

我总是得到错误:

找不到与绑定CustomBinding的端点的scheme http匹配的基址。注册的基地址方案是[https]。

我对以下几点感到困惑:

  • 如何解决此错误?
  • 我应该将web.config文件中的EchoWSService作为其他服务吗?
  • 如何使用网络套接字管理基本身份验证?

谢谢!

1 个答案:

答案 0 :(得分:1)

我失踪了:

Binding binding = WebSocketHost.CreateWebSocketBinding(true);

之前:

host.AddWebSocketEndpoint();

现在端点是正确的。