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;