Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
2 changed files
with
295 additions
and
15 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,170 @@ | ||
var httpServer = require('http').createServer(function(req, response){ /* Serve your static files */ }) | ||
httpServer.listen(8080); | ||
|
||
var nowjs = require("now"); | ||
var everyone = nowjs.initialize(httpServer); | ||
|
||
everyone.now.logStuff = function(msg){ | ||
console.log(msg); | ||
} | ||
var sys = require( "sys" ); | ||
var http = require( "http" ); | ||
var url = require( "url" ); | ||
var path = require( "path" ); | ||
var fileSystem = require( "fs" ); | ||
|
||
|
||
// ---------------------------------------------------------- // | ||
// ---------------------------------------------------------- // | ||
|
||
|
||
// Create an instance of the HTTP server. | ||
var server = http.createServer( | ||
function( request, response ){ | ||
|
||
// Get the requested "script_name". This is the part of the | ||
// path after the server_name. | ||
var scriptName = request.url; | ||
|
||
// Convert the script name (expand-path) to a physical file | ||
// on the local file system. | ||
var requestdFilePath = path.join( process.cwd(), scriptName ); | ||
|
||
// Read in the requested file. Remember, since all File I/O | ||
// (input and output) is asynchronous in Node.js, we need to | ||
// ask for the file to be read and then provide a callback | ||
// for when that file data is available. | ||
// | ||
// NOTE: You can check to see if the file exists *before* you | ||
// try to read it; but for our demo purposes, I don't see an | ||
// immediate benefit since the readFile() method provides an | ||
// error object. | ||
fileSystem.readFile( | ||
requestdFilePath, | ||
"binary", | ||
function( error, fileBinary ){ | ||
|
||
// Check to see if there was a problem reading the | ||
// file. If so, we'll **assume** it is a 404 error. | ||
if (error){ | ||
|
||
// Send the file not found header. | ||
response.writeHead( 404 ); | ||
|
||
// Close the response. | ||
response.end(); | ||
|
||
// Return out of this guard statement. | ||
return; | ||
|
||
} | ||
|
||
// If we made it this far then the file was read in | ||
// without a problem. Set a 200 status response. | ||
response.writeHead( 200 ); | ||
|
||
// Serve up the file binary data. When doing this, we | ||
// have to set the encoding as binary (it defaults to | ||
// UTF-8). | ||
response.write( fileBinary, "binary" ); | ||
|
||
// End the response. | ||
response.end(); | ||
|
||
} | ||
); | ||
|
||
} | ||
); | ||
|
||
// Point the server to listen to the given port for incoming | ||
// requests. | ||
server.listen( 8080 ); | ||
|
||
|
||
// ---------------------------------------------------------- // | ||
// ---------------------------------------------------------- // | ||
|
||
|
||
// Create a local memory space for further now-configuration. | ||
(function(){ | ||
|
||
// Now that we have our HTTP server initialized, let's configure | ||
// our NowJS connector. | ||
var nowjs = require( "now" ); | ||
|
||
|
||
// After we have set up our HTTP server to serve up "Static" | ||
// files, we pass it off to the NowJS connector to have it | ||
// augment the server object. This will prepare it to serve up | ||
// the NowJS client module (including the appropriate port | ||
// number and server name) and basically wire everything together | ||
// for us. | ||
// | ||
// Everyone contains an object called "now" (ie. everyone.now) - | ||
// this allows variables and functions to be shared between the | ||
// server and the client. | ||
var everyone = nowjs.initialize( server ); | ||
|
||
|
||
// Create primary key to keep track of all the clients that | ||
// connect. Each one will be assigned a unique ID. | ||
var primaryKey = 0; | ||
|
||
|
||
// When a client has connected, assign it a UUID. In the | ||
// context of this callback, "this" refers to the specific client | ||
// that is communicating with the server. | ||
// | ||
// NOTE: This "uuid" value is NOT synced to the client; however, | ||
// when the client connects to the server, this UUID will be | ||
// available in the calling context. | ||
everyone.connected( | ||
function(){ | ||
this.now.uuid = ++primaryKey; | ||
} | ||
); | ||
|
||
|
||
// Add a broadcast function to *every* client that they can call | ||
// when they want to sync the position of the draggable target. | ||
// In the context of this callback, "this" refers to the | ||
// specific client that is communicating with the server. | ||
everyone.now.syncPosition = function( position ){ | ||
|
||
// Now that we have the new position, we want to broadcast | ||
// this back to every client except the one that sent it in | ||
// the first place! As such, we want to perform a server-side | ||
// filtering of the clients. To do this, we will use a filter | ||
// method which filters on the UUID we assigned at connection | ||
// time. | ||
everyone.now.filterUpdateBroadcast( this.now.uuid, position ); | ||
|
||
}; | ||
|
||
|
||
// We want the "update" messages to go to every client except | ||
// the one that announced it (as it is taking care of that on | ||
// its own site). As such, we need a way to filter our update | ||
// broadcasts. By defining this filter method on the server, it | ||
// allows us to cut down on some server-client communication. | ||
everyone.now.filterUpdateBroadcast = function( masterUUID, position ){ | ||
|
||
// Make sure this client is NOT the same client as the one | ||
// that sent the original position broadcast. | ||
if (this.now.uuid == masterUUID){ | ||
|
||
// Return out of guard statement - we don't want to | ||
// send an update message back to the sender. | ||
return; | ||
|
||
} | ||
|
||
// If we've made it this far, then this client is a slave | ||
// client, not a master client. | ||
everyone.now.updatePosition( position ); | ||
|
||
}; | ||
|
||
})(); | ||
|
||
|
||
// ---------------------------------------------------------- // | ||
// ---------------------------------------------------------- // | ||
|
||
|
||
// Write debugging information to the console to indicate that | ||
// the server has been configured and is up and running. | ||
sys.puts( "Server is running on 8080" ); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,127 @@ | ||
<script type="text/javascript" src="http://localhost:8080/nowjs/now.js"></script> | ||
|
||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>NowJS And Node.js Realtime Communication</title> | ||
|
||
<style type="text/css"> | ||
|
||
html, | ||
body { | ||
height: 100% ; | ||
overflow: hidden ; | ||
width: 100% ; | ||
} | ||
|
||
img { | ||
left: 9px ; | ||
position: absolute ; | ||
top: 70px ; | ||
} | ||
|
||
</style> | ||
|
||
<!-- We have this file stored explicitly. --> | ||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"/></script> | ||
|
||
<!-- | ||
The NowJS HTTP augmentation will take care of routing | ||
this - we don't actually have this physical file stored | ||
at this file path. | ||
--> | ||
<script type="text/javascript" src="/nowjs/now.js"></script> | ||
</head> | ||
<body> | ||
|
||
<h1> | ||
NowJS And Node.js Realtime Communication | ||
</h1> | ||
|
||
<!-- | ||
This will be draggable. When this image drags, we are | ||
going to sync the position of it across browsers. | ||
--> | ||
<img | ||
id="olivia" | ||
src="./olivia_williams.jpg" | ||
width="100" | ||
height="100" | ||
alt="The very gorgeous Olivia Williams." | ||
/> | ||
|
||
|
||
<!-- Configure the client-side script. --> | ||
<script type="text/javascript"> | ||
now.ready(function(){ | ||
// "Hello World!" will print on server | ||
now.logStuff("Hello World!"); | ||
}); | ||
</script> | ||
|
||
// Get a reference to the target draggable. | ||
var olivia = $( "#olivia" ); | ||
|
||
// Get a reference to the body - this is the element on which | ||
// we'll be tracking mouse movement once the draggable | ||
// tracking has been turned on. | ||
var body = $( "body" ); | ||
|
||
|
||
// On mouse-down, turn on draggability. | ||
olivia.mousedown( | ||
function( event ){ | ||
// Prevent the default behavior. | ||
event.preventDefault(); | ||
|
||
// Get the current position of the mouse within the | ||
// bounds of the target. | ||
var localOffset = { | ||
x: (event.pageX - olivia.position().left), | ||
y: (event.pageY - olivia.position().top) | ||
}; | ||
|
||
// Start tracking the mouse movement on the body. | ||
// We're tracking on the body so that the mouse can | ||
// move faster than the tracking. | ||
body.mousemove( | ||
function( event ){ | ||
// Create a new position object. | ||
var newPosition = { | ||
left: (event.pageX - localOffset.x), | ||
top: (event.pageY - localOffset.y) | ||
}; | ||
|
||
// Update the target position locally. | ||
olivia.css( newPosition ); | ||
|
||
// Announce the updated position so that we | ||
// can sync accross all clients with NowJS. | ||
now.syncPosition( newPosition ); | ||
} | ||
); | ||
} | ||
); | ||
|
||
|
||
// On mouse-up, turn off draggability. | ||
olivia.mouseup( | ||
function( event ){ | ||
// Unbind the mousemove - no need to track movement | ||
// once the mouse has been lifted. | ||
body.unbind( "mousemove" ); | ||
} | ||
); | ||
|
||
|
||
// I allow the remove server to make a request to update the | ||
// position of the target. | ||
// | ||
// NOTE: By defining this function in the NOW scope, it gives | ||
// the server access to it as well. | ||
now.updatePosition = function( newPosition ){ | ||
|
||
// Check to see if this client is in master mode; if so, | ||
// we won't update the position as this client is | ||
// actively updating its own position. | ||
olivia.css( newPosition ); | ||
|
||
}; | ||
|
||
</script> | ||
|
||
</body> | ||
</html> |