[ Content | Sidebar ]

Archives for web dev

node.js中mysql-native的掉线重联

由于受一篇性能测试的文章的影响,选择了mysql-native作为node的mysql客户端,由于没有自动重联的功能,长时间运行后就会掉线,所以加了一段判断掉线的代码:

var Mysql = null;
 
function MysqlConnect() { //... }
 
MysqlSafeQuery = function(sql) {
    if (!Mysql || !Mysql.connection.writable) {
        MysqlConnect();
    }
 
    return Mysql.query(sql);
}
Copy Code 

JsonStream.js

JsonStream.js是一个用于node.js的双向通信协议实现,它使用json作为数据包格式,可以用于socket,也可以用于http长连接,同时自带了简单的rpc实现。这段代码现在被用于一个对实时性要求比较高的小项目,本来打算用python+twisted做,但是后来临时决定尝试一下node.js,下面举例说明用法:

第一个例子,最简单的应用,基于socket通信,发送和接受json数据
StreamServer.js

var Net = require('net');
var JsonStream = require('./JsonStream.js');
 
//创建一个普通的socket server
var server = Net.createServer(function(c) {
    //当有客户端连接后,socket连接之上创建一个JsonStream
    var stream = new JsonStream.Stream(c);
 
    //监听客户端发来的json数据
    stream.on('json', function(json) {
        console.log('receiv json from client:');
        console.log(json);
    });
 
    //没三秒钟向客户端发送一个json数据
    setInterval(function(){
        stream.write({
            data:'hello client',
            time:new Date()
        });
    }, 3000);
});
 
server.listen(7777);
Copy Code 

第二个例子,基于socket,两端互相rpc调用
RpcServer.js

var Net = require('net');
var JsonStream = require('./JsonStream.js');
 
//定义服务端支持的Rpc接口
var ServerApi = {
 
    //这是一个普通的接口,直接返回数据
    hello:function(name) {
        console.log('client call hello');
        return 'hello ' + name;
    },
 
    //这是一个异步返回的方法
    //这里的SimpleDeferred的确不是一个全功能的Deffered
    //只能用在异步返回的情况
 
    helloAfter:function(name, delay) {
        console.log('client call helloAfter');
        var defer = new JsonStream.SimpleDeferred();
        setTimeout(function(){
            defer.done('hello ' + name + ' after ' + delay + 's');
        }, delay * 1000);
        return defer;
    }
};
 
var server = Net.createServer(function(c) {
    var stream = new JsonStream.Stream(c);
    stream.delegate = ServerApi;
 
    //每3秒调用一次客户端的say方法
    setInterval(function(){
        stream.rpcCall('say', ['你好!']);
    }, 3000);
});
 
server.listen(7777);
Copy Code 

RpcClient.js中的调用部分

stream.rpcCall('hello', ['client a'], function(res) {
     console.log(res);
});
 
stream.rpcCall('helloAfter', ['client a', 1], function(res) {
     console.log(res);
});
Copy Code 

第三个例子,用于长连接的http双向通信,由于客户端的代码和现有的业务框架结合比较紧密,暂不提供,只示意一下Server端的代码,基本使用方法和socket的类似

var Http = require('http');
var JsonStream = require('./JsonStream.js');
 
//Rpc接口定义
var ServerApi = {
};
 
//创建一个http server
var HttpServer = Http.createServer(function(request, response){
    //让JsonStream处理所有http请求
    JsonStream.HttpStream.acceptRequest(request, response);
});
 
JsonStream.HttpStream.events.on('new', function(stream, request) {
    console.log('new http stream !!!!!');
    stream.delegate = ServerApi;
    //发送json到浏览器端
    stream.write({
        data:'hello browser'
    });
});
 
HttpServer.listen(80);
//长连接的最大时长设为30秒
JsonStream.HttpStream.checkTimeOut(30);
Copy Code 

更多细节详见源码:),经过一段时间的运行,代码已趋于稳定,可以通过svn获取代码和示例,请容忍我的不爱写注释,呵呵~:


http://code-of-emptyhua.googlecode.com/svn/trunk/nodejs/jsonstream

comet的两个小问题

最近做了一个webim的项目,使用长连接做push,在chrome和ie下有些小问题

1. chrome的左下角下一直显示等待push.xx.com的响应

解决方法:接到请求立刻返回http头就可以了,不等到有了推送再返回http头

2.ie下对于每个域名同一时刻最多只能有两个并发请求,如果开多个窗口(这个限制不是针对单个窗口的),有的请求便会被阻塞。

解决方法:对每个窗口使用不同的请求域名
使用三级泛域名配置起来最简单,例如:123.push.xx.com.但是JS里涉及到跨域的问题,所以还是要使用push-123.xx.com这样的二级域名。查了下bind9的手册可以这么搞

;示例
$GENERATE 0-100000 push-$ IN A xx.xx.xx.xx
Copy Code 

这样ie下JS可以用时间戳或随机数决定一个domain去请求,不会产生阻塞

接上一篇

有必要给blogo2加个追加功能。。可以直接把mail追加到最新一篇blog的后面
————————
gcc之预处理js和as,下面的makefile主要处理flash的两个版本,SSL版本要比普通版本大150K。。感谢gcc

FLAGS="-DDEBUG"
 
define make-all
	gcc $(FLAGS) $1 -E -x c src/swfsocket.js -o $2/swfsocket.js 
	gcc $(FLAGS) $1 -E -x c src/swf/SwfSocket.rel.as -o src/swf/SwfSocket.as
	sed -i "/^#/d" $2/swfsocket.js
	sed -i "/^#/d" src/swf/SwfSocket.as
	cd src/swf; \
	mxmlc -static-link-runtime-shared-libraries -output=./SwfSocket.swf SwfSocketMain.as
	mv src/swf/SwfSocket.swf $2 
endef
 
main:
	$(call make-all,,bin)
	$(call make-all,-DSSL,bin_ssl)
Copy Code 

———–
post by gmail~

gcc预处理用于其他语言也很好用啊

header.js

function SSL_socket()
{
    alert('SSL');
}
 
function socket()
{
    alert('normal');
}
Copy Code 

main.js

#include "header.js"
#ifdef _SSL
var socket = new SSL_socket();
#else
var socket = new socket();
#endif
Copy Code 
gcc -E -x c main.js
# 1 "main.js"
# 1 ""
# 1 ""
# 1 "main.js"
# 1 "header.js" 1
function SSL_socket()
{
    alert('SSL');
}

function socket()
{
    alert('normal');
}
# 2 "main.js" 2

var socket = new socket();
gcc -E -x c -D_SSL main.js
# 1 "main.js"
# 1 ""
# 1 ""
# 1 "main.js"
# 1 "header.js" 1
function SSL_socket()
{
    alert('SSL');
}

function socket()
{
    alert('normal');
}
# 2 "main.js" 2

var socket = new SSL_socket();

———–
post by gmail~