控制台应用程序调用websocket
控制台应用程序:
class Program { public static void Main() { string ip = "127.0.0.1"; int port = 8080; var server = new TcpListener(IPAddress.Parse(ip), port); server.Start(); Console.WriteLine("Server has started on {0}:{1}, Waiting for a connection...", ip, port); TcpClient client = server.AcceptTcpClient(); Console.WriteLine("A client connected."); NetworkStream stream = client.GetStream(); // enter to an infinite cycle to be able to handle every change in stream while (true) { while (!stream.DataAvailable) ; while (client.Available < 3) ; // match against "get" byte[] bytes = new byte[client.Available]; stream.Read(bytes, 0, client.Available); string s = Encoding.UTF8.GetString(bytes); if (Regex.IsMatch(s, "^GET", RegexOptions.IgnoreCase)) { Console.WriteLine("=====Handshaking from client=====\n{0}", s); // 1. Obtain the value of the "Sec-WebSocket-Key" request header without any leading or trailing whitespace // 2. Concatenate it with "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" (a special GUID specified by RFC 6455) // 3. Compute SHA-1 and Base64 hash of the new value // 4. Write the hash back as the value of "Sec-WebSocket-Accept" response header in an HTTP response string swk = Regex.Match(s, "Sec-WebSocket-Key: (.*)").Groups[1].Value.Trim(); string swka = swk + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; byte[] swkaSha1 = System.Security.Cryptography.SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(swka)); string swkaSha1Base64 = Convert.ToBase64String(swkaSha1); // HTTP/1.1 defines the sequence CR LF as the end-of-line marker byte[] response = Encoding.UTF8.GetBytes( "HTTP/1.1 101 Switching Protocols\r\n" + "Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Sec-WebSocket-Accept: " + swkaSha1Base64 + "\r\n\r\n"); stream.Write(response, 0, response.Length); } else { bool fin = (bytes[0] & 0b10000000) != 0, mask = (bytes[1] & 0b10000000) != 0; // must be true, "All messages from the client to the server have this bit set" int opcode = bytes[0] & 0b00001111, // expecting 1 - text message msglen = bytes[1] - 128, // & 0111 1111 offset = 2; if (msglen == 126) { // was ToUInt16(bytes, offset) but the result is incorrect msglen = BitConverter.ToUInt16(new byte[] { bytes[3], bytes[2] }, 0); offset = 4; } else if (msglen == 127) { Console.WriteLine("TODO: msglen == 127, needs qword to store msglen"); // i don't really know the byte order, please edit this // msglen = BitConverter.ToUInt64(new byte[] { bytes[5], bytes[4], bytes[3], bytes[2], bytes[9], bytes[8], bytes[7], bytes[6] }, 0); // offset = 10; } if (msglen == 0) Console.WriteLine("msglen == 0"); else if (mask) { byte[] decoded = new byte[msglen]; byte[] masks = new byte[4] { bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3] }; offset += 4; for (int i = 0; i < msglen; ++i) decoded[i] = (byte)(bytes[offset + i] ^ masks[i % 4]); string text = Encoding.UTF8.GetString(decoded); Console.WriteLine("Message received {0}", text); } else Console.WriteLine("mask bit not set"); Console.WriteLine(); } } } }
html:
<!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 text = document.getElementById("test1").value; var ws = new WebSocket("ws://localhost:8080/service"); ws.onopen = function () { alert("About to send data"); ws.send(text); // 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..."); }; }; </script> </head> <body style="font-size:xx-large" > <div> <a href="#" onclick="connect()">Click here to start</a></div> <input id="test1" > </body> </html>