C# Websocket 服务器:永远不会调用 Web 套接字上的 onopen 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2211898/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:28:40  来源:igfitidea点击:

Websocket server: onopen function on the web socket is never called

c#websocket

提问by Jon List

I'm trying to implement a C# web socket server, but its giving me a few troubles. I'm running a webserver(ASP.NET) to host the page with the javascript and the web socket server is implemented as a C# console application.

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

I'm able to detect the connection attempt from the client (chrome running the javascript) and also to retrieve the handshake from the client. But the client doesn't seem to accept the handshake I'm sending back (the onopenfunction on the web socket is never called).

我能够检测到来自客户端的连接尝试(运行 javascript 的 chrome),并且还可以从客户端检索握手。但是客户端似乎不接受我发回的握手(onopen网络套接字上的函数从未被调用)。

I've been reading the The Web Socket protocoland I can't see what I'm doing wrong. Heres a bit of the server code:

我一直在阅读The 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();

I'm running to web server on port 8080 and the web socket server on port 8181, both on my localhost.

我运行到端口 8080 上的 Web 服务器和端口 8181 上的 Web 套接字服务器,都在我的本地主机上。

I've tried sending the handshake in different encodings (ASCII, bytes and Hex) but this doesn't seem to make a difference. The connection is never fully established. The javascript looks like this:

我试过以不同的编码(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');
};

I'm guessing that the error lies in the C# server as chrome is sending the information as it should, but as a said the onopenfunction is never called.

我猜测错误在于 C# 服务器,因为 chrome 正在发送信息,但正如所说的那样,该onopen函数从未被调用。

So my question in short:Has any of you ever accomplished this - and if yes, how did you do it? And of cause: Do you see any apparent errors in the code (hope thats not to much to ask)

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

采纳答案by Darin Dimitrov

Probably it's an encoding issue. Here's a working C# server I wrote:

应该是编码问题。这是我写的一个工作的 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();
    }
}

And the corresponding client hosted on localhost:8080:

对应的客户端托管在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>

This example only establishes the handshake. You will need to tweak the server in order to continue accepting data once the handshake has been established.

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

回答by Kerry Jiang

Please use UTF8 encoding to send text message.

请使用UTF8编码发送短信。

There is an open source websocket server which is implemented by C#, you can use it directly.

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

http://superwebsocket.codeplex.com/

http://superwebsocket.codeplex.com/

It's my open source project!

这是我的开源项目!

回答by Dave Hillier

The .NET Framework 4.5 introduces support for WebSockets in Windows Communication Foundation. WebSockets is an efficient, standards-based technology that enables bidirectional communication over the standard HTTP ports 80 and 443. The use of the standard HTTP ports allow WebSockets to communicate across the web through intermediaries. Two new standard bindings have been added to support communication over a WebSocket transport. NetHttpBinding and NetHttpsBinding. WebSockets-specific settings can be configured on the HttpTransportBinding element by accessing the WebSocketSettings property.

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

I think it still uses SOAP though

我认为它仍然使用 SOAP

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

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