2014年6月13日 星期五

如何接收GCM Server發送的Registration ID訊息,以php、Java及JSP為例

在行動裝置安裝了有GCM功能的App之後,會根據App的功能進行Registration ID的註冊,接著將會將Registration ID傳送到後台,後台收到Registration ID後就可以對之做相應的處理,例如此篇文章就採取將Registration ID存進資料庫的處理。

以下後台的範例程式有兩個版本,一個為php、另一為Java,共同的環境為:

1.資料庫此例為MySql,假設相關資訊為
   Host : localhost
   User : userName
   Password :  pass
   Database :  DB_Name
   Table      :   TB_Name
   Table只有一個欄位,名為regId,存放著Registration ID

2.行動裝置使用了POST傳送方式,資料內容沒有使用JSON等格式,為最普通的名值對,如以下所示

regId=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
一、首先是php版本
<?php
    //建立跟資料庫的連接
    $dbhost = 'localhost';
    $dbuser = 'userName';
    $dbpass = 'pass';
    $dbname = 'DB_Name';
    $conn = mysql_connect($dbhost, $dbuser, $dbpass) or die('Error with MySQL connection');
    mysql_query("SET NAMES 'utf8'");
    mysql_select_db($dbname);
   //從行動裝置的傳來訊息中,獲取Registration ID
    if(isset($_POST['regId']))
    {
        $regId = $_POST['regId'];
        $sql = "INSERT INTO TB_Name(regId) VALUES ('$regId')";    新增資料進資料庫中
        mysql_query($sql) or die('MySQL query error');
    }
?>
二、JAVA版本(使用Apache的HttpClient)

import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.impl.DefaultBHttpServerConnection;
import org.apache.http.util.EntityUtils;

public class GCM_register {
public static void main(String[] args) {
try {
//服務器監聽端口號8081
ServerSocket serverSocket = new ServerSocket(8081);
Socket socket;

// 驅動程序名
String driver = "com.mysql.jdbc.Driver";
// URL指向要訪問的數據庫名
String url = "jdbc:mysql://127.0.0.1:3306/DB_Name";
// MySQL配置時的用戶名
String user = "userName";
// Java連接MySQL配置時的密碼
String password = "pass";
Connection connDB = null;

Class.forName(driver);
// 連接數據庫
connDB = DriverManager.getConnection(url, user, password);
if (!connDB.isClosed())
System.out.println("Succeeded connecting to the Database!");
// statement用來執行SQL語句
Statement statement = connDB.createStatement();
                        //無窮迴圈,不斷等待新安裝App的手機傳Registration ID進來
while (true) {
// 等待接收請求,這是一個阻塞的方法,當請求到來的時候才會繼續向下執行
socket = serverSocket.accept();
DefaultBHttpServerConnection conn = new DefaultBHttpServerConnection(2000);
conn.bind(socket);
HttpRequest request = conn.receiveRequestHeader();
if (request instanceof HttpEntityEnclosingRequest) {
conn.receiveRequestEntity((HttpEntityEnclosingRequest) request);
                                        //取得行動裝置傳來的訊息其實體之POST的資料部份
HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
String regIdKey = "regId=";
if (entity != null) {
String ss = EntityUtils.toString(entity);
                                                //用來分辨POST資料的開頭是否為"regId="
if (ss.startsWith(regIdKey)) {
                                                        //讀取"regID="之後的內容
String regId = ss.substring(regIdKey.length());
System.out.println(regId);
// 要執行的SQL語句,將Registration ID新增到資料庫中
String sql = "INSERT INTO TB_Name(regId) VALUES ('"
+ regId + "')";
statement.executeUpdate(sql);  //執行SQL的INSERT命令
}
EntityUtils.consume(entity);
conn.close();
}
}
}
} catch (Exception er) {
System.out.println(er.getMessage());
}
}
}
三、JSP版本(使用Netbeans的war檔佈署)
<%@ page import="java.sql.*"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Hello World!</h1>
        //得到GCM_Server傳來的regId訊息
        <%String regid = request.getParameter("regId");%>
        <%
            try {
//讀取mysqlDriver驅動程式
                Class.forName("com.mysql.jdbc.Driver").newInstance();
//連接mysql資料庫
// 使用Unicode編碼"true",字元集"UTF-8"
                String db_user = "userName";
                String db_pwd = "pass";
                String db_database = "DB_Name";
                Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + db_database + "?user=" + db_user + "&password=" + db_pwd + "&useUnicode=true&characterEncoding=UTF-8");

//建立statement
                Statement statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

//建立SQL查詢
                String sql = "INSERT INTO TB_Name(regId) VALUES ('" + regid +"')";
                statement.executeUpdate(sql);  //執行SQL語法
            } catch (Exception err) {
                out.println(err.getMessage());
            }
        %>
    </body>
</html>

2 則留言 :

  1. 急!
    想問如果我database裹開一個table存放Registration ID
    但在其他特定的一個table有新資料insert時才在app push notification可行嗎?

    因為我普遍找到的教學例子都只有一個放registration ID的table

    回覆刪除
    回覆
    1. 請問你的意思是: 你有兩個table,table1放Registration ID、另一個tabel2放想要push給app的notification之資料,並且你想要在table2有insert資料時即時push notification給app(對應到table1裏的各Registration ID),
      是這樣嗎?如果是這樣的話,應該隻要在insert資料進database的程式碼處再加上push notification給app的程式碼就好了。

      刪除