I am writing a websocket client using C#. But I can't figure out how to send the websocket handshake request to the server in C# and how to generate sec-websocket-key.
The client request sample will be like below.
GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Server response sample would be like below.
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Look at the sample websocket server code from mozilla.
To generate the key on client side you can use random generators.
String secWebSocketKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("WebSocket rocks!"));
Related
I'm following the following link https://docs.aws.amazon.com/AmazonS3/latest/dev/HLuploadFileDotNet.html
to upload files from local machine to an S3 bucket on VPC. The application is also testing and running on the on-premise machine.
var s3Client = new AmazonS3Client(RegionEndpoint.USEast2);
var fileTransferUtility = new TransferUtility(s3Client);
await fileTransferUtility.UploadAsync("c:\tmp\test.txt", "bucketName");
However, the code gets the following error.
A socket operation was attempted to an unreachable network
Should an Url be given?
Here is the network traffic captured by Fiddler. However, it gets a different exception for the code.
GET http://1xx.1xx.1xx.2xx/latest/meta-data/iam/security-credentials HTTP/1.1
Host: 1xx.1xx.1xx.2xx
HTTP/1.1 503 Service Unavailable
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Proxy-Connection: Keep-Alive
Connection: Keep-Alive
Content-Length: 787
Network Error
Network Error (tcp_error)
A communication error occurred: "Operation timed out"
The Web Server may be down, too busy, or experiencing other problems preventing it from responding to requests. You may wish to try again at a later time.
For assistance, contact your network support team.
.aws\config
[default]
region = USWest2
I had the same error today, even though I had a valid $USERPROFILE\.aws\credentials file - it was actually because $USERPROFILE\AppData\Local\AWSToolkit\RegisteredAccounts.json couldn't be decrypted (not sure why), which causes AWS to think you don't have have local credentials, and hence tries to make a connection to the EC2 metadata URL which is http://169.254.169.254/latest/meta-data/?. On a local development machine that won't be accessible. For me, deleting the $USERPROFILE\AppData\Local\AWSToolkit\RegisteredAccounts.json file did the trick. FWIW, I only managed to figure this out by reading through the source of the AWS SDK...
I am using Nginx + Websockets on a precise 64 vagrant box, with c#/mono for the app server. The goal is to serve up static content directly through Nginx, and handle both plain 'ol http service requests (on /service) and also websocket requests (on /webSocket) all on the same port. Here's the relevant conf:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
# (1)
location / {
root /var/www;
index index.html;
}
# (2)
location /service {
add_header Access-Control-Allow-Origin *;
proxy_pass http://localhost:9000;
}
# (3)
location /webSocket {
proxy_pass http://localhost:9000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
Most of it is working well. Static content, yes, service requests, yes, and even the first part of websockets. I am getting a well-formed 101 Switching Protocols request from my client (Firefox or Chrome). I am making a nice http upgrade response and sending it. And then the client does... nothing... nothing is received.
But the crazy thing is, when I give up and manually kill my server side app, and the client web socket closes with error, THEN the Response Headers show up on the client browser debugger. The whole thing looks like:
REQUEST HEADERS
Request URL: http://localhost:8086/webSocket
Request Method: GET
Status Code: HTTP/1.1 101 Switching Protocols
Request Headers 16:18:50.000
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: Nx0sUAemOFWM2rsaCAJpfQ==
Sec-WebSocket-Extensions: permessage-deflate
Pragma: no-cache
Origin: http://localhost:8086
Host: localhost:8086
Connection: keep-alive, Upgrade
Cache-Control: no-cache
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
RESPONSE HEADERS Δ19660ms
Upgrade: websocket
Transfer-Encoding: chunked
Server: nginx/1.1.19
Sec-WebSocket-Accept: gNiAeqxcVjkiReIpdtP0EZiClpg=
Date: Mon, 08 Jun 2015 20:18:48 GMT
Connection: keep-alive
NO RESPONSE BODY Δ0ms
There's no evidence that my server app is not flushing out its send data right away - I'm using async TcpSocket.BeginSend and FinishSend and the send seems to complete right away. And it works fine on plain http service comm.
So where is my websocket message data going??? It seems like Nginx doesn't want to send it back to my client, except until I close the Tcp connection from the server side.
Has anybody experienced something like this before. Everything I've read on Nginx and Websockets is concerned with the basic setup that gets the hop-by-hop upgrade working, and I've got that. No one has anything to say as to why sending back from the server side doesn't seem to go anywhere.
When I open a web socket to my server - it looks like the client is automatically sending an HTTP request as part of the first payload. How can I prevent this?
That is the nature of the web socket protocol. It starts with a handshake done over simple HTTP
GET /mychat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13
Origin: http://example.com
More: http://en.wikipedia.org/wiki/WebSocket#WebSocket_protocol_handshake
You cannot create a websocket without this handshake.
I sent Upgrade Header in httpwebrequest header on port 80 to use TLS.Server responded successfully with 101 switching protocol response and hence upgrading the protocol.
Now I want to know how to start SSL handshake on the same port in C#.?
You don't want to be intervening in the headers (by adding "Upgrade"). Let HttpWebRequest do it's thing.
Have you tried using this which specifically tells it to use SSL, but over port 80:
var req = (HttpWebRequest)WebRequest.Create("https://your.host.com:80/test.htm");
I've created a Sample Application based on SuperWebSocket (running v0.3). I manage to get connect to the WebSocket Server through Telnet, but for some reason I'm having trouble doing it through JavaScript (running Chrome 17.0.963.46 m).
Through Telnet I can connect through either localhost:911 or 192.168.1.147:911.
My Application is running on http://localhost/Raphael-Test/, and I've tried running through both localhost and the local networks IP, both gets stuck at "Connecting" ie. status 0.
Is there anything obvious I'm missing, any configuration that should be done in the Web Application itself? I should add that I've successfully tried out the LiveChat demo, got it working through JavaScript.
This is my current Client Implementation running when the Page has been fully loaded:
ws = new WebSocket("ws://192.168.1.147:911");
ws.onopen = function () {
alert("connected");
};
ws.onmessage = function (evt) {
var msg = evt.data;
alert(msg);
};
Handshake (with NO response):
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 192.168.1.147:911
Origin: http://192.168.1.147
Sec-WebSocket-Key: 8bl46pmPrixTYRJ/5i9Sug==
Sec-WebSocket-Version: 13
It turns out I used the SuperSocket Server base classes instead of SuperWebSocket on the server side. This made the TCP connection itself work as expected, but did of course not handle the WebSocket Handshake and therefore the connection failed.