Showing posts with label NodeJS. Show all posts
Showing posts with label NodeJS. Show all posts

Friday, June 5, 2015

Working Around Nodejs Module Common Singleton Design Pattern

I ran into a problem a few days ago. I built this really nifty queue module. It removes elements once they're old as defined by the key "endTime" (which come to think about it, maybe that could be a future enhancement to specify how to "expire", but I digress). Here is the problem, I needed a second queue. Well I can't just require my queue module in because it's cached and well it's not a "new" instance.

So for example.

var queue = require('queue.js');
var queue2 = require('queue.js');

queue.add({endTime : 1234});
queue2.add({enddTime : 2345});

// Assume queue.element returns the head of the queue
console.log(queue.element());

Output
>> {endTime : 2345}

// Assume queue.entire returns the entire queue
console.log(queue2.entire());

Output
>> {endTime : 1234}, {endTime : 2345}

As you can see you don't get a unique queue.

I found some examples around the interwebs and gave it a try. I have a problem with the common approach shown below.

var queue = function(){
   var self = this;
   self.local_queue = [];
   var funcs = {
                      add : function (obj){
                      ...... stuff ......
                      },
                     entire : function(){
                     ..... stuff..........
                     }
                     ...
       }
}
module.exports = function(){
    return new queue();
}

I don't like implementing my functions IN the surrounding function (the add: function example).

I prefer the following:

var add = function(obj){
... stuff ...
}

...

...


var queue = function(){
   var self = this;
   self.local_queue = [];
   var funcs = {
                      add : add,
                     entire : entire,
                     ...
       }
}
module.exports = function(){
    return new queue();
}

The problem is that my functions were not able to reference self. 

So I finally worked around this like this.

var add = function(self, obj){
... stuff ...
}

...

...


var queue = function(){
   var self = this;
   self.local_queue = [];
   var funcs = {
                      add : function(obj){return add(self, obj)},
                       ...
       }
}
module.exports = function(){
    return new queue();
}


If you notice now we have a self reference being passed to the function, all is now well in queue land.

Now when I require in it looks something like this.

var queue = require('./queue')
var queue1 = new queue();
var queue2 = new queue();

Now any adds and removes all affect only their own queues.

If you have a better cleaner way to implement this I'd be happy to see it.

Thursday, August 28, 2014

Post JSON to Nodejs from Angularjs

I'm struggling with the title of this post as I searched many ways but couldn't find something simple like this.
If you have any other name suggestions I'm totally open!
Here goes.

I wanted to send JSON from an AngularJS app and get it on my NodeJS side so I could do something with the data.

There may be better ways (Socket.IO anyone?) but here goes:

Here is my angularJS service:


And here is my nodejs page:

Install express, and body-parser (I think that's about all) and you should be able to send a message using
$message.create({ }); // That's a JSON object being passed in
Simple AngularJS controller

And Finally a simple HTML page for it.

Good Luck!
I hope that helps SOMEONE out there.

Wednesday, August 20, 2014

Control your Network Connected Devices

Today I want to tell you about a little epiphany I had a few weeks back. I realized that I could connect firebase to a local nodejs server and a public facing website, and control my roku.

Most people read this and think....well duh you can already control your roku using your phone. At this time (please prove me wrong) you need to be on your Intranet. Your Intranet is the network in your house that your roku is on, so basically you have to be on the same wifi as your roku.

This means you can setup a website using firebase to authenticate you, connect to a common data point in your database and now control things in your house from ANYWHERE as long as both have an internet connection. So I could be in Hong Kong and change the channel on my roku.

Ok, big deal why should I care? Well what if I told you that your roku isn't the only device that connects to the internet? You can query for all these devices, setup commands for them, and control them from anywhere! Forgot a light on in the house when you left? With (some) devices you can check the status and turn it off/on. This kinda makes that whole "internet" of things a lot closer to reality without completely opening up your network, the only "failure" point here is if your firebase gets hacked or something.

But you want code....

https://github.com/onaclovtech/MediaController

Here is the side that runs in your house (and you could also just run this on a raspberry pi or something instead of a dedicated full blown computer).

Right now I have my own rolled roku controller, but I think there is one in npm already that I haven't checked out. You can control your Chromecast this way. Possibly smart tv's etc.


Details for the people who are interested:

Node Side:
1. Start server
2. Server does a query for network devices and adds them to a list.
3. Server pushes list to myfirebaseurl/mediadevices
4. Server then sets up a callback to trigger when a child changes (state specifically).
5. Server sets up functions to handle deleting devices in mediadevices when it closes (this is to ensure that the devices are always accessible).

AngularJS side:
1. Connect to myfirebaseurl/mediadevices
2. Associate NG model to a dropdown (that's how I'm swapping between, if you have other ideas I'd love to hear them).
3. When a button is pressed, it looks at which device is selected and changes it's state to whatever mode that button is designed to accomplish.
4. If the server is removed then mediadevices is empty and the dropdown goes away.




Let me know what you think! If you have a chromecast, amazontv, etc that you want to build this on, or want to lend me to build it on, lemme know I'd love to chat!

Tyson


Sunday, February 10, 2013

Roku SSDP nodejs

I tried using the SSDP to find the roku ip address using ncat as recommended by Roku, but using wireshark to moitor it just didn't seem to be working. In Ubuntu using sudo wireshark brings up the app, selecting your network interface under filter type in udp.dstport == 1900 and click apply, I was seeing my router and the roku box notifying the 239.255.255.250 ip of their ip addresses, but I wasn't seeing the "M-SEARCH * HTTP/1.1 showing up. I wanted a nodejs solution so I tried searching for that, hoping that might change things up, I found this:

However placing the roku parameters ST: just wasn't working"roku:ecp", I did notice in the notify from the box that it was using MX as 2, so I tried updating that, however still no luck. After consulting nodejs.org I discovered the optional call back and in their example they close the connection when the call is completed. So I made the update to the following.

It appears that the program was closing the client connection before the message was sent out (and a response occurs), so once I put in the callback to close it, I got a response. Hope that helps anyone else who wants to use SSDP.

 Check out the Roku Remote nodejs module I am working on.

Thursday, January 31, 2013

Using Nodejs as a fileserver


Creating a Simple Fileserver.
Tip #2
I wanted a simple fileserver, I tried looking for a variety of search terms, but finally came upon simple file server. I came across the post linked by Tip #2 above, but it wasn't exactly clear what it was doing exactly.

The documentation isn't 100% clear so I played with it a little, (and added some comments to one of the posters).

I used connect.

Install it with npm connect.

Next use the following code:

var connect = require('connect'),
    http = require('http');
connect()
    .use(connect.static('pathyouwishtoserve'))
    .use(connect.directory('pathyouwishtoserve'))
    .listen(8080);
.use(connect.static('pathyouwishtoserve')) tells the server where to look for files.
.use(connect.directory('pathyouwishtoserve')) tells the server to return the following directories contents.

If you now navigate to http://your-ip-address:3000 you'll get a list of the directory contents,
if you add a /filename to that path you'll get the file.


I'll be posting tips as I come across them of using NodeJS as an intranet fileserver.
Long story short, I want to build a Roku app that will refer to the NodeJS server for where to find the files. I figure it'll be simpler than PLEX, and also faster (I'm hoping). Once I get the stuff running I'll plan on running it on my Pogo Plug as a media server for my Roku, totally awesome!

Sunday, January 27, 2013

Using NodeJS as an Intranet Webserver

I'll be posting tips as I come across them of using NodeJS as an intranet webserver.

Long story short, I want to build a Roku app that will refer to the NodeJS server for where to find the files. I figure it'll be simpler than PLEX, and also faster (I'm hoping). Once I get the stuff running I'll plan on running it on my Pogo Plug as a media server for my Roku, totally awesome!

Tip #1
When running a http://nodejs.org/ port, the IP address should be of the machine you are currently on. I chose the port 8080 as it's the standard http port.

From linux you can find this by doing a simple ifconfig command on the command line. From windows ipconfig should do it.

Then using the example below: (from the NodeJS website)

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

So when you go to another machine such as your phone and access the page 100.11.1.6 you should get "Hello World". When you're able to do this, your Roku can now see the server (when you have the app setup).

The above tip was discovered after a google search to figure out an error. The link is from stackoverflow, and can be clicked above on the Tip #1 link.