#c# #sockets #websocket #asyncsocket
#c# #сокеты #websocket #asyncsocket
Вопрос:
Я пытаюсь создать асинхронный сервер websocket с использованием c #.
Я уже завершил рукопожатие после долгих поисков в Интернете.
Но после рукопожатия я не могу отправить какие-либо данные в формате массива байтов: (
Это код, который я использую для отправки данных byte [] в принятый и подключенный сокет (я проверяю оба!)
socket.Send(Encoding.Default.GetBytes("Hello"));
//socket is a System.Net.Sockets.Socket object.
Если я попытаюсь это сделать, я получу это на стороне клиента (я использую расширение Chrome под названием «Simple Web Socket Client»):
index.js:15 WebSocket connection to 'ws://localhost:2017/' failed: Invalid frame header
CLOSED: ws://localhost:2017
(Да, 2017 — это порт), но почему он говорит недопустимый фрейм
Хорошо, я понимаю, что в строке «hello» нет заголовка фрейма, но, похоже, я не могу найти подходящий заголовок нигде в Интернете: (и ДА, я искал, и все, что я получаю, — это серьезно запутанная спецификация RTC!
Кто-нибудь здесь знает, что я делаю не так?
Комментарии:
1. Я не уверен, куда вы смотрели, но взгляните на конечный источник для websockets, то есть стандартный RFC 6455. Он описывает , как выполняется кадрирование. Вы вообще не создаете фрейм в своем примере кода, а просто отправляете данные без фрейма непосредственно в сокет (не в websocket).
2. Я знаю, что я не делаю никаких обрамлений, я даже не знал, что это такое, пока не получил сообщение об ошибке (добро пожаловать в программирование: P), я просто хочу отправить аудиопакеты byte [] клиентам, но я не знаю, как это сделать после рукопожатия
Ответ №1:
Как вы можете видеть в этой статье или в самой спецификации WebSocket, протокол WebSocket обменивается данными в определенном формате фрейма данных. Вы не просто записываете байты в обычный сокет.
Вот пример того, как выглядит формат фрейма:
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
- - - - ------- - ------------- -------------------------------
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
- - - - ------- - ------------- - - - - - - - - - - - - - - -
4 5 6 7
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| Extended payload length continued, if payload len == 127 |
- - - - - - - - - - - - - - - -------------------------------
8 9 10 11
- - - - - - - - - - - - - - - -------------------------------
| |Masking-key, if MASK set to 1 |
------------------------------- -------------------------------
12 13 14 15
------------------------------- -------------------------------
| Masking-key (continued) | Payload Data |
-------------------------------- - - - - - - - - - - - - - - -
: Payload Data continued ... :
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| Payload Data continued ... |
---------------------------------------------------------------
Вы должны поместить свои данные в этот формат, а также использовать схему безопасности, основанную на ранее переданных учетных данных безопасности. WebSocket — это не простой сокет. Вы должны использовать протокол WebSocket.
К вашему сведению, мои сотрудники не внедряют конечные точки WebSocket с нуля, а скорее подбирают библиотеку на выбранном вами языке, которая выполняет всю эту работу за вас. Затем вы можете просто отправить байты, и библиотека позаботится о работе протокола за вас.
Комментарии:
1. Хорошо, спасибо за объяснение! Я видел это в спецификации, но извините, если это звучит глупо, но я этого совсем не понимаю.. как это перевести в код? Является ли первая строка чисел байтовыми индексами? Мне все это кажется случайными числами и символами ‘ ^-^
2. @ErikBrandsma — Почему вы пытаетесь реализовать протокол WebSocket с нуля? Большинство людей выбирают библиотеку, которая выполняет всю работу протокола за вас, а затем вы можете просто отправлять то, что хотите, не беспокоясь обо всех этих деталях. Если вы собираетесь внедрять протокол с нуля, вам нужно научиться читать документы RFC с нуля, поскольку они являются окончательной ссылкой на то, что требуется в протоколе. В этом протоколе задействовано многое, включая шифрование.
3. Я не xD, я просто хочу передавать пакеты audio byte [] клиентам. Цель состоит в том, чтобы передавать звук Windows (стереомикс) клиентам, у меня уже есть часть, в которой я получаю пакеты byte [] с аудиокарты, но теперь я хочу отправить эти данные клиентам, и сокеты показались лучшим вариантом для этого
4. @ErikBrandsma — Какие клиенты? Клиенты браузера? Или что? Браузеры уже поддерживают различные форматы потокового аудио.
5. @ErikBrandsma — Мы ответили на ваш первоначальный вопрос здесь. Если вы хотите задать новый вопрос, в котором вы описываете свою фактическую проблему высокого уровня, я бы посоветовал вам написать новый вопрос, в котором подробно описываются ваши требования и с чем вы ищете помощь. Просто имейте в виду, что запрос сторонней библиотеки, которая делает что-то конкретное, здесь «не по теме» из-за переполнения стека, и подобные вопросы будут закрыты. Я не вижу причин, по которым вы вообще использовали бы WebSocket для этой конкретной потребности.
Ответ №2:
Я также столкнулся с такой же проблемой. Решается путем установки socket.io at client side
. Это может сработать и для вас.