无法使用Microsoft Owiin selfhost获取WebSocket请求

时间:2016-02-02 09:28:09

标签: c# websocket owin

我在互联网上找到了这个例子。不知何故,我无法让它正常运行。 我做了很多搜索,但仍然无法找出错误是什么?! 希望,有人可以帮助解决这个问题。

服务器代码:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Tracing;
using HTek.Core.MEF;
using HTek.Core.Server.Web.MEF;
using HTek.Core.Server.Web.Tracing;
using Microsoft.Owin;
using Owin;

// http://owin.org/extensions/owin-WebSocket-Extension-v0.4.0.htm
using WebSocketAccept = System.Action<System.Collections.Generic.IDictionary<string, object>, // options
    System.Func<System.Collections.Generic.IDictionary<string, object>, System.Threading.Tasks.Task>>; // callback
using WebSocketCloseAsync = System.Func<int /* closeStatus */,
        string /* closeDescription */,
        System.Threading.CancellationToken /* cancel */,
        System.Threading.Tasks.Task>;
using WebSocketReceiveAsync = System.Func<System.ArraySegment<byte> /* data */,
        System.Threading.CancellationToken /* cancel */, System.Threading.Tasks.Task<System.Tuple<int /* messageType */,
            bool /* endOfMessage */,
            int /* count */>>>;
using WebSocketSendAsync = System.Func<System.ArraySegment<byte> /* data */,
        int /* messageType */,
        bool /* endOfMessage */,
        System.Threading.CancellationToken /* cancel */,
        System.Threading.Tasks.Task>;
using WebSocketReceiveResult = System.Tuple<int, // type
    bool, // end of message?
    int>; // count

namespace Server.WebApi
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
             var webApiConfiguration = ConfigureWebApi();

            // Use the extension method provided by the WebApi.Owin library:
            app.UseWebApi((HttpConfiguration)webApiConfiguration);
            app.Use(UpgradeToWebSockets);
        }

        private HttpConfiguration ConfigureWebApi()
        {
            WebComposition provider = new WebComposition();
            Composition.SetCurrentProvider(provider);
            Composition.Start();

            var config = new HttpConfiguration();
            config.Routes.MapHttpRoute("DefaultApi",
                                       "api/{controller}/{id}",
                                       new
                                       {
                                           id = RouteParameter.Optional
                                       });
            provider.ConfigureWebApi(config);

            //// tracing config
            config.Services.Replace(typeof(ITraceWriter), new Tracer());

            return config;
        }

        private static Task UpgradeToWebSockets(IOwinContext context, Func<Task> next)
        {
            WebSocketAccept accept = context.Get<WebSocketAccept>("websocket.Accept");
            if (accept == null)
            {
                // Not a websocket request
                return next();
            }

            accept(null, WebSocketEcho);

            return Task.FromResult<object>(null);
        }

        private static async Task WebSocketEcho(IDictionary<string, object> websocketContext)
        {
            var sendAsync = (WebSocketSendAsync)websocketContext["websocket.SendAsync"];
            var receiveAsync = (WebSocketReceiveAsync)websocketContext["websocket.ReceiveAsync"];
            var closeAsync = (WebSocketCloseAsync)websocketContext["websocket.CloseAsync"];
            var callCancelled = (CancellationToken)websocketContext["websocket.CallCancelled"];

            byte[] buffer = new byte[1024];
            WebSocketReceiveResult received = await receiveAsync(new ArraySegment<byte>(buffer), callCancelled);

            object status;
            while (!websocketContext.TryGetValue("websocket.ClientCloseStatus", out status)
                   || (int)status == 0)
            {
                // Echo anything we receive
                await
                    sendAsync(new ArraySegment<byte>(buffer, 0, received.Item3),
                              received.Item1,
                              received.Item2,
                              callCancelled);

                received = await receiveAsync(new ArraySegment<byte>(buffer), callCancelled);
            }

            await
                closeAsync((int)websocketContext["websocket.ClientCloseStatus"],
                           (string)websocketContext["websocket.ClientCloseDescription"],
                           callCancelled);
        }
    }
}

private static void Main(string[] args)
{
    string baseAddress = "http://localhost:9000/";
    // Start OWIN host 
    using (WebApp.Start<Startup>(url: baseAddress))
    {
          Logger<Program>.InfoFormat("Server running on {0}", baseAddress);
          Console.ReadLine();
    }
 }

和HTML客户端:

var wsUri = "ws://localhost:9000";
var output;

function init()
{
    output = document.getElementById("output");
    testWebSocket();
}

function testWebSocket() {
    websocket = new WebSocket(wsUri);
    websocket.onopen = function(evt) { onOpen(evt) };
    websocket.onclose = function(evt) { onClose(evt) };
    websocket.onmessage = function(evt) { onMessage(evt) };
    websocket.onerror = function(evt) { onError(evt) };
}

function onOpen(evt)
{
    writeToScreen("CONNECTED");
    doSend("WebSocket rocks");
}

function onClose(evt)
{
    writeToScreen("DISCONNECTED");
}

function onMessage(evt)
{
    writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
    websocket.close();
}

function onError(evt)
{
    writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}

function doSend(message)
{
    writeToScreen("SENT: " + message);
    websocket.send(message);
}

function writeToScreen(message)
{
    var pre = document.createElement("p");
    pre.style.wordWrap = "break-word";
    pre.innerHTML = message;
    output.appendChild(pre);
}

window.addEventListener("load", init, false);

一切看起来都不错。例外,'accept'(在'UpgradeToWebSockets'中)总是 NULL

1 个答案:

答案 0 :(得分:2)

WebSocket不支持Windows 7等旧版Windows。

您可以升级到较新的版本,例如Windows 10。