我正在尝试在Windows 7上使用WebSockets。我尝试使用System.Net.Sockets,我尝试过这些示例,但每个都有一个问题或另一个在Windows 7上运行:
WebSocket Server in C#,Writing a WebSocket server in C#, Creating a “Hello World” WebSocket example,How 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是如何运作的。 有谁知道怎么做?