`
biyeah
  • 浏览: 203282 次
  • 来自: ...
社区版块
存档分类
最新评论

nowjs和nodejs实现服务器端与客户端实时数据传输的例子

阅读更多
参考:http://www.bennadel.com/blog/2171-Realtime-Messaging-And-Synchronization-With-NowJS-And-Node-js.htm

    先说例子实现的功能。网页上有一图片,图片可以拖动。用浏览器打开多个同一网页,当图片移动时,其它页面的图片会同步移动。例子也展示了用jQuery实现图片的拖动。
测试环境window7,nodejs v0.6.5 分别用ie,firefox,chrome打开http://127.0.0.1:8080/client.html,所有该网页上的图片会同步移动。贴上代码。
server.js端:
需要用sock.io和nowjs第三包,推荐用npm方式安装。nowjs包在window的安装可参考:
http://blog.nowjs.com/running-nowjs-natively-on-windows
// Include the necessary modules.
var sys = require("util");
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) {//syncPosition()在这里定义,在客户端调用

// 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.
        this.now.updatePosition(position);//updatePosition()为客户端定义的方法,在这里可调用,用this修饰now。

    };

})();


// ---------------------------------------------------------- //
// ---------------------------------------------------------- //


// 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");


我把重要的东西摘录下来:
引用
Once the core HTTP server is configured and the NowJS module is initialized, we are given access to the "everyone" object. This everyone object then provides us with access to the server-side "now" scope. This "now" scope is shared between the server and every one of the clients. Anything added to or removed from the server-side "now" scope is also added to or removed from every client currently (or eventually) connected to the server.

This is true for both variables and functions! Notice that my server-side Node.js code defines two methods: syncPosition() and filterUpdateBroadcast(). By defining them in the "everyone.now" scope, I am making them available to both the server and to every single one of the connected clients.

But what about that, "everyone.now.updatePosition()", function? Where did that come from? Ah-ha! Here's the real, "there is no spoon" mind-screw - that function is defined on the client (which we'll see in a minute). And, since it's defined in the client's "now" scope, the server-side Javascript can then invoke it as if there were no separation between the server and client contexts.


client.html
<!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.4.2/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="myhead"
        src="./myhead.gif"
        width="100"
        height="100"
        alt="It's my head, do you like it?"
        />


<!-- Configure the client-side script. -->
<script type="text/javascript">

    // Get a reference to the target draggable.
    var myhead = $("#myhead");

    // 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.
    myhead.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 - myhead.position().left),
                    y:(event.pageY - myhead.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.
                            myhead.css(newPosition);

// Announce the updated position so that we
// can sync accross all clients with NowJS.
                            now.syncPosition(newPosition);//syncPosition()是在服务器端定义的方法,可在客户端调用。
                        }
                );
            }
    );


    // On mouse-up, turn off draggability.
    myhead.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){
//updatePosition()这个方法在客户端定义,可在服务器端调用
// 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.
        myhead.css(newPosition);

    };

</script>
</body>
</html>


引用
When the user moves the image on the client, the client broadcasts the new position using the "now.syncPosition()" function. This function, which was defined on the server, then pushes the updated position down to all the other clients using the "now.updatePosition()" function, which was defined on the client.

Even after coding this myself, it's still somewhat confusing; so, let's look at a quick rundown of the various functions to see where they were defined and where they were invoked:

syncPosition()
  • Defined: Server-side
  • Invoked: Client-side

filterUpdateBroadcast()
  • Defined: Server-side
  • Invoked: Server-side

updatePosition()
  • Defined: Client-side
  • Invoked: Server-side
分享到:
评论

相关推荐

    three7-html5:HTML5Canvas 落块游戏的灵感来自 YuYu Hakusho 动漫中的类似游戏

    如果一个块落下的值加上水平或垂直块序列的值等于 7,那么下落的块和该块序列将消失。 这些方块上方的任何方块都会掉落并且可能会触发连击。 7 的块本身不会清除,因为总和中必须涉及 2 个或更多块。 这个规则只有...

    vimrc-builder:ⓥvimrc文件生成器

    通过Web应用程序轻松构建vimrc为什么构建vimrc文件应该并不困难。 毕竟,您要配置的代码编辑器是1991年发明的。 没关系,您的经验水平是不变的,总有新的方法可以改变vim的经验,但是由于提示分散在Internet上,因此...

    java+sql server项目之科帮网计算机配件报价系统源代码.zip

    sql server+java项目之科帮网计算机配件报价系统源代码

    【java毕业设计】智慧社区老人健康监测门户.zip

    有java环境就可以运行起来 ,zip里包含源码+论文+PPT, 系统设计与功能: 文档详细描述了系统的后台管理功能,包括系统管理模块、新闻资讯管理模块、公告管理模块、社区影院管理模块、会员上传下载管理模块以及留言管理模块。 系统管理模块:允许管理员重新设置密码,记录登录日志,确保系统安全。 新闻资讯管理模块:实现新闻资讯的添加、删除、修改,确保主页新闻部分始终显示最新的文章。 公告管理模块:类似于新闻资讯管理,但专注于主页公告的后台管理。 社区影院管理模块:管理所有视频的添加、删除、修改,包括影片名、导演、主演、片长等信息。 会员上传下载管理模块:审核与删除会员上传的文件。 留言管理模块:回复与删除所有留言,确保系统内的留言得到及时处理。 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上

    【java毕业设计】智慧社区心理咨询平台(源代码+论文+PPT模板).zip

    zip里包含源码+论文+PPT,有java环境就可以运行起来 ,功能说明: 文档开篇阐述了随着计算机技术、通信技术和网络技术的快速发展,智慧社区门户网站的建设成为了可能,并被视为21世纪信息产业的主要发展方向之一 强调了网络信息管理技术、数字化处理技术和数字式信息资源建设在国际竞争中的重要性。 指出了智慧社区门户网站系统的编程语言为Java,数据库为MYSQL,并实现了新闻资讯、社区共享、在线影院等功能。 系统设计与功能: 文档详细描述了系统的后台管理功能,包括系统管理模块、新闻资讯管理模块、公告管理模块、社区影院管理模块、会员上传下载管理模块以及留言管理模块。 系统管理模块:允许管理员重新设置密码,记录登录日志,确保系统安全。 新闻资讯管理模块:实现新闻资讯的添加、删除、修改,确保主页新闻部分始终显示最新的文章。 公告管理模块:类似于新闻资讯管理,但专注于主页公告的后台管理。 社区影院管理模块:管理所有视频的添加、删除、修改,包括影片名、导演、主演、片长等信息。 会员上传下载管理模块:审核与删除会员上传的文件。 留言管理模块:回复与删除所有留言,确保系统内的留言得到及时处理。

    计算机系统基础实验LinkLab实验及解答:深入理解ELF文件与链接过程

    内容概要:本文档详细介绍了LinkLab实验的五个阶段,涵盖了ELF文件的组成、符号表的理解、代码节与重定位位置的修改等内容。每个阶段都有具体的实验要求和步骤,帮助学生理解链接的基本概念和链接过程中涉及的各项技术细节。 适合人群:计算机科学专业的本科生,特别是正在修读《计算机系统基础》课程的学生。 使用场景及目标:① 通过实际操作加深对链接过程和ELF文件的理解;② 掌握使用readelf、objdump和hexedit等工具的技巧;③ 实现特定输出以验证实验结果。 阅读建议:实验过程中的每个阶段都有明确的目标和提示,学生应按照步骤逐步操作,并结合反汇编代码和二进制编辑工具进行实践。在完成每个阶段的实验后,应及时记录实验结果和遇到的问题,以便于总结和反思。

    基于关键词的历时百度搜索指数自动采集资料齐全+详细文档+高分项目+源码.zip

    【资源说明】 基于关键词的历时百度搜索指数自动采集资料齐全+详细文档+高分项目+源码.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    用C语言写出一个简单的圣诞树,让你的朋友们体验一下程序员的浪漫,点开即令哦!

    第一次发文的小白,解释的不好,各位大佬勿怪哦

    免费下载:Hilma af Klint a Biography (Julia Voss)_tFy2T.zip

    免费下载:Hilma af Klint a Biography (Julia Voss)_tFy2T.zip

    屏幕截图 2024-12-21 172527.png

    屏幕截图 2024-12-21 172527

    2024级涉外护理7班马天爱劳动实践总结1.docx

    2024级涉外护理7班马天爱劳动实践总结1.docx

    IndexOutOfBoundsException(解决方案).md

    IndexOutOfBoundsException(解决方案)

    【java毕业设计】智慧社区垃圾分类门户.zip

    有java环境就可以运行起来 ,zip里包含源码+论文+PPT, 系统设计与功能: 文档详细描述了系统的后台管理功能,包括系统管理模块、新闻资讯管理模块、公告管理模块、社区影院管理模块、会员上传下载管理模块以及留言管理模块。 系统管理模块:允许管理员重新设置密码,记录登录日志,确保系统安全。 新闻资讯管理模块:实现新闻资讯的添加、删除、修改,确保主页新闻部分始终显示最新的文章。 公告管理模块:类似于新闻资讯管理,但专注于主页公告的后台管理。 社区影院管理模块:管理所有视频的添加、删除、修改,包括影片名、导演、主演、片长等信息。 会员上传下载管理模块:审核与删除会员上传的文件。 留言管理模块:回复与删除所有留言,确保系统内的留言得到及时处理。 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上

    【java毕业设计】智慧社区网端门户(源代码+论文+PPT模板).zip

    有java环境就可以运行起来 ,zip里包含源码+论文+PPT, 系统设计与功能: 文档详细描述了系统的后台管理功能,包括系统管理模块、新闻资讯管理模块、公告管理模块、社区影院管理模块、会员上传下载管理模块以及留言管理模块。 系统管理模块:允许管理员重新设置密码,记录登录日志,确保系统安全。 新闻资讯管理模块:实现新闻资讯的添加、删除、修改,确保主页新闻部分始终显示最新的文章。 公告管理模块:类似于新闻资讯管理,但专注于主页公告的后台管理。 社区影院管理模块:管理所有视频的添加、删除、修改,包括影片名、导演、主演、片长等信息。 会员上传下载管理模块:审核与删除会员上传的文件。 留言管理模块:回复与删除所有留言,确保系统内的留言得到及时处理。 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上

    【java毕业设计】智慧社区智慧养老照护系统(源代码+论文+PPT模板).zip

    zip里包含源码+论文+PPT,有java环境就可以运行起来 ,功能说明: 文档开篇阐述了随着计算机技术、通信技术和网络技术的快速发展,智慧社区门户网站的建设成为了可能,并被视为21世纪信息产业的主要发展方向之一 强调了网络信息管理技术、数字化处理技术和数字式信息资源建设在国际竞争中的重要性。 指出了智慧社区门户网站系统的编程语言为Java,数据库为MYSQL,并实现了新闻资讯、社区共享、在线影院等功能。 系统设计与功能: 文档详细描述了系统的后台管理功能,包括系统管理模块、新闻资讯管理模块、公告管理模块、社区影院管理模块、会员上传下载管理模块以及留言管理模块。 系统管理模块:允许管理员重新设置密码,记录登录日志,确保系统安全。 新闻资讯管理模块:实现新闻资讯的添加、删除、修改,确保主页新闻部分始终显示最新的文章。 公告管理模块:类似于新闻资讯管理,但专注于主页公告的后台管理。 社区影院管理模块:管理所有视频的添加、删除、修改,包括影片名、导演、主演、片长等信息。 会员上传下载管理模块:审核与删除会员上传的文件。 留言管理模块:回复与删除所有留言,确保系统内的留言得到及时处理。

    Delphi 12 控件之DevExpressVCLProductDemos-24.2.3.exe

    DevExpressVCLProductDemos-24.2.3.exe

    计算机语言学中并查集数据结构的C++实现

    欢迎下载

    【java毕业设计】智慧社区养老服务平台.zip

    有java环境就可以运行起来 ,zip里包含源码+论文+PPT, 系统设计与功能: 文档详细描述了系统的后台管理功能,包括系统管理模块、新闻资讯管理模块、公告管理模块、社区影院管理模块、会员上传下载管理模块以及留言管理模块。 系统管理模块:允许管理员重新设置密码,记录登录日志,确保系统安全。 新闻资讯管理模块:实现新闻资讯的添加、删除、修改,确保主页新闻部分始终显示最新的文章。 公告管理模块:类似于新闻资讯管理,但专注于主页公告的后台管理。 社区影院管理模块:管理所有视频的添加、删除、修改,包括影片名、导演、主演、片长等信息。 会员上传下载管理模块:审核与删除会员上传的文件。 留言管理模块:回复与删除所有留言,确保系统内的留言得到及时处理。 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上

    小米15pro工程固件 可以用于修改参数 修复tee损坏 修复底层分区 会用的下载

    资源描述: 机型代码:haotian 1-----工程固件可以用于修改参数 开启diag端口。可以用于修复tee损坏以及修复底层分区。 2-----此固件是完整官方。不是第三方打包。请知悉 3-----此固件可以解锁bl后fast模式刷写。也可以底层深刷。也可以编程器写入 4-----请会用此固件 了解工程固件常识以及会用的朋友下载。 5-----个别高版本深刷需要授权才可以刷入。需要自己会刷写。 6------资源有可复制性。下载后不支持退。请考虑清楚在下载哦 工程资源常识可以参考博文:https://blog.csdn.net/u011283906/article/details/141815378 了解基本

    JSP论文格式化系统_——后台模块的设计与实现(源代码+论文)(2024gk).7z

    1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于计算机科学与技术等相关专业,更为适合;

Global site tag (gtag.js) - Google Analytics