I am trying to use WebSockets on Windows 7. I trying to use System.Net.Sockets, I have tried following these examples, but each of them has one problem or another running on 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
I have looked into several 3rd party tools, but it looks like they are either no longer supported or in beta.
Here's the code I have so far:
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;
}
}
}
When the OnLoadData event fires it calls another class which simply has:
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();
I then get this error:
An established connection was aborted by the software in your host machine at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size) NativeErrorCode 10053 int SocketErrorCode ConnectionAborted System.Net.Sockets.SocketError
I am looking for a simple C# WebSockets implementation that works on Windows 7. I cannot use SignalR or ASP.NET because I am using OWIN to self-host Web API.
I took a look at this post, but I can't figure out how the OP made it work. Anyone know how to do this?