I'm trying to make a simple WebSocket between my C# and my simple JS page,
I've made my TCP server the same as from these docs
And i've implemented all methods for onconnect, onmessage etc..
The issue is that my JS page successfully handshake and connect to the server, and even successfully send the data to the server, but when i run stream.Write(response, 0, response.Length); to send some data to the Client .onmessage doesn't receive anything..
Here is my code:
C# Server:
private void tcpServer()
{
string ip = "127.0.0.1";
int port = 8080;
var server = new TcpListener(IPAddress.Parse(ip), port);
server.Start();
Console.WriteLine("Server has started on {0}:{1}, Waiting for a connection...", ip, port);
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("A client connected.");
NetworkStream stream = client.GetStream();
// enter to an infinite cycle to be able to handle every change in stream
while (true)
{
while (!stream.DataAvailable) ;
while (client.Available < 3) ; // match against "get"
byte[] bytes = new byte[client.Available];
stream.Read(bytes, 0, client.Available);
string s = Encoding.UTF8.GetString(bytes);
if (Regex.IsMatch(s, "^GET", RegexOptions.IgnoreCase))
{
Console.WriteLine("=====Handshaking from client=====
{0}", s);
// 1. Obtain the value of the "Sec-WebSocket-Key" request header without any leading or trailing whitespace
// 2. Concatenate it with "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" (a special GUID specified by RFC 6455)
// 3. Compute SHA-1 and Base64 hash of the new value
// 4. Write the hash back as the value of "Sec-WebSocket-Accept" response header in an HTTP response
string swk = Regex.Match(s, "Sec-WebSocket-Key: (.*)").Groups[1].Value.Trim();
string swka = swk + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
byte[] swkaSha1 = System.Security.Cryptography.SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(swka));
string swkaSha1Base64 = Convert.ToBase64String(swkaSha1);
// HTTP/1.1 defines the sequence CR LF as the end-of-line marker
byte[] response = Encoding.UTF8.GetBytes(
"HTTP/1.1 101 Switching Protocols
" +
"Connection: Upgrade
" +
"Upgrade: websocket
" +
"Sec-WebSocket-Accept: " + swkaSha1Base64 + "
");
stream.Write(response, 0, response.Length); // sending data to client
}
else
{
bool fin = (bytes[0] & 0b10000000) != 0,
mask = (bytes[1] & 0b10000000) != 0; // must be true, "All messages from the client to the server have this bit set"
int opcode = bytes[0] & 0b00001111, // expecting 1 - text message
msglen = bytes[1] - 128, // & 0111 1111
offset = 2;
if (msglen == 126)
{
// was ToUInt16(bytes, offset) but the result is incorrect
msglen = BitConverter.ToUInt16(new byte[] { bytes[3], bytes[2] }, 0);
offset = 4;
}
else if (msglen == 127)
{
Console.WriteLine("TODO: msglen == 127, needs qword to store msglen");
// i don't really know the byte order, please edit this
// msglen = BitConverter.ToUInt64(new byte[] { bytes[5], bytes[4], bytes[3], bytes[2], bytes[9], bytes[8], bytes[7], bytes[6] }, 0);
// offset = 10;
}
if (msglen == 0)
Console.WriteLine("msglen == 0");
else if (mask)
{
byte[] decoded = new byte[msglen];
byte[] masks = new byte[4] { bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3] };
offset += 4;
for (int i = 0; i < msglen; ++i)
decoded[i] = (byte)(bytes[offset + i] ^ masks[i % 4]);
string text = Encoding.UTF8.GetString(decoded);
Console.WriteLine("{0}", text);
}
else
Console.WriteLine("mask bit not set");
Console.WriteLine();
}
}
}
And here is my JS
websocket = new WebSocket('ws://localhost:8080');
websocket.onopen = function (e) {
console.info("CONNECTED");
websocket.send("WE")
};
websocket.onclose = function (e) {
console.info("DISCONNECTED");
};
websocket.onmessage = function (e) {
console.log("RESPONSE: " + e.data);
};
websocket.onerror = function (e) {
console.error("ERROR: " + e.data); };
question from:https://stackoverflow.com/questions/66062325/unable-to-send-message-from-tcp-c-sharp-to-websocket-in-js