Сервер веб-сокетов: функция onopen на веб-сокете никогда не вызывается - PullRequest
61 голосов
/ 06 февраля 2010

Я пытаюсь реализовать сервер веб-сокетов C #, но это доставляет мне некоторые проблемы. Я использую веб-сервер (ASP.NET) для размещения страницы с javascript, и сервер веб-сокетов реализован как консольное приложение C #.

Я могу обнаружить попытку подключения от клиента (Chrome работает с JavaScript), а также получить рукопожатие от клиента. Но клиент, похоже, не принимает рукопожатие, которое я отправляю обратно (функция onopen в веб-сокете никогда не вызывается).

Я читал протокол веб-сокета , и я не вижу, что я делаю неправильно. Вот немного кода сервера:

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 и на сервере веб-сокетов на порту 8181, оба на моем локальном хосте.

Я пытался отправить рукопожатие в разных кодировках (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 никогда не вызывается.

Итак, мой вопрос вкратце: Кто-нибудь из вас когда-либо достигал этого - и если да, то как вы это сделали? И причины: Вы видите какие-либо очевидные ошибки в коде (надеюсь, это не так много, чтобы спросить)

Ответы [ 3 ]

47 голосов
/ 06 февраля 2010

Возможно, это проблема с кодировкой. Вот рабочий сервер 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>

Этот пример только устанавливает рукопожатие. Вам нужно будет настроить сервер, чтобы продолжить прием данных после установления рукопожатия.

24 голосов
/ 08 декабря 2010

Пожалуйста, используйте кодировку UTF8 для отправки текстового сообщения.

Существует сервер websocket с открытым исходным кодом, который реализован на C #, вы можете использовать его напрямую.

http://superwebsocket.codeplex.com/

Это мой проект с открытым исходным кодом!

3 голосов
/ 24 мая 2012

.NET Framework 4.5 представляет поддержку WebSockets в Windows Фонд связи. WebSockets - это эффективный, основанный на стандартах технология, которая позволяет двунаправленную связь по стандарту HTTP-порты 80 и 443. Использование стандартных HTTP-портов позволяет WebSockets для общения через Интернет через посредников. Два новые стандартные привязки были добавлены для поддержки связи через WebSocket транспорт. NetHttpBinding и NetHttpsBinding. Специфичные для WebSockets параметры можно настроить на Элемент HttpTransportBinding путем доступа к WebSocketSettings свойство.

Я думаю, что он все еще использует SOAP, хотя

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...