• APNs功能之Node.js和Mysql应用总结


    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的代码:

     1 var server = require("./server");
     2 
     3 var router = require("./router");
     4 
     5 var requestHandlers = require("./requestHandlers");
     6 
     7  
     8 
     9 var handle = {}
    10 
    11 handle["/"] = requestHandlers.start;
    12 
    13 handle["/start"] = requestHandlers.start;
    14 
    15 handle["/upload"] = requestHandlers.upload;
    16 
    17 handle["/show"] = requestHandlers.show;
    18 
    19 handle["/sendMyInfo"] = requestHandlers.sendMyInfo;
    20 
    21  
    22 
    23 server.start(router.route, handle);
    View Code

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

          server.js的代码:

     1 var http = require('http');
     2 
     3 var url = require('url');
     4 
     5 function start(route, handle){
     6 
     7               function onRequest(req,res){
     8 
     9                        var pathname = url.parse(req.url).pathname;
    10 
    11                        console.log("Request for " + pathname + " received.");
    12 
    13                       
    14 
    15                        route(handle, pathname, res,req);         
    16 
    17               }
    18 
    19               http.createServer(onRequest).listen(1337, 'Your IP');
    20 
    21               console.log('Server running at http://Your IP:1337/');
    22 
    23 }
    24 
    25  
    26 
    27 exports.start = start;
    View Code

    说明:与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的代码

     1 function route(handle, pathname, res, req){
     2 
     3               console.log("About to route a request for " + pathname);
     4 
     5               if(typeof handle[pathname] === 'function'){
     6 
     7                        handle[pathname](res, req);
     8 
     9               }else{
    10 
    11                        console.log("No request handler found for " + pathname);
    12 
    13                        res.writeHead(404, {'Content-Type': 'text/plain'});
    14 
    15                        res.end('404 route not found');
    16 
    17               }
    18 
    19 }
    20 
    21  
    22 
    23 exports.route = route;
    View Code

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

    requestHanlders.js的代码:

      1 var querystring = require ("querystring");
      2 
      3 var url = require('url');
      4 
      5 var fs = require("fs");
      6 
      7 var formidable = require("formidable");
      8 
      9 var util = require("util");
     10 
     11 var mysqlOperation = require("./mysqlOperation");
     12 
     13 var testPicPath = "/testPic/test.png";
     14 
     15 function start(res, req){
     16 
     17               console.log("Request handler 'start' was called.");
     18 
     19               var body = '<html>'+
     20 
     21                        '<head>'+
     22 
     23                        '<meta http-equiv="Content-Type" content="text/html; '+
     24 
     25                        'charset=UTF-8" />'+
     26 
     27                        '</head>'+
     28 
     29                        '<body>'+
     30 
     31                        '<form action="/upload" enctype="multipart/form-data" method="post">'+
     32 
     33                        '<input type="file" name="upload">'+
     34 
     35                        '<input type="submit" value="Upload file" />'+
     36 
     37                        '</form>'+
     38 
     39                        '</body>'+
     40 
     41                        '</html>';
     42 
     43               res.writeHead(200, {'Content-Type': 'text/html'});
     44 
     45               res.end(body);
     46 
     47 }
     48 
     49  
     50 
     51 function upload(res, req){
     52 
     53               console.log("Request handler 'upload' was called.");
     54 
     55  
     56 
     57               var form = new formidable.IncomingForm();
     58 
     59  
     60 
     61               console.log("about to parse");
     62 
     63  
     64 
     65               form.parse (req, function(error, fields, files) {
     66 
     67                        console.log("parsing done");
     68 
     69 /*                  res.writeHead(200,{"Content-type":"text/plain"});
     70 
     71                        res.write("received upload:
    
    ");
     72 
     73                        res.write(util.inspect({fields:fields,files:files})); */
     74 
     75  
     76 
     77                        fs.rename(files.upload.path, '/testPic/' + files.upload.name, function(err){
     78 
     79                                  if(err) throw err;
     80 
     81                                  console.log("renamed complete");
     82 
     83                                  testPicPath =  "/testPic/" + files.upload.name;
     84 
     85                                 
     86 
     87                                  res.writeHead (200, {"Content-Type": "text/html"});
     88 
     89  
     90 
     91                                  res.write ("received image:<br/>");
     92 
     93  
     94 
     95                                  res.write ("<img src= '/show' />");
     96 
     97  
     98 
     99                                  res.end();
    100 
    101                        }); 
    102 
    103               });
    104 
    105 }
    106 
    107  
    108 
    109 function show(res, req) {
    110 
    111               console.log("Request handler 'show' was called.");
    112 
    113               fs.readFile (testPicPath, "binary", function(error, file) {
    114 
    115                        if(error) {
    116 
    117                                  res.writeHead (500, {"Content-Type": "text/plain"});
    118 
    119                                  res.write ("Image error: " + error + "
    ");
    120 
    121                                  res.end();
    122 
    123                        } else {
    124 
    125                                  res.writeHead (200, {"Content-Type": "image/png"});
    126 
    127                                  res.write (file, "binary");
    128 
    129                                  res.end();
    130 
    131                        }
    132 
    133               });
    134 
    135 }
    136 
    137  
    138 
    139 function sendMyInfo(res,req){
    140 
    141               console.log("Request handler 'sendMyInfo' was called.");
    142 
    143               var urlstring = url.parse(req.url).query;
    144 
    145               var user = {
    146 
    147                        name : querystring.parse(urlstring).name,
    148 
    149                        country : querystring.parse(urlstring).country,
    150 
    151                        city : querystring.parse(urlstring).city,
    152 
    153                        street : querystring.parse(urlstring).street
    154 
    155               };
    156 
    157              
    158 
    159               if(use.name == undefined || user.country == undefined
    160 
    161 || user.city == undefined || user.street == undefined){
    162 
    163                        res.writeHead (500, {"Content-Type": "text/plain"});
    164 
    165                        res.write ("error: paras undefined.");
    166 
    167                        res.end();
    168 
    169                        console.log("error: paras undefined.");
    170 
    171                        return;
    172 
    173               }
    174 
    175              
    176 
    177               console.log(user);
    178 
    179               mysqlOperation.storeUserInfo(user,res);
    180 
    181 }
    182 
    183  
    184 
    185 exports.start = start;
    186 
    187 exports.upload = upload;
    188 
    189 exports.show = show;
    190 
    191 exports.sendMyInfo = sendMyInfo;
    View Code

    说明:这个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来创建,代码如下:

      1 var mysql = require('mysql');
      2 
      3 var db_options = {
      4 
      5     host: "localhost",
      6 
      7     port: 3306,
      8 
      9     user: "root",
     10 
     11     password: "Your password"
     12 
     13 };
     14 
     15 var client = new mysql.createConnection(db_options);
     16 
     17  
     18 
     19 //要创建的数据库名 
     20 
     21 var TEST_DATABASE = 'NodeJsTest', 
     22 
     23     //要创建的表名 
     24 
     25     TEST_TABLE = Users;
     26 
     27  
     28 
     29 client.query('show databases', function(err, rows, fields){
     30 
     31          if(err){
     32 
     33                    console.log(err);
     34 
     35          }else{
     36 
     37                    console.log(rows);
     38 
     39          }
     40 
     41 });
     42 
     43  
     44 
     45 client.query('CREATE DATABASE '+TEST_DATABASE, function(err) { 
     46 
     47   if (err && err.number != client.ERROR_DB_CREATE_EXISTS) { 
     48 
     49     throw err; 
     50 
     51   } 
     52 
     53 }); 
     54 
     55  
     56 
     57 // If no callback is provided, any errors will be emitted as `'error'` 
     58 
     59 // events by the client 
     60 
     61 client.query('USE '+TEST_DATABASE); 
     62 
     63 client.query( 
     64 
     65   'CREATE TABLE '+TEST_TABLE+
     66 
     67   ‘name VARCHAR(255), '+ 
     68 
     69   ' country VARCHAR(255),'+ 
     70 
     71   ' city VARCHAR(255), '+ 
     72 
     73   ' street VARCHAR(255),' 
     74 
     75 ); 
     76 
     77  
     78 
     79 client.query( 
     80 
     81   'INSERT INTO '+TEST_TABLE+' '+ 
     82 
     83   'SET name = ?, country = ?, city = ?, street = ?', 
     84 
     85   ['Li Lei', 'China', 'Bei jing', ‘ ’] 
     86 
     87 ); 
     88 
     89  
     90 
     91 client.query('USE '+TEST_DATABASE);
     92 
     93 client.query( 
     94 
     95   'SELECT * FROM '+TEST_TABLE, 
     96 
     97   function selectCb(err, results, fields) { 
     98 
     99     if (err) { 
    100 
    101       throw err; 
    102 
    103     } 
    104 
    105  
    106 
    107     console.log(results);
    108 
    109          console.log(results[0].name);
    110 
    111          console.log(results.length);   
    112 
    113     console.log(fields);  
    114 
    115   } 
    116 
    117 ); 
    118 
    119  
    120 
    121 client.end();
    View Code

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

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

      1 var mysql = require('mysql');
      2 
      3 var db_options = {
      4 
      5     host: "localhost",
      6 
      7     port: 3306,
      8 
      9     user: "root",
     10 
     11     password: "Your password"
     12 
     13 };
     14 
     15  
     16 
     17 //database name 
     18 
     19 var DATABASE = ‘NodeJsTest’, 
     20 
     21 //table name 
     22 
     23 TABLE = 'Users';
     24 
     25 function storeUserInfo(user, res){
     26 
     27          if(user.name == " "){
     28 
     29                    res.writeHead (600, {"Content-Type": "text/plain"});
     30 
     31                    res.write ("error: name can not be empty.
    ");
     32 
     33                    res.end();
     34 
     35                    return;
     36 
     37          }
     38 
     39          var client = new mysql.createConnection(db_options);
     40 
     41          client.query('USE '+DATABASE);
     42 
     43         
     44 
     45          client.query( 
     46 
     47                    "SELECT * FROM "+ TABLE + " WHERE name = ?",
     48 
     49                    [user.name],
     50 
     51                    function(err, results, fields) { 
     52 
     53                             if (err) {
     54 
     55                                      client.end();
     56 
     57                                      res.writeHead (700, {"Content-Type": "text/plain"});
     58 
     59                                      res.write ("error: " + err);
     60 
     61                                      res.end();
     62 
     63                                      return; 
     64 
     65                             } 
     66 
     67                            
     68 
     69                             console.log(results.length);
     70 
     71                             if(results.length < 1){
     72 
     73                                      //Added new record
     74 
     75                                      client.query( 
     76 
     77 "INSERT INTO "+ TABLE + " SET name = ?, country = ?, city = ?, street = ? ", [user.name, user.country, user.city, user.street],
     78 
     79                                                function(err, results, fields) { 
     80 
     81                                                         if (err) { 
     82 
     83                                                                  client.end();
     84 
     85                                                                  res.writeHead (700, {"Content-Type": "text/plain"});
     86 
     87                                                                  res.write ("error: " + err);
     88 
     89                                                                  res.end();
     90 
     91                                                                  return; 
     92 
     93                                                         }                          
     94 
     95                                                        
     96 
     97                                                         client.end();
     98 
     99                                                         res.writeHead (200, {"Content-Type": "text/plain"});
    100 
    101                                                         res.write ("added new user");
    102 
    103                                                         res.end();
    104 
    105                                                         console.log(results); 
    106 
    107                                                         console.log(fields);  
    108 
    109                                                } 
    110 
    111                                      ); 
    112 
    113                             }else if(results.length == 1){
    114 
    115                                      //Update record
    116 
    117                                      client.query(
    118 
    119 "UPDATE " + TABLE + " SET name = ?, country = ?, city = ?, street = ? WHERE name = ?", [user.name],
    120 
    121                                                function(err, results, fields) { 
    122 
    123                                                         if (err) {
    124 
    125                                                                  client.end();
    126 
    127                                                                  res.writeHead (700, {"Content-Type": "text/plain"});
    128 
    129                                                                  res.write ("error: " + err);
    130 
    131                                                                  res.end();                                                                 
    132 
    133                                                                  return; 
    134 
    135                                                         }                          
    136 
    137                                                        
    138 
    139                                                         client.end();
    140 
    141                                                         res.writeHead (200, {"Content-Type": "text/plain"});
    142 
    143                                                         res.write ("updated");
    144 
    145                                                         res.end();
    146 
    147                                                         console.log(results); 
    148 
    149                                                         console.log(fields);  
    150 
    151                                                }
    152 
    153                                      )
    154 
    155                             }else{
    156 
    157                                      client.end();
    158 
    159                                      res.writeHead (700, {"Content-Type": "text/plain"});
    160 
    161                                      res.write ("error: Repeat records exist!");
    162 
    163                                      res.end();
    164 
    165                                      console.log("Repeat records exist!");
    166 
    167                                      //handle
    168 
    169                             }  
    170 
    171                    } 
    172 
    173          ); 
    174 
    175 }
    176 
    177  
    178 
    179 exports.storeUserInfo = storeUserInfo;
    View Code

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

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

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

  • 相关阅读:
    cocos2dx Menu
    关于iOS招聘面试的一些问题
    OC画图
    iOS苹果产品简介
    iOS知识小总结
    @property的修饰参数的的解释
    IOS:UI设计之UINavigationController,NavigationBar,ToolBAR相关基础
    IOS:UI设计之UISegmentedControl相关基础
    IOS:UI设计之UISlider相关基础
    IOS:UI设计之UILable相关基础
  • 原文地址:https://www.cnblogs.com/A-Long-Way-Chris/p/3534625.html
Copyright © 2020-2023  润新知