2013-03-26 84 views
0

也許我迫切需要一隻手了。C#的WebSocket服務器未燒製的onmessage事件在HTML5

我目前有關於使用C#和HTML5的WebSocket服務器有問題。它不是在html5中觸發我的onmessage()事件。它打開套接字連接並觸發onopen()事件。但是,一旦建立連接,它將繼續關閉連接。這裏是我的簡單的代碼:

服務器(C#):

using System; 
using System.Collections.Generic; 
using System.Net.Sockets; 
using System.Net; 
using System.IO; 
using System.Security.Cryptography; 
using System.Threading; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     public Socket ListenerSocker { get; private set; } 
     static IPEndPoint ipLocal; 
     static Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); 
     static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 

     static void Main(string[] args) 
     { 
      serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080)); 
      //serverSocket.Listen(128); 
      serverSocket.Listen(200); 
      serverSocket.BeginAccept(null, 0, OnAccept, null); 

      Console.Read(); 
     } 


     private static void OnClientConnect() 
     { 

      serverSocket.BeginAccept(null, 0, OnAccept, null); 
     } 







     private static void OnAccept(IAsyncResult result) 
     { 
      byte[] buffer = new byte[1024]; 

      Socket client = null; 
      string headerResponse = ""; 
      if (serverSocket != null && serverSocket.IsBound) 
      { 
       client = serverSocket.EndAccept(result); 
       var i = client.Receive(buffer); 
       headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0, i); 
       // write received data to the console 
       Console.WriteLine(headerResponse); 

      } 
      if (client != null) 
      { 
       /* Handshaking and managing ClientSocket */ 

       var key = headerResponse.Replace("ey:", "`") 
          .Split('`')[1]      // dGhlIHNhbXBsZSBub25jZQ== \r\n ....... 
          .Replace("\r", "").Split('\n')[0] // dGhlIHNhbXBsZSBub25jZQ== 
          .Trim(); 

       // key should now equal dGhlIHNhbXBsZSBub25jZQ== 
       var test1 = AcceptKey(ref key); 

       var newLine = "\r\n"; 

       var response = "HTTP/1.1 101 Switching Protocols" + newLine 
        + "Upgrade: websocket" + newLine 
        + "Connection: Upgrade" + newLine 
        + "Sec-WebSocket-Accept: " + test1 + newLine + newLine 
        + "Sec-WebSocket-Key: " + test1 + newLine + newLine 
        + "Sec-WebSocket-Key: " + test1 + newLine + newLine 
        //+ "Sec-WebSocket-Protocol: chat, superchat" + newLine 
        //+ "Sec-WebSocket-Version: 13" + newLine 
        ; 

       // which one should I use? none of them fires the onopen method 
       client.Send(System.Text.Encoding.UTF8.GetBytes(response)); 

       var i = client.Receive(buffer); // wait for client to send a message 

       // once the message is received decode it in different formats 
       Console.WriteLine(Convert.ToBase64String(buffer).Substring(0, i)); 
       /* 
       Console.WriteLine("\n\nPress enter to send data to client"); 
       Console.Read(); 
       */ 
       var subA = SubArray<byte>(buffer, 0, i); 
       Console.WriteLine("***SUBA****:"+subA); 
       Console.WriteLine("TEST"); 
       client.Send(subA); 

       // Thread.Sleep(10000);//wait for message to be send 

       // OnClientConnect(); 
      } 
     } 

     public static T[] SubArray<T>(T[] data, int index, int length) 
     { 
      T[] result = new T[length]; 
      Array.Copy(data, index, result, 0, length); 
      Console.WriteLine(result); 
      return result; 
     } 

     private static string AcceptKey(ref string key) 
     { 
      string longKey = key + guid; 
      byte[] hashBytes = ComputeHash(longKey); 
      return Convert.ToBase64String(hashBytes); 
     } 

     static SHA1 sha1 = SHA1CryptoServiceProvider.Create(); 
     private static byte[] ComputeHash(string str) 
     { 
      return sha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(str)); 
     } 
    } 
} 

客戶端(HTML5):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <script type="text/javascript"> 
     function connect() { 
      var ws = new WebSocket("ws://localhost:8080"); 
      console.log(ws); 
      ws.onopen = function() { 
       alert("About to send data"); 
       ws.send("test"); // I WANT TO SEND THIS MESSAGE TO THE SERVER!!!!!!!! 
       alert("Message sent!"); 
      }; 

      ws.onmessage = function (evt) { 
       alert("About to receive data"); 
       var received_msg = evt.data; 
       alert("Message received = "+received_msg); 
      }; 
      ws.onclose = function() { 
       // websocket is closed. 
       alert("Connection is closed..."); 
      }; 
     }; 

     function send(){ 
     } 


    </script> 
</head> 
<body style="font-size:xx-large" > 
    <div> 
    <a href="#" onclick="connect()">Click here to start</a></div> 

</body> 
</html> 

我能得到這個:

alert("About to send data"); 

這:

alert("Message sent!"); 

但之後,連接關閉。我也可以檢查服務器是否從客戶端接收數據。問題是,一旦我將數據從服務器發送到客戶端,爲了能夠返回客戶端給我的內容,連接突然關閉。可能是什麼問題?

回答

0

的WebSocket消息不是純文本;他們需要有一個簡單的幀協議施加

成幀規則客戶端 - >服務器和服務器 - >客戶端的消息略有不同。我想當客戶嘗試在不應用不同幀的情況下回應其消息時,客戶端正在關閉其連接。

參見RFC6455爲如何解碼/編碼消息data framing section。或者,如果您使用.NET4.5,則可以考慮使用System.Net.WebSockets而不是編寫自己的服務器。

+0

是啊,我相信我有數據成幀 – Charmie

+0

我不能看到它在你的示例代碼。每個傳入消息都需要一些前導字節,然後轉換剩餘的字節。每個傳出消息都需要添加一些前導字節。 – simonc

+0

你有沒有我可以參考的實際示例代碼?我很難理解這個數據框架 – Charmie

相關問題