jchristn / WatsonWebsocket

A simple C# async websocket server and client for reliable transmission and receipt of data
MIT License
277 stars 53 forks source link

Communication with JS websockets #35

Closed maomao1983zy closed 4 years ago

maomao1983zy commented 4 years ago

Thanks for your work with this library. I had some problems with this library.Please forgive my poor English.

Title

server c# static void Main(string[] args) { using (WatsonWsServer wss = new WatsonWsServer("127.0.0.1", 4000, false)) { wss.ClientConnected += (s, e) => { Console.WriteLine(e.IpPort + " is connected."); };

            wss.ClientDisconnected += (s, e) =>
            {
                Console.WriteLine(e.IpPort + " is disconnected.");
            };

            wss.MessageReceived += async (s, e) =>
            {
                Console.WriteLine(BitConverter.ToString(e.Data));
                await wss.SendAsync(e.IpPort, e.Data);
            };
            wss.Start();

            Console.WriteLine("press any key to exit.....");
            Console.ReadKey();
        }

Error WebSocket connection to 'ws://127.0.0.1:4000/socket' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

Do you have any hints?

jchristn commented 4 years ago

Hi @maomao1983zy could you help me reproduce this? I tested using my Test.Server project and Chrome's console and it worked without the exception.

image

Also I notice in your exception it's going to /socket, whereas mine did not. Perhaps that's part of the problem?

jchristn commented 4 years ago

Hi @maomao1983zy wasn't sure if you saw the comment above

Xeenych commented 4 years ago

The same problem for me Logger says: [WatsonWsServer.AcceptConnections] non-websocket request rejected from 127.0.0.1 :58722

jchristn commented 4 years ago

Hi @Xeenych please help me reproduce this. I can't reproduce using the test server and the Chrome console. Thanks

Xeenych commented 4 years ago

I have Chrome version 86.0.4240.75 Windows 7x64 test.server.exe is run from bin/debug/net452

jchristn commented 4 years ago

Thanks - could you post your JavaScript code and the code you use to initialize WatsonWebsocket?

Xeenych commented 4 years ago

Javascript is just web in console let socket = new WebSocket("ws://localhost:9000/"); or let socket = new WebSocket("ws://127.0.0.1:9000/"); it doesn't matter

C# code is your test.server without any changes

jchristn commented 4 years ago

Like this?

image

image

JS code I was using:

let socket = new WebSocket("ws://localhost:9000/");
socket.onopen = function () { console.log("success"); };
socket.onmessage = function (msg) { console.log(msg.data); };
socket.onclose = function () { console.log("closed"); };
socket.send("foo");
Xeenych commented 4 years ago

Yes

jchristn commented 4 years ago

I'm going to need more to look at here. I'll need code for both client and server and preferably screenshots.

Xeenych commented 4 years ago

See this video. https://yadi.sk/d/1AYnUt2ECN5XLQ

The code is here: https://github.com/jchristn/WatsonWebsocket/tree/master/Test.Server

jchristn commented 4 years ago

Thank you for the video. Very helpful. Frankly I'm not exactly sure why or how that's happening. I'm using Chrome version 85.0.4183.121 and this isn't happening. Let me try updating and see if I can reproduce.

jchristn commented 4 years ago

Testing after update image

jchristn commented 4 years ago

Ok, this is interesting. I'm using the same version of Chrome (86.0.4240.75) using the same command in the JS console and getting an entirely different result.

image

There's a property on the webserver called HttpHandler that can be set. If I provide some sample could would you be willing to test with that so I can see fully what your server instance is receiving?

jchristn commented 4 years ago

Pushing a patch now which has a small fix to the library as well as updates to the Test.Server project including the enumeration of non-websocket requests. Once you update you should see something like this in the console:

[WatsonWsServer.Start] starting on http://localhost:9000/
Command [? for help]: [WatsonWsServer.AcceptConnections] non-websocket request forwarded to HTTP handler from ::1:51477: GET /
Non-websocket request received for: GET /
Headers:
DNT: 1
Upgrade-Insecure-Requests: 1
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Connection: keep-alive
Accept: text/html
Accept: application/xhtml+xml
Accept: application/xml;q=0.9
Accept: image/avif
Accept: image/webp
Accept: image/apng
Accept: */*;q=0.8
Accept: application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip
Accept-Encoding: deflate
Accept-Encoding: br
Accept-Language: en-US
Accept-Language: en;q=0.9
Host: localhost:9000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36

Would you be willing to update, re-run, and send me the console output?

NuGet v2.2.0.2: https://www.nuget.org/packages/WatsonWebsocket/2.2.0.2 Commit: https://github.com/jchristn/WatsonWebsocket/commit/602addc3f5e35de4719a7efd3646ec2febe3ca5a

Xeenych commented 4 years ago

That's what I get

Server IP: [localhost]
Server port: [9000]
Use SSL: [y/N]?
[WatsonWsServer.Start] starting on http://localhost:9000/
Command [? for help]:
Command [? for help]:
Command [? for help]: [WatsonWsServer.AcceptConnections] non-websocket request f
orwarded to HTTP handler from ::1:59646: GET /
Non-websocket request received for: GET /
Headers:
  Origin: chrome://new-tab-page
  Sec-WebSocket-Version: 13
  Sec-WebSocket-Key: JYTjtu8nsd5HKFju4SjDVQ==
  Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
  Cache-Control: no-cache
  Connection: Upgrade
  Pragma: no-cache
  Upgrade: websocket
  Accept-Encoding: gzip
  Accept-Encoding: deflate
  Accept-Encoding: br
  Accept-Language: ru-RU
  Accept-Language: ru;q=0.9
  Accept-Language: en-US;q=0.8
  Accept-Language: en;q=0.7
  Accept-Language: de;q=0.6
  Accept-Language: uk;q=0.5
  Accept-Language: es;q=0.4
  Accept-Language: bg;q=0.3
  Host: localhost:9000
  User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML
, like Gecko) Chrome/85.0.4183.121 Safari/537.36
jchristn commented 4 years ago

Here are the headers that come in under my successful tests:

GET /
Headers:
  Origin: chrome://new-tab-page
  Sec-WebSocket-Version: 13
  Sec-WebSocket-Key: FEUF9CshU2tSyEg5Hcyx3Q==
  Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
  Cache-Control: no-cache
  Connection: Upgrade
  Pragma: no-cache
  Upgrade: websocket
  Accept-Encoding: gzip
  Accept-Encoding: deflate
  Accept-Encoding: br
  Accept-Language: en-US
  Accept-Language: en;q=0.9
  Host: localhost:9000
  User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36

The only differences are the Sec-WebSocket-Key which we would expect to change, and, the various Accept-* headers, which wouldn't change behavior.

Actually, I just realized you said you were on Windows 7... Which doesn't support websockets. https://stackoverflow.com/questions/11039438/using-websocket-on-windows-7

WatsonWebsocket uses the underlying http.sys and doesn't implement its own webserver. That's likely the exact reason why it's not working for you. The underlying http.sys in Windows 7 doesn't know how to upgrade a standard HTTP connection to websockets.

Xeenych commented 4 years ago

I tried WebsocketSharp and NetCoreServer libraries. Don't know how they work internally, but they work on win7

jchristn commented 4 years ago

Yes, they have their own underlying HTTP implementation and don't rely on http.sys.