62

我正在尝试实现一个 C# Web 套接字服务器,但它给我带来了一些麻烦。我正在运行一个 Web 服务器(ASP.NET)来使用 javascript 托管页面,并且 Web 套接字服务器被实现为 C# 控制台应用程序。

我能够检测到来自客户端的连接尝试(运行 javascript 的 chrome),还能够从客户端检索握手。但是客户端似乎不接受我发回的握手(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、字节和十六进制)发送握手,但这似乎没有什么区别。连接永远不会完全建立。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函数永远不会被调用。

简而言之,我的问题是: 你们中的任何人有没有做到这一点——如果有,你是怎么做到的?原因是:您是否在代码中看到任何明显的错误(希望不要问太多)

4

3 回答 3

49

可能是编码问题。这是我写的一个工作的 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

<!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>

此示例仅建立握手。一旦建立握手,您将需要调整服务器以便继续接受数据。

于 2010-02-06T10:07:41.677 回答
24

请使用 UTF8 编码发送短信。

有一个C#实现的开源websocket服务器,可以直接使用。

http://superwebsocket.codeplex.com/

这是我的开源项目!

于 2010-12-08T02:20:08.260 回答
3

.NET Framework 4.5 在 Windows Communication Foundation 中引入了对 WebSockets 的支持。WebSockets 是一种基于标准的高效技术,可通过标准 HTTP 端口 80 和 443 进行双向通信。标准 HTTP 端口的使用允许 WebSockets 通过中介在 Web 上进行通信。添加了两个新的标准绑定以支持通过 WebSocket 传输进行的通信。NetHttpBinding 和 NetHttpsBinding。通过访问 WebSocketSettings 属性,可以在 HttpTransportBinding 元素上配置特定于 WebSocket 的设置。

我认为它仍然使用 SOAP

http://msdn.microsoft.com/en-us/library/hh674271(v=vs.110).aspx

于 2012-05-24T14:51:09.593 回答