2010-02-06 5 views
60

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

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

Я читал The Web Socket protocol, и я не вижу, что я делаю неправильно. Heres немного кода сервера:

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# сервер, как хром посылает информацию, как и должно быть, но, как сказал функция onopen никогда не вызывается.

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

+1

Вы можете захотеть использовать Fleck, доступный на NuGet: http://nuget.org/packages/Fleck/ –

ответ

47

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

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

+1

Спасибо! Оказалось, что это была проблема с сайтом WebSocket-Location в рукопожатии. По-видимому, это не может быть просто «ws: // localhost: 8181». После того, как вы изменили его на «ws: // localhost: 8181/something» и сменили хост в javascript на то же самое - он сработал. –

+0

Спасибо за сообщение. Я пытался это сделать с помощью Chrome + статического html-файла и должен был изменить начало координат, чтобы предотвратить немедленное отключение браузера: writer.WriteLine («WebSocket-Origin: file: //»); –

+0

@Darin Ваш код работает нормально. Это не сработало, когда я удалил это «использование» и объявил, что «писатель», как обычно. Дело в том, что писатель не писал клиенту. Вы можете это объяснить? – prabhakaran

24

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

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

http://superwebsocket.codeplex.com/

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

+2

Теперь SuperWebSocket также содержит реализацию клиента WebSocket! –

3

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^