Showing posts with label html5. Show all posts
Showing posts with label html5. Show all posts

Wednesday, January 23, 2013

WebSocket: Alchemy - C# <-> javascript

Reference: http://divyen.wordpress.com/2012/06/13/html5-developing-websocket-server-using-c-sharp-dot-net/ 

Downloaded src code. http://alchemywebsockets.net/
Open it in Visual C# 2010 express
Managed to compile and get the Alchemy.dll

Created a new Console app project. added DLL
added the codes. https://gist.github.com/2976928
Build and then error....

Warning 8 - The referenced assembly "Alchemy" could not be resolved because it has a dependency on "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which is not in the currently targeted framework ".NETFramework,Version=v4.0,Profile=Client". Please remove references to assemblies not in the targeted framework or consider retargeting your project.

Go to Project Properties > application > Target Framework > .NET Framework 4
Click Yes for message box.

Build and Run. no more error.

added HTML codes. https://gist.github.com/a9409a82d2379d52e9af
run in chrome. HTML connected with websocket. clock ticking. cool.


Sunday, April 01, 2012

HTML5 WebSocket server using c#

Use Socket.Listen(10) as per normal.
on Socket.Accept(): the HTML5 client from the browser will initiate a handshake.
grab the request using Socket.Receive(byte[])
C#:

bytes = new byte[1024];
 int bytesRec = client.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);

Example:

"--- Request ---
GET /echo HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 127.0.0.1:9998
Origin: null
Sec-WebSocket-Key: NBX4xUnlu1QWVPtGE2RFyw==
Sec-WebSocket-Version: 13"

To generate a response back, need a few steps.
Reference: http://en.wikipedia.org/wiki/WebSocket#WebSocket_protocol_handshake

Get the key, eg.: "NBX4xUnlu1QWVPtGE2RFyw=="
append the magic string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" to the key.
Use SHA1 to hash the combined string.
Convert this string to base64

Reference: http://www.gamedev.net/topic/611744-websocket-c-handshake-client-does-not-response-on-handshake/
C#:

string combined = key + magicString;
 SHA1 sha = new SHA1CryptoServiceProvider();
byte[] hash = sha.ComputeHash(Encoding.ASCII.GetBytes(combined));
string acceptKey = Convert.ToBase64String(hash);

so in this case, accept key is "YOBURURfF9giWA8womjw1NpT9fk="

Then form the response.
Example:

"--- Response ---
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: YOBURURfF9giWA8womjw1NpT9fk="

use "\r\n" to end each line. and add an additional "\r\n" to the last line, ie., two "\r\n"

send this thru the socket.
example:

byte[] outputBytes = Encoding.ASCII.GetBytes(output);
 int result = client.Send(outputBytes);

To decode any message from client. using the WebSocket.send(message) method
Reference: http://stackoverflow.com/questions/8125507/how-can-i-send-and-receive-websocket-messages-on-the-server-side

sequence: "one byte which contains the type of data
one byte which contains the length
either two or eight additional bytes if the length did not fit in the second byte
four bytes which are the masks (= decoding keys)
the actual data"

to decode: "decodedByte = encodedByte XOR masks[encodedByteIndex MOD 4]"
C#:

                    bytes = new byte[1024];
                    int bytesRec = client.Receive(bytes);


                    int second = bytes[1] & 127; // AND 0111 1111
                    int maskIndex = 2;
                    if (second < 126)
                    {
                        // length fit in second byte
                        maskIndex = 2;
                    }
                    else if (second == 126)
                    {
                        // next 2 bytes contain length
                        maskIndex = 4;
                    }
                    else if (second == 127)
                    {
                        // next 8 bytes contain length
                        maskIndex = 10;
                    }
                    // get mask
                    byte[] mask = { bytes[maskIndex], 
                                  bytes[maskIndex+1], 
                                  bytes[maskIndex+2], 
                                  bytes[maskIndex+3]};
                    int contentIndex = maskIndex + 4;


                    // decode
                    byte[] decoded = new byte[bytesRec - contentIndex];
                    for (int i = contentIndex, k = 0; i < bytesRec; i++, k++ )
                    {
                        // decoded = byte XOR mask
                        decoded[k] = (byte)(bytes[i] ^ mask[k % 4]);
                    }
                    data = Encoding.UTF8.GetString(decoded, 0, decoded.Length);
                    Console.WriteLine(data);