APNs功能之Node.jsMysql应用总结

   这篇文档主要是总结Node.js和Mysql的学习心得体会。当然也可以看作是此前所写的消息推送服务的续篇。

简单描述下应用背景,我们的应用需要实现苹果的消息推送服务APNs,之前已经实现了iOS客户端配置和功能代码,也实现了推送通知的本地Provider功能代码,具体参考此前的系列总结。好比一个三角形,A点代表iOS移动设备端,B点代表苹果的消息推送服务器,C点代表应用开发者的本地服务器,现在A和B连接好了,B和C也连接好了,就差A和

B建立连接沟通。

这样一来,很明显就是要在本地搭建一个服务器了,可以处理A发送的请求;当然也少不了数据库,用来存储相关数据。

说到这里,不同技术背景的人会有不同的方案,在此我采用了Node.js+Mysql的解决方案。当然其他方案如ASN.NET、JSP、PHP加上SQLServer、Mysql、MongoDB等等就不谈论了。纯粹作为技术学习和新方案的尝试。

Node.js

作为这篇文档的重点内容,Node.js肯定是要优先总结的。

我这种刚学习Node.js的新手,就不敢把此文当做Node.js的入门资料了,只是简单介绍一下,然后直接根据应用需求实现代码。

Node.js实现了服务端Javascript,通过简单快捷的环境搭建,就可以实现一个运行Javascript的服务器。

1、  去官网下载最新的Node.js安装程序。说明一下,我是在Windows32位操作系统上安装,所以下载Windows对应安装程序即可。我的版本为:node-v0.10.24-x86。

2、  安装Node.js。

3、  在开始—>所有程序中,找到Node.js的命令行程序Node.js command prompt并运行

好了,至此,你已经可以开始编程了。就是这么简单快捷。

或许很多人还是很困惑,那在哪里写代码呢,命令行?

在此,我要说一下刚接触时候我的感受:我觉得很郁闷,不知道从何入手。

对于很多新手,大家需要的是把事情说明白一点,而不是玄乎。可以这样理解,Node.js就是一个服务器,用于搭载Javascript、CSS、Html等网页所可以有的一切。但是他本身不集成IDE。再具体点,他的出现,使我们可以不用熟悉的IIS、Apache、Tomcat来部署了,只需要运行Node.js,然后通过一句话“node xxx.js”,加载已经写好的Javascript,就一切OK了。是的,Javascript,那用你熟悉的任何方式和工具去书写吧。Notepad++是我选择的工具。

一定还有疑惑,没关系,我们先来看实例。

下列实例实现一个可以上传图片文件并预览的页面,还有一个向数据库插入一条数据的请求。

先看这个例子NodejsDemo的文件夹结构

说明:index.js是入口,server.js用于启动服务,router.js用于路由请求,requesHandlers.js用于处理路由后的对应请求,mysqlOperation.js用于处理数据库操作,mysqlDBHelper.js用于连接数据库并操作

接下就是具体代码部分了,太多语法我无法一下说清楚,在需要的地方,我会稍加说明,想了解更多,建议去官网查看API说明,毕竟是抛砖引玉哈。

Index.js的代码:

 var server = require("./server");

 var router = require("./router");

 var requestHandlers = require("./requestHandlers");

 var handle = {}

 handle["/"] = requestHandlers.start;

 handle["/start"] = requestHandlers.start;

 handle["/upload"] = requestHandlers.upload;

 handle["/show"] = requestHandlers.show;

 handle["/sendMyInfo"] = requestHandlers.sendMyInfo;

 server.start(router.route, handle);

说明:这是示例的入口,最后一句,调用server中的start方法,并传递两个参数,第一个是router中route函数,第二个是类似字典实例的handle。

      server.js的代码:

 var http = require('http');

 var url = require('url');

 function start(route, handle){

               function onRequest(req,res){

                        var pathname = url.parse(req.url).pathname;

                        console.log("Request for " + pathname + " received.");

                        route(handle, pathname, res,req);         

               }

               http.createServer(onRequest).listen(1337, 'Your IP');

               console.log('Server running at http://Your IP:1337/');

 }

 exports.start = start;

说明:与require(“./server”)调用同级目录js文件不同,require(‘http’)是生成一个http对象实例的方法。url.parse(string).pathname用于获取url字符串中路径名称。Your IP为本机的IP地址。http.createServer(function).listen(端口号,’IP’)用于通过一个方法创建一个服务,并在设置的iP和端口号监听。Exports.start=start为其他js对象调用本方法暴露接口。

route.js的代码

 function route(handle, pathname, res, req){

               console.log("About to route a request for " + pathname);

               if(typeof handle[pathname] === 'function'){

                        handle[pathname](res, req);

               }else{

                        console.log("No request handler found for " + pathname);

                        res.writeHead(404, {'Content-Type': 'text/plain'});

                        res.end('404 route not found');

               }

 }

 exports.route = route;

说明:路由请求,当请求未定义的路径时,则在response的head里面返回404错误。

requestHanlders.js的代码:

 var querystring = require ("querystring");

 var url = require('url');

 var fs = require("fs");

 var formidable = require("formidable");

 var util = require("util");

 var mysqlOperation = require("./mysqlOperation");

 var testPicPath = "/testPic/test.png";

 function start(res, req){

               console.log("Request handler 'start' was called.");

               var body = '<html>'+

                        '<head>'+

                        '<meta http-equiv="Content-Type" content="text/html; '+

                        'charset=UTF-8" />'+

                        '</head>'+

                        '<body>'+

                        '<form action="/upload" enctype="multipart/form-data" method="post">'+

                        '<input type="file" name="upload">'+

                        '<input type="submit" value="Upload file" />'+

                        '</form>'+

                        '</body>'+

                        '</html>';

               res.writeHead(200, {'Content-Type': 'text/html'});

               res.end(body);

 }

 function upload(res, req){

               console.log("Request handler 'upload' was called.");

               var form = new formidable.IncomingForm();

               console.log("about to parse");

               form.parse (req, function(error, fields, files) {

                        console.log("parsing done");

 /*                  res.writeHead(200,{"Content-type":"text/plain"});

                        res.write("received upload:\n\n");

                        res.write(util.inspect({fields:fields,files:files})); */

                        fs.rename(files.upload.path, '/testPic/' + files.upload.name, function(err){

                                  if(err) throw err;

                                  console.log("renamed complete");

                                  testPicPath =  "/testPic/" + files.upload.name;

                                  res.writeHead (200, {"Content-Type": "text/html"});

                                  res.write ("received image:<br/>");

                                  res.write ("<img src= '/show' />");

                                  res.end();

                        }); 

               });

 }

 function show(res, req) {

               console.log("Request handler 'show' was called.");

               fs.readFile (testPicPath, "binary", function(error, file) {

                        if(error) {

                                  res.writeHead (500, {"Content-Type": "text/plain"});

                                  res.write ("Image error: " + error + "\n");

                                  res.end();

                        } else {

                                  res.writeHead (200, {"Content-Type": "image/png"});

                                  res.write (file, "binary");

                                  res.end();

                        }

               });

 }

 function sendMyInfo(res,req){

               console.log("Request handler 'sendMyInfo' was called.");

               var urlstring = url.parse(req.url).query;

               var user = {

                        name : querystring.parse(urlstring).name,

                        country : querystring.parse(urlstring).country,

                        city : querystring.parse(urlstring).city,

                        street : querystring.parse(urlstring).street

               };

               if(use.name == undefined || user.country == undefined

 || user.city == undefined || user.street == undefined){

                        res.writeHead (500, {"Content-Type": "text/plain"});

                        res.write ("error: paras undefined.");

                        res.end();

                        console.log("error: paras undefined.");

                        return;

               }

               console.log(user);

               mysqlOperation.storeUserInfo(user,res);

 }

 exports.start = start;

 exports.upload = upload;

 exports.show = show;

 exports.sendMyInfo = sendMyInfo;

说明:这个js文件是处理请求的主要地方,当路由路径后,会找到相应方法。

这里需要重点说一下start方法。在返回response内容时候,直接采用字符串方式表达body,当然这是不好的习惯,那么在疑惑页面的朋友就可以在这里找到答案了。Node.js有负责加载页面的API,还有类似于模板页的结构,以前熟悉的方式依然可以使用。至于其他方法,相信你会看明白的。还有,为什么错误返回码总是500呢,因为是我随意设置的。。。

至此,一个简单的Node.js的demo就完成了,噢,忘了方法sendMyInfo,那是等下继续要说的。马上运行Node.js的命令行程序,然后在“路径>”后面输入“node index.js路径”,回车就可以看到Server running的输出提示了。在浏览器里面访问“Your IP:Your port/”。

多说一句,index.js的全路径是绝对无误的,当index.js处于用户根目录时,可以直接输入“node index.js”;当index.js处于node.js的安装磁盘根目录时候,可以直接输入“node /index.js”。

在方法sendMyInfo中,我试图向数据库中插入一条记录。那就接着进入node.js的数据库连接和操作吧。

Node.js的数据库操作之创建数据库

我们可以先在Mysql数据库里面创建好一个新的database和一个用户表users。也可以通过Node.js来创建,代码如下:

 var mysql = require('mysql');

 var db_options = {

     host: "localhost",

     port: 3306,

     user: "root",

     password: "Your password"

 };

 var client = new mysql.createConnection(db_options);

 //要创建的数据库名 

 var TEST_DATABASE = 'NodeJsTest', 

     //要创建的表名 

     TEST_TABLE = Users;

 client.query('show databases', function(err, rows, fields){

          if(err){

                    console.log(err);

          }else{

                    console.log(rows);

          }

 });

 client.query('CREATE DATABASE '+TEST_DATABASE, function(err) { 

   if (err && err.number != client.ERROR_DB_CREATE_EXISTS) { 

     throw err; 

   } 

 }); 

 // If no callback is provided, any errors will be emitted as `'error'` 

 // events by the client 

 client.query('USE '+TEST_DATABASE); 

 client.query( 

   'CREATE TABLE '+TEST_TABLE+

   ‘name VARCHAR(255), '+ 

   ' country VARCHAR(255),'+ 

   ' city VARCHAR(255), '+ 

   ' street VARCHAR(255),' 

 ); 

 client.query( 

   'INSERT INTO '+TEST_TABLE+' '+ 

   'SET name = ?, country = ?, city = ?, street = ?', 

   ['Li Lei', 'China', 'Bei jing', ‘ ’] 

 ); 

 client.query('USE '+TEST_DATABASE);

 client.query( 

   'SELECT * FROM '+TEST_TABLE, 

   function selectCb(err, results, fields) { 

     if (err) { 

       throw err; 

     } 

     console.log(results);

          console.log(results[0].name);

          console.log(results.length);   

     console.log(fields);  

   } 

 ); 

 client.end();

说明:Your password为你的Mysql数据库密码。好了,可以将代码所在的js文件直接加载到命令行中,方法还是“node xxxx.js”。如果你之前已经在运行index.js了,那么按下crtrl+C停下之前的服务。我想运行结果会成功的,除非node.js的API又升级了,这个时候就去查官网API吧。

Node.js的数据库操作之插入数据

 var mysql = require('mysql');

 var db_options = {

     host: "localhost",

     port: 3306,

     user: "root",

     password: "Your password"

 };

 //database name 

 var DATABASE = ‘NodeJsTest’, 

 //table name 

 TABLE = 'Users';

 function storeUserInfo(user, res){

          if(user.name == " "){

                    res.writeHead (600, {"Content-Type": "text/plain"});

                    res.write ("error: name can not be empty.\n");

                    res.end();

                    return;

          }

          var client = new mysql.createConnection(db_options);

          client.query('USE '+DATABASE);

          client.query( 

                    "SELECT * FROM "+ TABLE + " WHERE name = ?",

                    [user.name],

                    function(err, results, fields) { 

                             if (err) {

                                      client.end();

                                      res.writeHead (700, {"Content-Type": "text/plain"});

                                      res.write ("error: " + err);

                                      res.end();

                                      return; 

                             } 

                             console.log(results.length);

                             if(results.length < 1){

                                      //Added new record

                                      client.query( 

 "INSERT INTO "+ TABLE + " SET name = ?, country = ?, city = ?, street = ? ", [user.name, user.country, user.city, user.street],

                                                function(err, results, fields) { 

                                                         if (err) { 

                                                                  client.end();

                                                                  res.writeHead (700, {"Content-Type": "text/plain"});

                                                                  res.write ("error: " + err);

                                                                  res.end();

                                                                  return; 

                                                         }                          

                                                         client.end();

                                                         res.writeHead (200, {"Content-Type": "text/plain"});

                                                         res.write ("added new user");

                                                         res.end();

                                                         console.log(results); 

                                                         console.log(fields);  

                                                } 

                                      ); 

                             }else if(results.length == 1){

                                      //Update record

                                      client.query(

 "UPDATE " + TABLE + " SET name = ?, country = ?, city = ?, street = ? WHERE name = ?", [user.name],

                                                function(err, results, fields) { 

                                                         if (err) {

                                                                  client.end();

                                                                  res.writeHead (700, {"Content-Type": "text/plain"});

                                                                  res.write ("error: " + err);

                                                                  res.end();                                                                 

                                                                  return; 

                                                         }                          

                                                         client.end();

                                                         res.writeHead (200, {"Content-Type": "text/plain"});

                                                         res.write ("updated");

                                                         res.end();

                                                         console.log(results); 

                                                         console.log(fields);  

                                                }

                                      )

                             }else{

                                      client.end();

                                      res.writeHead (700, {"Content-Type": "text/plain"});

                                      res.write ("error: Repeat records exist!");

                                      res.end();

                                      console.log("Repeat records exist!");

                                      //handle

                             }  

                    } 

          ); 

 }

 exports.storeUserInfo = storeUserInfo;

说明:这个js实现向数据库里面插入一条记录,如果已存在该用户,则更新用户信息。就是这样的熟悉味道。

忘了一点,我没有封装这个demo的数据库连接,因为当操作多了以后,还是封装一个负责数据库连接操作的DBHelper比较好。

到此,Node.js的总结就结束了,别忘了重新node index.js后,在浏览器里面访问“Your IP : Your port/sendMyInfo?name=xxx&country=xxx&city=xxx&street=xxx”。

APNs功能之Node.js和Mysql应用总结的更多相关文章

  1. Node.js连接MySQL数据库及构造JSON的正确姿势

    做一下整理,以前也很随意的引入包链接数据库,后来发现常常连接出问题,异常退出,后来使用在网上一个方法解决问题,网址由于书签丢失,抱歉不能引用了.再有就是简单的模块化下,使得目录合理点,再有就是说明一下 ...

  2. 分享Node.js + Koa2 + MySQL + Vue.js 实战开发一套完整个人博客项目网站

    这是个什么的项目? 使用 Node.js + Koa2 + MySQL + Vue.js 实战开发一套完整个人博客项目网站. 博客线上地址:www.boblog.com Github地址:https: ...

  3. Node.js连接Mysql,并把连接集成进Express中间件中

    引言 在node.js连接mysql的过程,我们通常有两种连接方法,普通连接和连接池. 这两种方法较为常见,当我们使用express框架时还会选择使用中间express-myconnection,可以 ...

  4. 使用node js 操作 Mysql 数据库

    使用node js 操作 Mysql 数据库 http://www.nodejs.org/ //node js 数据库操作 MySQL //使用https://github.com/felixge/n ...

  5. Node.js 连接 MySQL 并进行数据库操作

    Node.js 连接 MySQL 并进行数据库操作  按照这篇操作mysql的指引,我远程操作了我另一台电脑的mysql数据库. var mysql = require('mysql'); var c ...

  6. node.js连接MySQL操作及注意事项

    node.js作为服务端的js运行环境已经出现了有几年了,最近我有个朋友也在做这方面的开发,但是也是刚刚接触,遇到了很多坑.前几天他们在操作数据库的时候出现了点问题,后来我们一起看了看,其实都是nod ...

  7. node.js使用mysql模块的坑

      之前用node.js写的订餐系统,很容易挂掉,一直也没想去解决它.今天看了一下,试了试,原因是在连接数据库的时候没有对error事件进行处理,导致程序一直挂在那里,需要重启服务才能正常使用.   ...

  8. Async.js解决Node.js操作MySQL的回调大坑

    因为JavaScript语言异步特性.在使用Node.js运行非常多操作时都会使用到回调函数,当中就包含訪问数据库.假设代码中的业务逻辑略微复杂一点,回调一层层嵌套.那么代码非常easy进入Callb ...

  9. node.js操作MySQL数据库

    MySQL数据库作为最流行的开源数据库.基本上是每个web开发者必须要掌握的数据库程序之一了. 基本使用 node.js上,最受欢迎的mysql包就是mysql模块. npm install mysq ...

随机推荐

  1. 交易应用-运行多个SQL声明

    事务具有原子性.要么不运行.要么全运行.一旦成功运行永久保存.而这些正是因为事务的原子性和对数据库的持久性形成的.下面是一个关于统一给数据库中的数据改动的批量操作,利用到事务. TODO:批量改动数据 ...

  2. Entity Framework执行Sql语句返回DataTable

    Entity Framework中对外开放了数据库连接字符串,使用的时候可以直接得到这个连接字符串,然后进行相关的操作.如果在使用的过程中,发现Entity Framework中有一些满足不了的需求的 ...

  3. mac github工具将命令当下来的代码拖入macgithub中就可以

    mac github工具将命令当下来的代码拖入macgithub中就可以,刚開始傻傻的就知道点击那个加入button,总是在当下来的文件夹下创建个文件夹.并且代码不能同步

  4. [Phonegap+Sencha Touch] 移动开发34 gem安装compass,不编译scss,怎么办?

    很多人已经发现,今天,该命令 "gem install compass" 安装compass,正在使用 "compass compile" 编scss的时间将报 ...

  5. Net社区虚拟大会

    微软“.Net社区虚拟大会”dotnetConf2015:关键词:.NET 创新.开源.跨平台 去年 11 月的时候,微软开源了 .NET CoreFX,然后是今年 2 月份的 .NET CoreCL ...

  6. iOS_中国汉字到拼音_pinyin4objc

    最后效果图: ViewController.h // // ViewController.h // PinYin4Objc汉字转拼音演示demo // // Created by beyond on ...

  7. IE6下jquery ajax报error的原因

    用jquery ajax()方法,在其他浏览都通过,IE7以上都通过,唯独在ie6不行. 我这边的解决方案是:必须保证ajax里面的所有数字为小写,ie6对大小写敏感. 错误: $.ajax({ ur ...

  8. SURF分析算法

    SURF分析算法 一个.整体形象     这个概念是积分图像Viola和Jones建议.随机位积分图像(i.j)的值原始图象的左上角随机点(i,j)级配相应的重点领域值的总和,其数学公式如图1所看到的 ...

  9. CloudNotes

    CloudNotes 今天,我发布了CloudNotes的一个更新版本:1.0.5484.36793.这个版本与1.0.5472.20097不同的是,它拥有增强的笔记列表,与之前单调的列表系统相比,新 ...

  10. Jquery AJAX POST与GET之间的区别

    1:GET访问 浏览器 认为 是等幂的就是 一个相同的URL 只有一个结果[相同是指 整个URL字符串完全匹配]所以 第二次访问的时候 如果 URL字符串没变化 浏览器是 直接拿出了第一次访问的结果 ...