WCF Websocket,无法从浏览器连接

时间:2014-03-19 21:07:49

标签: .net wcf websocket

由于某种原因,我无法从我的javascript客户端连接到我的WebSocket服务器。

我的服务器:

[ServiceContract(CallbackContract = typeof(IHelloCallback))]
public interface IHelloService
{
    [OperationContract(IsOneWay = true)]
    Task Hello(string msg);
}

[ServiceContract]
public interface IHelloCallback
{
    [OperationContract(IsOneWay = true)]
    Task OnHello(string msg);
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class HelloService : IHelloService
{
    public async Task Hello(string msg)
    {
        var callback = OperationContext.Current.GetCallbackChannel<IHelloCallback>();
        await callback.OnHello(msg);
    }
}

class Program
{
    static void Main(string[] args)
    {
              ConfigurationManager.AppSettings
    ["aspnet:UseTaskFriendlySynchronizationContext"] = "true";

  var mapping = new System.ServiceModel.Configuration.ProtocolMappingElementCollection();
  mapping.Add(
    element: new ProtocolMappingElement(
      schemeType: "http",
      binding: "netHttpBinding",
      bindingConfiguration: "default"));
  mapping.Add(
    element: new ProtocolMappingElement(
      schemeType: "https",
      binding: "netHttpsBinding",
      bindingConfiguration: "default"));

  ServiceHost serviceHost = null;

  try {
    string addressStr = "http://localhost:27272/HelloService";

    var binding = new NetHttpBinding(
      securityMode: BasicHttpSecurityMode.None,
      reliableSessionEnabled: true);

    var addressUri = new Uri(uriString: addressStr);

    serviceHost = new ServiceHost(
      serviceType: typeof(HelloService),
      baseAddresses: addressUri);

    var endpoint = serviceHost.AddServiceEndpoint(
      implementedContract: typeof(IHelloService),
      binding: binding,
      address: addressUri);

    serviceHost.Open();

    Console.WriteLine(
      "WebSocketsServiceValues service is running, press any key to close...");
    Console.ReadKey();

  }
  catch (Exception ex) {
    Console.WriteLine(ex.ToString());
  }
  finally {
    serviceHost.Close();
  }
}
}

我的客户:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>WebSocket Chat</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-2.0.2.js"></script>
    <script type="text/javascript">
        var ws;
        $().ready(function () {
            $("#btnConnect").click(function () {
                $("#spanStatus").text("connecting");
                ws = new WebSocket("ws://localhost:27272/HelloService");
                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>

4 个答案:

答案 0 :(得分:1)

我注意到了一些有趣的事情。可能会帮助你: 客户端发送服务器的消息如下所示:

Upgrade: websocket
Connection: upgrade
Host: localhost:27272
Origin: null
Pragma: no-cache
Sec-WebSocket-Key: 6hblahblahblah
Sec-WebSocket-Version: 13 --- THIS IS INTERESTING
etc...

如果您使用Fiddler并将其切换为

Sec-WebSocket-Version: 13, 7

或几乎任何13以外的数字,

Sec-WebSocket-Version: 12
Sec-WebSocket-Version: 14

你将从服务器得到426响应,我认为这是谈判的下一步。我对此做了一些研究,你使用的msdn api实际上是非文档的,而且JavaScript api很蹩脚(你似乎无法在那里配置头文件)。

答案 1 :(得分:0)

尝试关闭可靠的会话:

var binding = new NetHttpBinding(
  securityMode: BasicHttpSecurityMode.None,
  reliableSessionEnabled: false);

答案 2 :(得分:0)

检查一下。可能有所帮助:MSDN Using the NetHttpBinding

我猜你的配置中缺少这个:

<bindings>
  <netHttpBinding>
    <binding name="My_NetHttpBindingConfig">
      <webSocketSettings transportUsage="WhenDuplex"/>
    </binding>
  </netHttpBinding>
</bindings>

答案 3 :(得分:0)

您可能希望在服务器上启用WCF跟踪,以便您更好地了解客户端进行调用时WCF服务侦听器正在执行的操作(例如,服务是否“看到”请求?有什么例外情况?服务抛出(记录在跟踪日志中)?

供参考: WCF跟踪为故障监视和分析提供诊断数据。您可以使用跟踪而不是调试器来了解应用程序的行为方式或故障原因。 http://msdn.microsoft.com/en-us/library/ms733025(v=vs.110).aspx

如果没有其他诊断信息,我建议您查看服务器绑定。特别是netHttp(s)Binding中的messageEncoding设置。默认情况下,netHttpBindingnetHttpsBinding绑定会以Binary格式传输数据,但根据您的客户端代码,您可能希望将messageEncoding切换为Text

祝你好运