2017-06-13 224 views
2

我正在嘗試爲瀏覽器輸入交互的應用程序編寫C#WebSocket服務器。C#WebSocket - 在握手過程中客戶端沒有響應

這是代碼:

class Program { 
static void Main(string[] args) { 
    var listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 42001); 
    listener.Start(); 
    using(var client = listener.AcceptTcpClient()) 
    using(var stream = client.GetStream()) 
    using(var reader = new StreamReader(stream)) 
    using(var writer = new StreamWriter(stream)) { 
    while (!reader.EndOfStream) { 
    String line = reader.ReadLine(); 

    if (new Regex("^GET").IsMatch(line)) { 
    line = reader.ReadLine(); 
    if (new Regex("^Sec-WebSocket-Key: ").IsMatch(line)) { 
     String key = new Regex("(^Sec-WebSocket-Key\\: |\\r\\n)").Replace(line, ""); 

     key = Convert.ToBase64String(SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))); 

     writer.WriteLine("HTTP/1.1 101 Switching Protocols"); 
     writer.WriteLine("Upgrade: websocket"); 
     writer.WriteLine("Connection: Upgrade"); 
     writer.WriteLine("Sec-WebSocket-Accept: " + key); 
     writer.WriteLine("Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits"); 
     writer.WriteLine("WebSocket-Origin: http://127.0.0.1"); 
     writer.WriteLine("WebSocket-Location: ws://localhost:42001/websocket"); 
     writer.WriteLine(""); 
    } 
    } 
    } 
    } 
    listener.Stop(); 
} 
} 

...和:

 var ws = new WebSocket('ws://localhost:42001/websocket'); 

     ws.onopen = function() { 
      console.log('connected'); 
     }; 

     ws.onmessage = function(e) { 
      console.log(e.data); 
     }; 

     ws.onerror = function(e) { 
      console.log(e); 
     }; 

     ws.onclose = function() { 
      console.log("closed"); 
     }; 

在執行時,所述成功TPCListener接受的TcpClient並讀取傳入的HTTP請求。它解析Key,生成正確的令牌Accept,但JS-window原生的WebSocket似乎已經變得瘋狂:它無論接收到什麼都不回答。 我期望它在發送HTTP/1.1 400 Bad Request時發生錯誤,但完全沒有任何事情發生。它只是靜音。 查看Chrome Dev Tools的Networking選項卡,我只看到websocket傳出GET請求,但沒有傳入數據包 - 是否應該發生? 如果我強制關閉應用程序,WebSocket會拋出以下異常:

WebSocket connection to 'ws://localhost:42001/websocket' failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET

我在這裏錯過了什麼?謝謝大家。

另外,我不使用Net.WebSockets,因爲它是自.NET 4.5可用,並從Windows 7到Windows 10的當前版本

回答

1

我的應用程序的目標系統以及...多遠做你的C#代碼得到?我的第一個賭注是緩衝 - 你不沖洗作家或流,所以我會期望他們堅持數據,而卡在while循環的頂部,但坦率地說,它不應該是一個while循環首先 - 你只能得到一次握手,而不是很多。您可以嘗試在空白行後面添加刷新,並且您應該確保Socket本身緩存禁用(NoDelay = true;) - 但是:從根本上說,這不是編寫Web套接字服務器的好方法。除了別的,數據將不再是文本如果握手成功,所以有一個TextReader是一件非常糟糕的事情。坦率地說,你應該在這裏處理原始Socket/byte[]數據,IMO(已經實施了這個東西幾次)。

+0

您的第一個賭注非常正確,謝謝。 我沒有沖洗作家和雙手相當成功地震動 - 我很抱歉。我欣賞提示! – anon123

+0

@Marc Gravell既然你已經實現了幾次WebSockets,你可以看看我的文章,並提供一個代碼示例?我的帖子https://stackoverflow.com/questions/47481999/c-sharp-websockets-on-windows-7-with-owin – Que