Advertisement

C# Websocket server not receiving messages from HTML5 client

Started by November 17, 2017 02:43 AM
5 comments, last by hplus0603 7 years ago

I'm attempting to create a bare bones websocket chat room server. My client is able to connect to the server, but it is unable to send messages to the server, despite the server being in a listening state.

When the client connects, a bunch of what looks like header information gets written to the console. But when WebSocket.send() gets executed in Javascript, nothing occurs server side.

HTML:


<button id="closeSocket">disconnect</button><br />
<input id = "inputField" /><button id="sendMessage">send</button>
<div id = "output"></div>

<script type = 'text/javascript' src = 'websockets.js'></script>

Javascript:


websocket = new WebSocket("ws://127.0.0.1:80");

document.getElementById("closeSocket").onclick = closeSocket;
document.getElementById("sendMessage").onclick = sendMessage;

websocket.onopen = function(){
  output("connected");
}

function sendMessage(){
    output("sent: " + document.getElementById('inputField').value);
  websocket.send(document.getElementById('inputField').value);
}

websocket.onmessage = function(e){
  output("got response: " + e.data);
}

function closeSocket(){
    websocket.close();
}

websocket.onclose = function(){
    output("disconnected");
}

function output(t){
    document.getElementById("output").innerHTML += t + "<br />";
}

C# Server:


using System;
using System.Net;
using System.Net.Sockets;

namespace WebSocketsTutorial {
    class Program {
        static void Main(string[] args) {
            TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 80);
            TcpClient client = default(TcpClient);

            server.Start();
            Console.WriteLine("server started");

            while (true) {
                client = server.AcceptTcpClient();

                byte[] receivedBuffer = new byte[100];
                NetworkStream stream = client.GetStream();

                stream.Read(receivedBuffer, 0, receivedBuffer.Length);

                foreach (byte b in receivedBuffer) {
                    Console.Write(Convert.ToChar(b).ToString());
                }
            }
        }
    }
}

This is what is output on the console when the client connects:

Untitled.png.67cdd364df4b78f6cc4435c49f07a476.png

What I'm mainly looking to do is to allow an arbitrary number of connections and ultimately have the server echo a user's submission to all connected clients.

Your C# server is rather broken. Your loop keeps attempting to accept connections every time it iterates, meanwhile it also attempts to read from the same socket, which as soon as the initial read is complete will result in some data being printed and the server back at the "accept" line.

 

You need to keep track of your clients that have connected and respond to them sending you data, not throw them away.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Advertisement

When I moved the client = server.AcceptTcpClient(); above the start of the loop, what I got was that that initial handshake was longer and contained a lot more weird information, but that attempts to "send testmessage" from the client would still have nothing happen serverside.

You need to think about the control flow. Moving it outside the loop would mean you only ever accept one client, and then read from that one forever. Fine in some circumstances, but probably not what you want.

Failing to store `client` anywhere, as in your current example, means you let a client connect, read some data, and then disconnect it and repeat the process the next time through the loop. You will want to be storing each client in a data structure so that you can service all of them periodically. Your current structure with the infinite loop makes this hard to do as it explicitly waits on just one socket, repeatedly.

You're also calling this a 'Websocket' but your server-side connection is not a websocket at all - it's just a normal socket. A websocket is a very specific thing, i.e. a socket that accepts an initial HTTP request and transforms that into a 'raw' socket. See here, for example: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers . You don't currently have any of that logic on the server side, so the best you can expect right now is just to show that an initial connection has been successful.

I would suggest that you maybe ditch the websockets for now and concentrate on getting a bare-bones server working, testing with something like Putty in raw mode instead. There are probably some trivial examples of C# chat servers around. Once you have that working as expected, you could add in the websocket support.

Do you know of a bare bones C# / HTML5 example I could paste, run, and then deconstruct? That's how I learn fastest.

I could go about building up to it like you said but that will take me much longer.

I've gotten full server/clients communicating and sending messages with a C# client and server. And I've gotten HTML5 clients talking to echo servers. But I haven't been able to find a good resources for making a C# websocket server that my HTML5 client could talk to.

 


            while (true) {
                client = server.AcceptTcpClient();

 

This is not how WebSockets work. WebSockets is a full protocol at a higher layer than TCP. Yes, you would get header information at the TCP level; a WebSockets server needs to do the right thing with that data to establish and keep running a WebSocket server.

You might want to use a known-good websocket server (node.js perhaps?) to make sure that your client is correct, and then get back to making sure that your server is correct.

 

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement