Websocket服务器:web套接字上的onopen函数永远不会被调用
我试图实现一个C#web套接字服务器,但它给了我一些麻烦。 我正在运行一个networking服务器(ASP.NET)来托pipe页面的JavaScript和Web套接字服务器被实现为一个C#控制台应用程序。
我能够检测到来自客户端的连接尝试(运行javascript的chrome),也能够从客户端检索握手。 但客户端似乎不接受我发回的握手(Web套接字上的onopen
函数从来没有被调用过)。
我一直在阅读Web Socket协议 ,我不明白我做错了什么。 下面是一些服务器代码:
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8181); listener.Bind(ep); listener.Listen(100); Console.WriteLine("Wainting for connection..."); Socket socketForClient = listener.Accept(); if (socketForClient.Connected) { Console.WriteLine("Client connected"); NetworkStream networkStream = new NetworkStream(socketForClient); System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(networkStream); System.IO.StreamReader streamReader = new System.IO.StreamReader(networkStream); //read handshake from client: Console.WriteLine("HANDSHAKING..."); char[] shake = new char[255]; streamReader.Read(shake, 0, 255); string handshake = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" + "Upgrade: WebSocket\r\n" + "Connection: Upgrade\r\n" + "WebSocket-Origin: http://localhost:8080\r\n" + "WebSocket-Location: ws://localhost:8181\r\n" + "\r\n"; streamWriter.Write(handshake); streamWriter.Flush();
我在本地主机上运行到端口8080上的Web服务器和端口8181上的Web套接字服务器。
我试过用不同的编码(ASCII,字节和hex)发送握手,但这似乎没有什么差别。 连接从未完全build立。 JavaScript看起来像这样:
var ws; var host = 'ws://localhost:8181'; debug("Connecting to " + host + " ..."); try { ws = new WebSocket(host); } catch (err) { debug(err, 'error'); } ws.onopen = function () { debug("connected...", 'success'); }; ws.onclose = function () { debug("Socket closed!", 'error'); }; ws.onmessage = function (evt) { debug('response: ' + evt, 'response'); };
我猜测错误在于C#服务器,因为chrome正在发送信息,但是作为一个说法, onopen
函数从来没有被调用过。
所以我的问题就是:你们有没有做到这一点 – 如果是的话,你们是怎么做到的? 原因:你看到代码中的任何明显的错误(希望不要多问)
可能是一个编码问题。 这是我写的一个可用的C#服务器:
class Program { static void Main(string[] args) { var listener = new TcpListener(IPAddress.Loopback, 8181); listener.Start(); using (var client = listener.AcceptTcpClient()) using (var stream = client.GetStream()) using (var reader = new StreamReader(stream)) using (var writer = new StreamWriter(stream)) { writer.WriteLine("HTTP/1.1 101 Web Socket Protocol Handshake"); writer.WriteLine("Upgrade: WebSocket"); writer.WriteLine("Connection: Upgrade"); writer.WriteLine("WebSocket-Origin: http://localhost:8080"); writer.WriteLine("WebSocket-Location: ws://localhost:8181/websession"); writer.WriteLine(""); } listener.Stop(); } }
并且在localhost:8080
上托pipe相应的客户端:
<!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"> var socket = new WebSocket('ws://localhost:8181/websession'); socket.onopen = function() { alert('handshake successfully established. May send data now...'); }; socket.onclose = function() { alert('connection closed'); }; </script> </head> <body> </body> </html>
这个例子只build立了握手。 您将需要调整服务器以便在握手build立后继续接受数据。
.NET Framework 4.5在Windows Communication Foundation中引入了对WebSockets的支持。 WebSockets是一种高效的基于标准的技术,可以通过标准的HTTP端口80和443进行双向通信。标准HTTP端口的使用允许WebSockets通过中介通过Web进行通信。 已经添加了两个新的标准绑定来支持通过WebSocket传输的通信。 NetHttpBinding和NetHttpsBinding。 可以通过访问WebSocketSettings属性在HttpTransportBinding元素上configuration特定于WebSockets的设置。
我认为它仍然使用SOAP
http://msdn.microsoft.com/en-us/library/hh674271(v=vs.110).aspx