带有OWIN的Windows 7上的C#WebSockets

时间:2017-11-25 02:02:35

标签: c# sockets websocket windows-7 tcpclient

我正在尝试在Windows 7上使用WebSockets。我尝试使用System.Net.Sockets,我尝试过这些示例,但每个都有一个问题或另一个在Windows 7上运行:

WebSocket Server in C#Writing a WebSocket server in C#Creating a “Hello World” WebSocket exampleHow to implement an asynchronous socket in C#MULTI-THREADED TCP SERVER IN C#Paul Batum

我已经研究了几个第三方工具,但看起来它们不再受支持或处于测试阶段。

这是我到目前为止的代码:

public class WebSocketService {
    private TcpListener _listener;
    private TcpClient _tcpClient;
    public event Action<NetworkStream> OnLoadData;

    public WebSocketService() {
       Listen();
    }

    public void Listen(int port) {
       _listener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
       _listener.Start();
       _listener.BeginAcceptTcpClient(HandleAsyncConnection, null);
    }

    private void HandleAsyncConnection(IAsyncResult result)
    {
        try
        {
            _tcpClient = _listener.EndAcceptTcpClient(result);
            _tcpClient.NoDelay = true;
            NetworkStream stream = _tcpClient.GetStream();

            // extract the connection details and use those details to build a connection
            ConnectionDetails connectionDetails = GetConnectionDetails(stream, _tcpClient);
            PerformHandshake(stream, connectionDetails.Header);

            if (connectionDetails.Path.Equals("/myApiPath"))
            {
                OnLoadData?.Invoke(stream);
            }

        }
        catch (Exception ex)
        {
            //write ex to log
            throw;
        }
    }

    private static ConnectionDetails GetConnectionDetails(NetworkStream stream, TcpClient tcpClient)
    {
        // read the header and check that it is a GET request
        string header = HttpHelper.ReadHttpHeader(stream);
        var getRegex = new Regex(@"^GET(.*)HTTP\/1\.1", RegexOptions.IgnoreCase);

        Match getRegexMatch = getRegex.Match(header);
        if (getRegexMatch.Success)
        {
            // extract the path attribute from the first line of the header
            string path = getRegexMatch.Groups[1].Value.Trim();

            // check if this is a web socket upgrade request
            var webSocketUpgradeRegex = new Regex("Upgrade: websocket", RegexOptions.IgnoreCase);
            Match webSocketUpgradeRegexMatch = webSocketUpgradeRegex.Match(header);

            if (webSocketUpgradeRegexMatch.Success)
            {
                return new ConnectionDetails(stream, tcpClient, path, ConnectionType.WebSocket, header);
            }

            return new ConnectionDetails(stream, tcpClient, path, ConnectionType.Http, header);
        }

        return new ConnectionDetails(stream, tcpClient, string.Empty, ConnectionType.Unknown, header);
    }

    private void PerformHandshake(Stream stream, string header)
    {
       try
        {
            Regex webSocketKeyRegex = new Regex("Sec-WebSocket-Key: (.*)");
            Regex webSocketVersionRegex = new Regex("Sec-WebSocket-Version: (.*)");

            // check the version. Support version 13 and above
            const int webSocketVersion = 13;
            int secWebSocketVersion = Convert.ToInt32(webSocketVersionRegex.Match(header).Groups[1].Value.Trim());
            if (secWebSocketVersion < webSocketVersion)
            {
                //throw some exception
            }

            string secWebSocketKey = webSocketKeyRegex.Match(header).Groups[1].Value.Trim();
            string setWebSocketAccept = ComputeSocketAcceptString(secWebSocketKey);
            var newLine = "\r\n";

            string response = ("HTTP/1.1 101 Switching Protocols" + newLine
                               + "Connection: Upgrade" + newLine
                               + "Upgrade: websocket" + newLine
                               + "Sec-WebSocket-Accept: " + setWebSocketAccept + newLine + newLine);

            WriteHttpHeader(response, stream);

        }
        catch (Exception ex)
        {
            // Write Log Entry(ex);
            WriteHttpHeader("HTTP/1.1 400 Bad Request", stream);
            throw;
        }
    }
}

当OnLoadData事件触发时,它会调用另一个只有:

的类
var jsonSerializerSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };

            var message = JsonConvert.SerializeObject(someData, jsonSerializerSettings);
            var messageData = Encoding.UTF8.GetBytes(message);


            _clientStream.Write(messageData, 0, messageData.Length);
            _clientStream.Flush();

然后我收到此错误:

  

已建立的连接已被主机中的软件中止   System.Net.Sockets.Socket.Send(Byte []缓冲区,Int32的机器   offset,Int32 size,SocketFlags socketFlags)at   System.Net.Sockets.NetworkStream.Write(Byte []缓冲区,Int32偏移量,   Int32尺寸)   NativeErrorCode 10053 int   SocketErrorCode ConnectionAborted System.Net.Sockets.SocketError

我正在寻找一个适用于Windows 7的简单C#WebSockets实现。我不能使用SignalR或ASP.NET,因为我使用OWIN来自托管Web API。

我看了一下post,但我无法弄清楚OP是如何运作的。 有谁知道怎么做?

0 个答案:

没有答案