Created
November 29, 2012 16:38
-
-
Save timcunningham/4170227 to your computer and use it in GitHub Desktop.
ColdFusion 10 Web sockets getting started
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfset this.name="ampMeter"> | |
<!-- This setups a web socket named meter1 --> | |
<cfset this.wschannels = [{name="meter1"}]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
When ColdFusion 10 was in early beta, I was really interested in playing with web sockets. Unfortunately I was only *playing* with them, I didn't have a real world need. So when Ray Camden wrote several demos that showed how web sockets would work, I ran the code, saw that it worked and then moved on to test something else. Long story short, I understood the principles of web sockets, without really know how to write one: till now. | |
At work we have two server rooms, they are on full UPS battery backup and natural gas generator. The generators each have a 70 amp breaker, so if the amperage load is around 70 amps and we lose power, the generator is going to trip and our server room will lose power. Do not ask me how I know this. I don't want to talk about it. | |
Anyway we purchased a neat little device called <a href="http://www.theenergydetective.com/">The Energy Detective (TED)</a> which measures the power flow being pulled from each server room. TED has a a really nice dash board that tells me many interesting stats, everything but, (you guessed it) amperage. True, I could do a simple division on the kVA, but math is hard. So web sockets to the rescue! First I re-read Evelin Varghese from Adobe's blog article about <a href="http://www.eveysijo.com/2012/02/coldfusion-websocket-for-absolute.html">ColdFusion WebSocket Part1:Getting Started</a> | |
For this implementation of web sockets we will need the following: | |
1. Set up a web socket channel name in application.cfc | |
2. Push information to the channel | |
3. Set up a page that listens to the channel | |
4. Write javascript that displays the information that comes from the channel. | |
The code below in application.cfc sets up a web socket named meter1 | |
application.cfc | |
PublishMessage.cfm pushes the current amperage to the web socket we set up in application.cfc | |
publishMessage.cfm | |
Subscriber.cfm listens to the channel meter1 and puts it into javascript object we named messageHandler. Anything pushed down the tube in publishmessage.cfm is going to show up on subscriber.cfm (without any page refreshing mumbo jumbo) | |
Subscriber.cfm | |
Once I saw the data update all by itself, the web sockets made perfect sense. It is really one of those things you have to watch in action to "get" You can see it here: <a href="http://services.cfmumbojumbo.com/ampmeter/subscriber.cfm">http://services.cfmumbojumbo.com/ampmeter/subscriber.cfm</a> | |
Finally, I wanted to make the data pretty, so I found RGraph which has a thermometer chart that uses HTML5 Canvas: | |
index.cfm | |
Mocked up demo: <a href="http://services.cfmumbojumbo.com/ampmeter/">http://services.cfmumbojumbo.com/ampmeter/</a> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- cfwebsocket subscribes to the websocket named meter1. Meter1 was created in application.cfc and messages | |
are being pushed to it on the publishmessage.cfm page. Anything pushed to the socket will be available | |
via a javascript object referenced in this case as messageHandler --> | |
<cfwebsocket name="myWS" onmessage="messageHandler" subscribeto="meter1" > | |
<!DOCTYPE html > | |
<html> | |
<head> | |
<link rel="stylesheet" href="./RGraph/demos/demos.css" type="text/css" media="screen" /> | |
<script src="./RGraph/libraries/RGraph.common.core.js" ></script> | |
<script src="./RGraph/libraries/RGraph.common.dynamic.js" ></script> | |
<script src="./RGraph/libraries/RGraph.common.tooltips.js" ></script> | |
<script src="./RGraph/libraries/RGraph.thermometer.js" ></script> | |
<!--[if lt IE 9]><script src="./RGraph/excanvas/excanvas.js"></script><![endif]--> | |
<title>Amps</title> | |
</head> | |
<body> | |
<center> | |
<h1>Amp load</h1> | |
<script type="text/JavaScript"> | |
function messageHandler(messageobj) | |
{ | |
//Converting the JS object to a string and display in "myDiv" | |
var message = ColdFusion.JSON.encode(messageobj); | |
var txt=document.getElementById("myDiv"); | |
//txt.innerHTML +=message + "<br>" ; | |
var amps = messageobj.data; | |
var color = getTempColor(amps); | |
var HostingServerRoom = new RGraph.Thermometer('cvs', 0,75,amps); | |
HostingServerRoom.Set('chart.colors', [color]); | |
HostingServerRoom.Set('chart.scale.decimals', 2); | |
HostingServerRoom.Draw(); | |
} | |
//function to control the color of the graph | |
function getTempColor(amp) | |
{ | |
var color = "red"; | |
if (amp >= 70) | |
{color="red"; | |
return color;} | |
else if (amp >=50) | |
{color="orange"; | |
return color;} | |
else if (amp >=30) | |
{color="green"; | |
return color;} | |
else if (amp >=0) | |
{color="blue"; | |
return color;} | |
return color; | |
} | |
</script> | |
<div id="myDiv"><!-- for debug output --></div> | |
<canvas id="cvs" width="100" height="400">[No canvas support]</canvas> | |
</center> | |
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfcomponent hint="fake component set up to simulate calls to amp meter"> | |
<cffunction name="getLiveData"> | |
<cfreturn randrange(5,70)> | |
</cffunction> | |
</cfcomponent> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Call my "fake api" which returns a random number of amps. I set up a scheduled job | |
that calls this page every 5 seconds --> | |
<cfset amps = createobject("component","LiveDataApi").getLiveData()> | |
<!-- Push the number to the web socket named Meter1 --> | |
<cfset wspublish("Meter1", amps)> | |
<!--- Below is unneeded output so you can see the data ---> | |
<cfoutput>#amps#</cfoutput> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfwebsocket name="myWS" onmessage="messageHandler" subscribeto="meter1" > | |
<!DOCTYPE html > | |
<html> | |
<head> | |
<title>Amps</title> | |
</head> | |
<body> | |
<center> | |
<h1>Amp load</h1> | |
<script type="text/JavaScript"> | |
function messageHandler(messageobj) | |
{ | |
//Converting the JS object to a string and display in "myDiv" | |
var message = ColdFusion.JSON.encode(messageobj); | |
var txt=document.getElementById("myDiv"); | |
txt.innerHTML +=message + "<br>" ; | |
var amps = messageobj.data; | |
} | |
</script> | |
<div id="myDiv"></div> | |
</center> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment