Сервер Websocket: функция onopen в веб-сокете никогда не вызывается
Я пытаюсь внедрить сервер веб-сокетов С#, но это дает мне несколько проблем.
Я запускаю веб-сервер (ASP.NET) для размещения страницы с помощью javascript, а сервер веб-сокетов реализован как консольное приложение С#.
Я могу обнаружить попытку подключения с клиента (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');
};
Я предполагаю, что ошибка лежит на сервере С#, поскольку хром отправляет информацию так, как должен, но, как сказано, функция onopen
никогда не вызывается.
Итак, мой вопрос:
Кто-нибудь из вас когда-либо делал это - и если да, то как вы это сделали?
И причина: вы видите какие-либо явные ошибки в коде (надеюсь, что не стоит много спрашивать)
Ответы
Ответ 1
Возможно, это проблема с кодировкой. Здесь работает рабочий сервер С#:
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>
В этом примере устанавливается только рукопожатие. Вам нужно будет настроить сервер, чтобы продолжить прием данных после установления рукопожатия.
Ответ 2
Пожалуйста, используйте кодировку UTF8 для отправки текстового сообщения.
Существует сервер веб-сервера с открытым исходным кодом, который реализован С#, вы можете использовать его напрямую.
http://superwebsocket.codeplex.com/
Это мой проект с открытым исходным кодом!
Ответ 3
В .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