node.js虽然也是单线程模型,但是它的异步调用使他的性能在i/o上比php高出很多。但是php确实很方便,在c层面做了那么多开发web需要的class/function。而node.js就算要获取post的数据也要自己去读入流然后分割字符串(虽然在node.js层面也有封装)。如果php接收到一些需要读写磁盘的操作,比如上传图片可以通过tcp/udp交给node.js处理.
tcp传输
node.js tcp服务端
var net = require("net");
var host = '127.0.0.1';
var port = '9999';
var Event = require("./Event");
net.createServer(function(sock){
console.log("connected:"+sock.remoteAddress+":"+sock.remotePort);
sock.on('data', function(data){
console.log("data:"+sock.remoteAddress+':'+data);
sock.write("success"+"\r\n");
var json = JSON.parse(data);
var e = new Event();
console.log(json);
e.trigger(json.type, json);
});
sock.on('close', function(data){
console.log("closed:"+sock.remoteAddress+':'+sock.remotePort);
});
sock.on('error', function(err){
console.log(err);
})
}).listen(port, host);
console.log('Server listening on '+host+':'+port);
php tcp客户端(php使用base64把图片编码成字符串传输)
<?php
$fp = stream_socket_client("tcp://127.0.0.1:9999", $errno, $errstr, 30);
if(!$fp){
echo $errstr. ' ' .$errno."\n";
}else{
$file = "a.png";
$img = base64_encode( file_get_contents($file) );
$arr = pathinfo($file);
$data = [
'type' => 'img',
'path' => date('Y/m/d/'),
'name' => date('His').'.'.$arr['extension'],
'imgstr' => $img,
];
fwrite($fp, json_encode( $data ));
echo fgets($fp);
fclose($fp);
exit();
}
udp传输
如果在网络情况比较好的情况下,比如一个内网中,用udp效率会更高:
node.js udp服务端
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("error", function(msg, remoteInfo){
console.log("server error:\n"+err.stack);
server.close();
});
server.on("message", function(data, remoteInfo){
//console.log("data:"+data);
var json = JSON.parse(data);
var event = require("./Event");
var e = new event();
var msg = new Buffer('success');
server.send(msg, 0, msg.length, remoteInfo.port,remoteInfo.address);
e.trigger(json.type, json);
});
server.on("listening", function(){
var address = server.address();
console.log("server listening "+address.address+':'+address.port);
});
server.bind("9999");
php udp客户端
<?php
$fp = stream_socket_client("udp://127.0.0.1:9999", $errno, $errstr);
if( !$fp ){
exit("ERROR:".$errno.' '.$errstr);
}
$file = "a.png";
$img = base64_encode( file_get_contents($file) );
$arr = pathinfo($file);
$data = [
'type' => 'img',
'path' => 'udp/'.date('Y/m/d/'),
'name' => date('His').'.'.$arr['extension'],
'imgstr' => $img,
];
fwrite($fp, json_encode( $data ));
$result = fread($fp, 1024);
fclose($fp);
echo $result;
node.js Event对象
var util = require("util");
var events = require("events");
function Event()
{
events.EventEmitter.call(this);
this.on('img', function(data){
var img = require("./libs/img");
var i = new img(data.imgstr);
i.save(data.path, data.name);
});
}
Event.prototype.trigger = function(type, data){
this.emit(type, data);
}
util.inherits(Event, events.EventEmitter);
module.exports = Event;
node.js Img上传对象
'use strict';
var fs = require("fs");
class img{
constructor(data){
this.data = new Buffer(data, 'base64');
}
save(path, name){
if( !fs.existsSync(path) ){
this.mkdir(path, '0777');
}
fs.writeFileSync(path+name, this.data);
}
mkdir(dirname, mode){
var path = require("path");
if(fs.existsSync(dirname)){
return true;
}else{
if(this.mkdir(path.dirname(dirname), mode)){
fs.mkdirSync(dirname, mode);
return true;
}
}
}
}
module.exports = img;

