Home > Dev Tips, Silverlight, Windows Phone > Getting Started with Node.js and Mango (Sockets)

Getting Started with Node.js and Mango (Sockets)

It’s been a while since I’ve found time to blog – but it’s not like I’ve left you in cold hands. Rohan has been doing a great job posting on the Silverlight for Windows Phone Performance blog (check it out if you haven’t yet).

On a completely non-performance related topic (we’ll get to those in the next couple of blog posts), I’ve been meaning to play around with Node.js for a while, and when a colleague posed a question about using it with Mango, I thought it might be a great excuse to polish off the Beta 2 tools (get them while they’re hot!) and do some Socketing!

First things first – grab 7zip (if you don’t have it already), and Node.js binaries for Windows (or build it yourself). Extract these to a convenient location and you should be good to go.

We’re going to use the Hello World sample ripped straight from the Node.js homepage, with one extra debugging addition (highlighted in yellow) and a practical change (highlighted in green – see “gotcha!” below):

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
 console.log('Sent message'); }).listen(1337, "192.168.2.125");
console.log('Server running at http://192.168.2.125:1337/');


Gotcha Warning!

A common mistake at this point is to stick with the sample’s use of 127.0.0.1 (locahost). This will work great from your browser, but not from the emulator or your device (regardless of whether it is connected to WiFi or tethered via Zune). This is because the emulator and the device join the network as *new* devices which means they get a newly assigned IP address and they act just as though they were a machine on the network. This leads to 127.0.0.1 pointing back to themselves, which is not allowed, leaving you with a “NetworkDown” network error. Instead, make sure to set your IP to your local LAN address (usually starts with 192.168.X.X or 10.X.X.X). You can find your exact IP address from cmd by typing “ipconfig” and looking for the address that corresponds to your local network.

Testing the Server

Now, save your modified script somewhere somewhere convenient (I saved it to c:\nodejs\bin\servers\helloworld.js) and then launch the server with a simple:

C:\nodejs\bin>node servers/helloworld.js
Server running at http://192.168.2.125:1337/

Note the use of UNIX style paths… If you see any errors at this point it’s most likely path related. Fix your path so it is relative to your binary and you should be good to go. Need to verify that everything is working? Fire up your browser and enter http://localhost:1337 and you should see “Hello World!”.

Note: When launching the server you may get the Windows warning dialog about a program accessing the network, feel free to set the settings to whatever you are comfortable with, just note that Node.js will need at least local network access so that you can talk to it from the emulator / a device over WiFi.

Let’s get me some Windows Phone!

We’re up and running, so time to get our hands dirty with some C# code. Open Visual Studio and start a new C# Windows Phone application targetting “Windows Phone 7l.1″ (which is the code target name for Mango). The project that we create is going to do something extremely simple – it’s going to open the socket, send a request for data (it’s really a dummy request since this server isn’t really waiting for a real request) and then displays the response, verbatim, on the screen.

Once you have the project created add a button (btnStart), which will kick the whole process off, and a textblock (txtServerResponse) to contain the server response. We’re not going to use binding to simplify the sample, but you can certainly do that instead. Add a Click handler to the button by double clicking on it and add the following code to MainPage.xaml.cs. The code is heavily documented so should answer any further questions you might have. I’ve also stuck a zipped version of the project (including the mini-server) which you can use to experiment with.

private Socket _socket;

private void btnStart_Click(object sender, RoutedEventArgs e)
{
    // the message to send to the server
    byte[] message = UTF8Encoding.UTF8.GetBytes("GET / HTTP/1.1\nHost: localhost\n\n");

    // the address we'll be connecting to
    IPAddress address  = new IPAddress(new byte[] {192, 168, 2, 125});

    // an endpoint translates into the complete destination - address + port
    // you can also use a DnsEndpoint to look up an IP address from a hostname
    IPEndPoint endpoint = new IPEndPoint(address, 1337);

    // all socket operations are asynchronous on the phone so you must set up 
    // a SocketAsyncEventArgs object to let the socket know how to act
    SocketAsyncEventArgs args = new SocketAsyncEventArgs() { RemoteEndPoint = endpoint };

    // don't allow multiple clicks before the request finishes
    btnStart.IsEnabled = false;

    // create our socket, note that it isn't connected yet
    _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    // set up the call back to be called when we finish connecting to the socket
    args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSocketConnected);

    // neat trick - setting the buffer of a socket before it connects will cause the socket to send
    // that data as soon as it connects
    args.SetBuffer(message, 0, message.Length);

    // boom! we're off
    _socket.ConnectAsync(args);
}

void OnSocketConnected(object sender, SocketAsyncEventArgs e)
{
    if (e.SocketError != SocketError.Success)
    {
        // don't forget that we're now on a background thread so anything that interacts with
        // the UI thread (MessageBoxes, updating UI etc) has to be dispatched back
        Dispatcher.BeginInvoke(() =>
        {
            MessageBox.Show("(Connect) Socket error! " + e.SocketError.ToString());
        });
        return;
    }

    // we're done with the connect + send, time to receive

    // create a buffer for the respone
    byte[] buffer = new byte[1024];

    // create the Socket event args for this receive
    SocketAsyncEventArgs args = new SocketAsyncEventArgs();

    // set a buffer for the receive - the size will be the maximum amount read
    args.SetBuffer(buffer, 0, 1024);

    // we have to come back somewhere after the receive completed
    args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSocketReceive);

    // kick off the actual receive
    _socket.ReceiveAsync(args);
}

void OnSocketReceive(object sender, SocketAsyncEventArgs e)
{
    if (e.SocketError != SocketError.Success)
    {
        Dispatcher.BeginInvoke(() =>
        {
            MessageBox.Show("(Receive) Socket error! " + e.SocketError.ToString());
        });

        return;
    }

    // the response comes back as a byte array, so convert it to a string
    // Note: usually you would read from the buffer and then call _socket.ReceiveAsync(e)
    // again until e.BytesTransferred == 0 (signals end of the receive), for this example
    // we're going to keep it simple
    string response = UTF8Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred - 1);

    // we have our response now update the UI thread
    Dispatcher.BeginInvoke(() =>
    {
        txtServerResponse.Text = response;
        btnStart.IsEnabled     = true;
    });
}

What does it look like?


Questions?

Feel free to leave comments below – Good Luck!

Download the solution + js file

Categories: Dev Tips, Silverlight, Windows Phone Tags:
  1. pisey
    November 27th, 2013 at 19:40 | #1

    If I want to chat, how can implement?

  2. February 9th, 2014 at 13:52 | #2

    Oren Nachman » Getting Started with Node.js and Mango (Sockets)
    air max bebe pas cher http://www.hipotelhotel.com/shox-vital.asp?id=air-max-bebe-pas-cher

  3. April 16th, 2014 at 18:58 | #3

    Oren Nachman » Getting Started with Node.js and Mango (Sockets) replica bags

  4. April 21st, 2014 at 23:55 | #4

    I do accept as true with all of the ideas you’ve introduced
    in your post. They are really convincing and
    will definitely work. Nonetheless, the posts are very quick for novices.
    Could you please lengthen them a little from subsequent time?
    Thanks for the post.

  5. April 29th, 2014 at 13:06 | #5

    Is direct generation starting off to frustrate you? You need tolerance in purchase to get them. However, if you are not doing things effectively, this could get you a even though to determine out. The subsequent post will manual you by way of making business sales opportunities. insanity work

    Incentives can push persons to act when they wouldn’t in any other case. For instance, incentives that involve them getting something they currently will need can have them opt into your supply. You will create far more leads by presenting one thing.

  6. June 11th, 2014 at 04:22 | #6

    Linda. porem um pouco curta pra mim.. eles tinham que fazer um pouco maior o comprimento pq nos brasileiras somos mais altas.. rsrs mas enfim eu gostei !!!Will defenitly buy again. Great shirt and great quality And those who are actively engaged in running or cycling, that is inflated legs, these jeans should be taken with some reserve. Pockets
    louis vuitton monogram bag http://www.maggihambling.com/brand.php?Search=258&louis-vuitton-monogram-bag

  7. June 17th, 2014 at 01:02 | #7

    Excellent. Very fast delivery (less than 2 weeks to Moscow), good quality. A little minus for me: there is no “middle pocket” inside the bag.Goods shipped as soon as possible. Recommend. very soft material and lightweight. And those who are actively engaged in running or cycling, that is inflated legs, these jeans should be taken with some reserve. Pockets
    ralph lauren polo shirts http://www.consolandi.it/public/brand/ralph-lauren-polo-shirts.html

  8. June 27th, 2014 at 20:45 | #8

    Woah! I’m really loving the template/theme of this blog.
    It’s simple, yet effective. A lot of times it’s challenging to get that “perfect balance” between superb usability and appearance.
    I must say you’ve done a awesome job with this. In addition, the blog loads extremely fast for me
    on Firefox. Outstanding Blog!

  9. July 11th, 2014 at 04:02 | #9

    Thanks to the seller! Handbag beautiful! Come make a very fast!bag just class! came very quickly. just super! Thank you so much!!!Excellent! Wonderful bag! Great seller! Thank you for fast shipping!

  10. September 9th, 2014 at 04:55 | #10

    Heey there! Do you know if they make any plugins to safeguard against hackers?
    I’m kinbda paranoid about losing everything I’ve worked hard on. Any
    tips?

  1. July 14th, 2011 at 00:11 | #1
  2. August 3rd, 2011 at 03:14 | #2
  3. August 22nd, 2011 at 01:43 | #3