Category Archives: 14. Web API RESTful

Bài 72: Học Firebase Cloud Message(FCM)


Trong bài Bài 50: Cách sử dụng Google Cloud Message trong Android Tui đã hướng dẫn rất chi tiết về Google Cloud Message(GCM). Hiện nay Google đã ra phiên bản mới là Firebase Cloud Message (FCM) cực kỳ hiệu quả, vì vậy để giúp các Sinh Viên hiểu và triển khai được FCM Tui đã quay Video lại từng bước làm FCM (hơn 2 giờ xem Video). Các em có thể xem Video tại post này (Tui không đủ thời gian để làm trau chuốt cái Video, nên Tui đang để thô các bạn cứ việc xem nhé, có thể kéo qua những chỗ phải chờ lâu. Chú ý Video này hướng dẫn cách làm FCM đã chạy hoàn chỉnh ngon như cơm mẹ nấu, có một vài lần test không ra là do mạng chậm nên các em cứ coi như OK nhé).

Để học FCM các em cần biết về kiến trúc hoạt động của FCM:

b72_1

Ở hình trên Tui để 5 bước, các bạn cần hiểu kiến trúc hoạt động của FCM như sau:

Bước 1: Khi các thiết bị của khách hàng cài phần mềm của Ta vào thì nó sẽ gửi yêu cầu lên Firebase Cloud Server để xin  Token

Bước 2: Firebase Server sẽ trả về Token(không trùng nhau) cho thiết bị đó.

Bước 3: Nhiệm vụ của Ta phải lưu được Token mà Firebase trả về cho từng thiết bị để sử dụng lại lần sau. Phải xây dựng Webservice để để bắn Token này về Server riêng của ta

Bước 4: Là phần Admin để quản trị việc thông báo Push Message cho các khách hàng có sử dụng phần mềm của mình (không tốn phí, được gửi khoảng gần 1000 thiết bị), Bước này Ta phải gửi danh sách Token + Thông điệp muốn thông báo cho FireBase (Tức là ta không có trực tiếp gửi cho khách hàng được , mà phải gửi yêu cầu cho Firebase xử lý. Vì lúc này Firebase cũng đang quản lý Token)

Bước 5: Sau khi Firebase nhập được yêu cầu từ bước 4, nó sẽ tự động kiểm tra và gửi thông báo tới toàn bộ khách hàng đúng với Token mà bước 4 yêu cầu.

Trong phần hướng dẫn này, Tui yêu cầu các bạn làm theo (các bạn có thể dùng PHP):

1) Xây dựng Remote Server (Asp.net – C#, IIS Webserver)

– SQL Server

– RESTFul

– IIS Web Server

2)Tạo Project Android để có tương tác FCM

3) Sử dụng https://console.firebase.google.com

4) Test chức năng FCM

Chi tiết từng bước làm Tui trong Video này, các bạn xem ở đây (Youtube) – Khoảng hơn 2 Tiếng nhé(đang upload lại, do bị lệch khung hình với âm thanh):

Còn đây là source code:

Chúc các bạn thành công.

=================================

Nếu khó theo dõi bằng Video được thì bạn có thể theo dõi hướng dẫn bằng các giải thích dưới đây:

1) Xây dựng Remote Server (Asp.net – C#, IIS Webserver)

  • Tạo Cơ sở dữ liệu CSDLFirebase:

b72_2

hình Trên Tui tạo CSDL tên : CSDLFirebase, có 1 bảng tên là FCM với 2 cột (id-tự động tăng làm khóa chính, bạn để Identity Specification =YES ; Cột token kiểu chuỗi để lưu Token mà firebase gửi về cho từng thiết bị).

  • Viết Webservice (Restful – Web API) để Mobile tương tác được với CSDLFirebase:

Khởi động Visual Studio, tạo 1 Project đặt tên là FCMServer:

b72_3

Ở hình trên Tui chọn C#/ Web / chọn ASP.NET Application. Phần Name đặt là FCMServer rồi nhấn nút OK, lúc này Visual mở ra màn hình hỏi ta chọn Template tiếp theo, ở màn hình dưới này ta chọn Empty rồi nhấn nút OK:

b72_4

Sau khi nhấn nút OK, ta được Solution dưới đây:

b72_5

Ta tiến hành tạo thư mục Models (để tạo lớp FCM, ở đây bạn có thể dùng LinQ để tự phát sinh, nhưng đây là chủ ý của Tui, Tui muốn hướng dẫn các bạn cách dùng ADO.NET):

b72_6

Ở màn hình trên, bạn bấm chuột phải vào Project/ chọn Add/ chọn new folder, rồi đặt tên folder là Models:

b72_7

Ta cần tạo 1 lớp tên là FCM trong thư mục Models này, bằng cách: Bấm chuột phải vào Models/chọn New/ chọn Class:

b72_8

Một màn hình hiển thị lên, ta chọn Class, rồi đặt tên là FCM, nhấn Add để tạo:

b72_9

Ta tiến hành coding cho lớp FCM như sau:

b72_10

tương tự tạo 1 thư mục mới tên là Controllers:

b72_11

Bấm chuột phải vào Controllers/ chọn Add/ chọn Controller…:

b72_12

Một cửa sổ hiển thị lên, mặc định là DefaultController, bạn sửa lại thành FCMController:

b72_13Khi bạn bấm Add, ta có kết quả:

b72_14

Bạn quan sát lớp FCMController được sinh ra , kế thừa từ ApiController, đồng thời phát sinh thêm lớp WebApiConfig.cs:

b72_15

Tui có giải thích file config này ở đây (các bạn có thể đọc lại): https://duythanhcse.wordpress.com/2015/11/10/bai-69-xay-dung-web-service-dung-api-restful-servicephan-2/

Để lập trình con FCMController, trước tiên ta cần cấu hình chuỗi kết nối tới CSDL trước trong file Webconfig:

b72_16

Bạn để ý Tui bổ sung :


<appSettings>
<add key="strConnection" value="server=.;database=CSDLFirebase;user id=sa;pwd=@Hunggia113"/>
</appSettings>

Tùy vào cấu hình SQL Server của bạn thì bạn cần đặt đúng user + mật khẩu nhé.

Giờ ta quay trở lại lập trình FCMController:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

using System.Data;
using System.Data.SqlClient;
using FCMServer.Models;

namespace FCMServer.Controllers
{
public class FCMController : ApiController
{
///
<summary>
/// trả về FCM theo id
/// </summary>

/// <param name="id">id trong CSDL</param>
/// <returns></returns>
[HttpGet]
public FCM getFCM(int id)
{
try
{
string strConnection =
System.Configuration.ConfigurationManager.AppSettings["strConnection"];

SqlConnection conn = new SqlConnection(strConnection);
conn.Open();
string sql = "select * from FCM where id=@id";
SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.Add("@id", SqlDbType.NVarChar).Value = id;
SqlDataReader reader = command.ExecuteReader();
FCM fcm = null;
while (reader.Read())//trong khi còn dữ liệu để đọc
{
fcm = new FCM();
fcm.Id = reader.GetInt32(0);
fcm.Token = reader.GetString(1);
}
conn.Close();
return fcm;
}
catch (Exception ex)
{
throw ex;
}
}
///
<summary>
/// Hàm trả về toàn bộ FCM để ta gửi Push Message cho toàn bộ device
/// </summary>

/// <returns></returns>
[HttpGet]
public List<FCM>getFCMS()
{
try
{
List<FCM> dsFcm = new List<FCM>();
string strConnection =
System.Configuration.ConfigurationManager.AppSettings["strConnection"];

SqlConnection conn = new SqlConnection(strConnection);
conn.Open();
string sql = "select * from FCM";
SqlCommand command = new SqlCommand(sql, conn);
SqlDataReader reader = command.ExecuteReader();
FCM fcm = null;
while (reader.Read())//trong khi còn dữ liệu để đọc
{
fcm = new FCM();
fcm.Id = reader.GetInt32(0);
fcm.Token = reader.GetString(1);
dsFcm.Add(fcm);
}
conn.Close();
return dsFcm;
}
catch (Exception ex)
{
throw ex;
}
}
///
<summary>
/// trả về FCM dựa vào 1 token
/// </summary>

/// <param name="token">token từ Firebase</param>
/// <returns>Nếu có trả về FCM, không có trả về null</returns>
[HttpGet]
public FCM getFCM(string token)
{
try
{
string strConnection =
System.Configuration.ConfigurationManager.AppSettings["strConnection"];

SqlConnection conn = new SqlConnection(strConnection);
conn.Open();
string sql = "select * from FCM where token=@token";
SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.Add("@token", SqlDbType.NVarChar).Value = token;
SqlDataReader reader = command.ExecuteReader();
FCM fcm = null;
while (reader.Read())//trong khi còn dữ liệu để đọc
{
fcm = new FCM();
fcm.Id = reader.GetInt32(0);
fcm.Token = reader.GetString(1);
}
conn.Close();
return fcm;
}
catch (Exception ex)
{
throw ex;
}
}
///
<summary>
/// Dịch vụ này dùng để lưu token của Device vào cơ sở dữ liệu
/// </summary>

/// <param name="token">token do Firebase truyền về</param>
/// <returns>lưu thành công trả về true, thất bại flase</returns>
[HttpPost]
public bool saveToken(string token)
{
try
{
if (getFCM(token) != null) return false;

string strConnection =
System.Configuration.ConfigurationManager.AppSettings["strConnection"];

SqlConnection conn = new SqlConnection(strConnection);
conn.Open();
string sql = "insert into FCM(token) values(@token)";
SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.Add("@token",SqlDbType.NVarChar).Value=token;
int kq = command.ExecuteNonQuery();//tiến hành insert
conn.Close();
return kq > 0;
}
catch(Exception ex)
{
throw ex;
}
}
}
}

Bạn chú ý chép vào nhé, vì muốn hiểu nó bạn phải rành về Lập trình cơ sở dữ liệu với C#, tuy nhiên trong bài này ta coi như đã biết, ứng dụng vào hệ thống này cho tiện.

Tiếp theo tạo 1 thư mục Views:

b72_17

Từ thư mục Views/ nhấn chuột phải/chọn Add/ Webform:

b72_18

màn hình hiển thị lên ta đặt tên là Admin rồi nhấn OK:

b72_19

bạn thiết kế Admin.aspx như sau (mục đích của trang này là cho phép gửi Push Notification tới toàn bộ Thiết bị của khách hàng có cài phần mềm Mobile của ta):

b72_20

Dưới đây là coding HTML (Design, chép vào Source):


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Admin.aspx.cs" Inherits="FCMServer.Views.Admin" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>

<form id="form1" runat="server">

<div>

Nhập tiêu đề muốn gửi thông báo:
<asp:TextBox ID="txtTieuDe" runat="server" Width="326px"></asp:TextBox>

Nhập nội dung muốn gửi thông báo:
<asp:TextBox ID="txtNoiDung" runat="server" Height="150px" TextMode="MultiLine" Width="358px"></asp:TextBox>

<asp:Button ID="btnGui" runat="server" OnClick="btnGui_Click" Text="Gửi thông báo tới toàn bộ khách hàng" />

kết quả sau khi gửi thông báo:
<asp:TextBox ID="txtKetQua" runat="server" Height="150px" TextMode="MultiLine" Width="358px"></asp:TextBox>

</div>

</form>

</body>
</html>

Bên trên là phần giao diện, bây giờ ta xử lý phần Coding:

b72_21

Coding đầy đủ của màn hình trên:


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace FCMServer.Views
{
public partial class Admin : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}

protected void btnGui_Click(object sender, EventArgs e)
{
Controllers.FCMController fcmController = new Controllers.FCMController();
List<Models.FCM> dsFcm = fcmController.getFCMS();
WebRequest tRequest;
//thiết lập FCM send
tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "POST";
tRequest.UseDefaultCredentials = true;

tRequest.PreAuthenticate = true;

tRequest.Credentials = CredentialCache.DefaultNetworkCredentials;

//định dạng JSON
tRequest.ContentType = "application/json";
tRequest.Headers.Add(string.Format("Authorization: key={0}", "<Chép KEY trong Firebase của bạn>"));
tRequest.Headers.Add(string.Format("Sender: id={0}", "<Chép ID trong Firebase của bạn>"));

string[] arrRegid = dsFcm.Select(x => x.Token).ToArray();
string RegArr = string.Empty;
RegArr = string.Join("\",\"", arrRegid);

string postData = "{ \"registration_ids\": [ \"" + RegArr + "\" ],\"data\": {\"message\": \"" + txtNoiDung.Text + "\",\"body\": \"" + txtNoiDung.Text + "\",\"title\": \"" + txtTieuDe.Text + "\",\"collapse_key\":\"" + txtNoiDung.Text + "\"}}";

Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;

Stream dataStream = tRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();

WebResponse tResponse = tRequest.GetResponse();

dataStream = tResponse.GetResponseStream();

StreamReader tReader = new StreamReader(dataStream);

String sResponseFromServer = tReader.ReadToEnd();

txtKetQua.Text = sResponseFromServer; //Lấy thông báo kết quả từ FCM server.
tReader.Close();
dataStream.Close();
tResponse.Close();
}
}
}

Bạn để ý :

Dòng 36: <Chép KEY trong Firebase của bạn>

Dòng 37: <Chép ID trong Firebase của bạn>

==> Bạn chỉ cần sửa 2 dòng lệnh này là đủ rồi, đó chính là chỗ tạo Project trong Firebase(Sẽ hướng dẫn các bạn tạo Project Firebase và chép vào chỗ này sau, Tạo thời ta cứ cấu hình chạy IIS Webserver. Khi nào qua phần Firebase ta sẽ chép lại sau)

  • Cấu hình IIS WEB Server:

Vì Tui đã hướng dẫn rất kỹ phần cấu hình IIS WEB Server trong bài 71 https://duythanhcse.wordpress.com/2015/11/11/bai-71-xay-dung-web-service-dung-api-restful-servicephan-4/ rồi, nên các bạn tự xem lại, dưới đây tui chụp hình kết quả:

b72_22Kết quả chạy:

b72_23

Chú ý ở trên là local host, lúc tương tác Mobile nó hiểu nhầm, nên bạn phải lấy địa chỉ IP (Mở của sổ Command line, gõ ipconfig để lấy IP):

b72_24

Ở cửa sổ trên (gõ Tổ hợp phím Windows + R), ta nhập cmd rồi nhấn OK:

b72_25Gõ Ipconfig ta được địa chỉ IP như bên dưới, giờ xem website từ IIS:

b72_26Hay vào xem Admin.aspx:

b72_27==> Các Em chú ý địa chỉ IP là theo máy các em nhé, nếu đã có domain thì chả cần quan tâm cái này, Nhưng ta là lập trình viên, đang test nên phải biết vụ này. Từ Mobile sẽ tương tác dựa trên cái này.

2)Tạo Project Android để có tương tác FCM

Bây giờ cá em tiến hành tạo 1 Project Android Studio có tên FCMClient như hình chụp dưới đây:

b72_28

Em để ý Tui khoanh đỏ package nhé, nó được dùng để đăng ký trên firebase.

3) Sử dụng https://console.firebase.google.com

Các em vào trang trên, Nếu chưa có Project nào có thì có hình sau:

b72_29

Nếu đã có Project rồi, thì hệ thống liệt kê ra như dưới đây:

b72_30

Giờ em chọn Create New Project để tạo:

b72_31

Các em đặt tên Project, chọn Việt Nam rồi nhấn Create Project:

b72_32Các Em thấy Tui đánh dấu số 1, số 2. Số 1 là cấu hình Firebase vào ứng dụng Android FCMClient, số 2 là xem danh sách các Project khác (em nhấn vào số 2 sẽ thấy danh sách các Project Firebase khác).

Bây giờ các em nhấn vào số 1 (Add Firebase to your Android app):

b72_33

Ta tiến hành Copy Package bên Project Android FCMClient vào chỗ này:

b72_34

Sau khi copy xong, các em nhấn ADD App:

b72_35Em Thấy Google hướng dẫn, tại màn hình này sẽ có file google_services.json tải về, và yêu cầu ta lưu vào bên trong thư mục app:

b72_36

Hình trên em thấy Tui trỏ tới thư mục app và nhấn Save (có thể lưu sau nếu quên bước này). Sau đó nhấn Continue để tiếp tục:

b72_37

Em thấy Google hướng dẫn ta sao chép các cấu hình vào Project rồi nhấn Sync now:

Đầu tiên là chép

classpath 'com.google.gms:google-services:3.0.0'
b72_38
Bước tiếp theo là sao chép:
apply plugin: 'com.google.gms.google-services'
Đồng thời sao chép cả:
compile 'com.google.firebase:firebase-messaging:9.4.0'
b72_39Các em chép cho đúng rồi nhấn Sync Now, chỗ Thấy khoanh tròn.

Như vậy sau khi Sync Now hoàn tất, ta quay lại Console của Firebase rồi nhấn finish:

b72_37

màn hình trong console sẽ như sau:

b72_40

Các em thấy Tui khoanh đỏ góc phải bên trên của Project không, nhấn vào đó nhé:

b72_41Em chọn Manage:

 

b72_42

Em thấy màn hình trên có thông tin Project, file google-services.json để lưu lại nếu các em lúc nãy quên lưu.

Giờ em nhấn vào tab CLOUD MESSAGEING nhé:

b72_43

ở trên Tui khoanh: Server Key, Sender ID. Đây là 2 thông số quan trọng để chép vào Admin.aspx (bên trên Thầy có nói để dòng 36,37 nhớ không?

Dòng 36 chép Server Key vào

Dòng 37 chép Sender Id vào

b72_44

Em thấy đó, Mỗi 1 Project sẽ có Server Key, Sender ID khác nhau. Mỗi 1 Mobile App em nên tạo 1 Firebase app nhé. Dĩ nhiên miễn phí thì chỉ tối đa 10 app thì phải. Em nhớ chép cho đúng vào Admin.aspx của em.

  • Bây giờ ta tiến hành xây dựng Mobile App để nó có thể nhận được Token và Push Message từ Firebase:

b72_45

trước tiên ta tạo lớp đa tiến trình FireBaseIDTask để lưu token vào CSDL riêng của ta do Firebase gửi về cho từng thiết bị:

<pre>package com.tranduythanh.fcmclient;

import android.os.AsyncTask;
import android.util.Log;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by cafe on 11/08/2016.
 */

public class FireBaseIDTask extends AsyncTask<String,Void,Boolean>
{
    @Override
    protected Boolean doInBackground(String... params) {
        try
        {
            URL url=new URL("http://http://192.168.11.93/hocfcm/api/fcm/?token="+params[0]);
            HttpURLConnection connection= (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type","application/xml;charset=UTF-8");
            InputStream inputStream=connection.getInputStream();
            InputStreamReader inputStreamReader=new InputStreamReader(inputStream,"UTF-8");
            BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
            StringBuilder builder=new StringBuilder();
            String line=bufferedReader.readLine();
            while (line!=null)
            {
                builder.append(line);
                line=bufferedReader.readLine();
            }
            boolean kt=builder.toString().contains("true");
            return kt;
        }
        catch (Exception ex)
        {
            Log.e("LOI",ex.toString());
        }
        return null;
    }

    @Override
    protected void onPostExecute(Boolean aBoolean) {
        super.onPostExecute(aBoolean);
    }
}</pre>

Với Firebase ta phải có 2 Service để hoạt động: Serivice tự động lắng nghe Token cho từng thiết bị và Service tự động lắng nghe Push Message, cách làm như sau:

  • đầu tiên là Service tự động lắng nghe Token:

b72_46

Lớp này Thầy đặt tên là: MyFirebaseIDService kế thừa từ FirebaseInstanceIdService, chi tiết coding:

<pre>package com.tranduythanh.fcmclient;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;

/**
 * Created by cafe on 11/08/2016.
 */

public class MyFirebaseIDService extends FirebaseInstanceIdService {
    @Override
    public void onTokenRefresh() {
        super.onTokenRefresh();
        String token= FirebaseInstanceId.getInstance().getToken();
        luuTokenVaoCSDLRieng(token);
    }

    private void luuTokenVaoCSDLRieng(String token) {
        new FireBaseIDTask().execute(token);
    }
}</pre>

Các em để ý hàm onTokenRefresh thường chỉ chạy 1 lần, khi nào có sự thay đổi mới thì nó mới chạy tiếp(tự động). Nên nhiều lúc vì lý do gì đó lần đầu chạy lấy được token nhưng lại không lưu vào được CSDL riêng do ta xây dựng, nên có thể mất token của thiết bị này (Để nó chạy lại ta thường phải clear cache, clear data, uninstall ứng dụng này ra khỏi thiết bị. Nhưng chú ý máy của Khách hàng làm sao ta làm được thao tác này?). Do đó chút nữa chúng ta sẽ xử lý trường hợp này sau nhé.

  • Tiếp theo là Service tự động lắng nghe Push Message:

b72_47

Tui đặt lớp này là: MyFirebaseMessagingService kế thừa từ FirebaseMessagingService

Khi có Push Message nó sẽ tự động thông báo cho khách hàng. Chú ý rằng ở đây có 2 kênh gửi Push Message

b72_48

  • Kênh thứ 1: Gửi trực tiếp từ Console Firebase:

b72_49

Ta nhấn mục Notification mà Tui đánh dấu là số 1, nhìn góc phải bên trên Tui có đánh số 2 (New Message), Muốn gửi Push Message thì ta nhấn vào đây. Đồng thời nhìn danh sách phía bên dưới là Tui đã demo ứng dụng thành công hàng loạt các Push Message.

Khi nhấn vào New Message:

b72_50

Mục số 1: nhập nội dung thông báo

Mục số 2: Tiêu đề

Mục số 3: Nhấn vào chọn package để gửi thông báo.

Mục số 4: Nhân SEND MESSAGE

Khi nhấn SEND MESSAGE, hệ thống sẽ xử lý, và gửi thông tin tới toàn bộ các thiết bị được cung cấp token ứng với Package này.

Ngoài ra ta có thể chọn từng Token để gửi nhé (chọn Single Device)

  • Kênh thứ 2: Do Lập trình viên của ta định nghĩa, cụ thể là web: Admin.aspx mà ta đã lập trình bên trên:

b72_51

Dĩ nhiên là giờ cả 2 kênh chưa sử dụng được, vì Ta đã viết xong ứng xong FCMClient đâu.

Như vậy các em đã nắm được có 2 kênh gửi Push Message. Giờ ta tiến hành coding cho MyFirebaseMessagingService này nhé:

<pre>package com.tranduythanh.fcmclient;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

/**
 * Created by cafe on 11/08/2016.
 */

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        if(remoteMessage.getNotification()!=null)
        {
            hienThiThongBao(remoteMessage.getNotification().getBody());
        }
        hienThiThongBao(remoteMessage.getData().get("body"),remoteMessage.getData().get("title"));
    }
    private void hienThiThongBao(String body,String title) {
        Intent intent=new Intent(this,MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent=PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
        Uri sound= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder builder=new NotificationCompat.Builder(this)
                .setSmallIcon(android.R.drawable.ic_dialog_alert)
                .setContentTitle(title)
                .setContentText(body)
                .setAutoCancel(true)
                .setSound(sound)
                .setContentIntent(pendingIntent);
        NotificationManager manager= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.notify(0,builder.build());
    }
    private void hienThiThongBao(String body) {
        hienThiThongBao(body,"google");
    }
}</pre>

Như vậy là Ta đã coding xong cả 2 Service tự động lắng nghe nhận Token và nhận Push Message. Bây giờ ta cần cấu hình 2 Serivce này trong Manifest để nó có thể tự động lắng nghe được khi Khách hàng cài app của ta:

<pre><?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tranduythanh.fcmclient">
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".MyFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>
        <service android:name=".MyFirebaseIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>
    </application>

</manifest></pre>

Để ý Manifest có cấp phép sử dụng Internet, có 2 Service lắng nghe token và push message

  • Cuối cùng ta vào lớp MainActivity để xử lý lấy token (trường hợp mà Tui nó bị cái gì đó không lưu được)
<pre>package com.tranduythanh.fcmclient;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessaging;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FirebaseMessaging.getInstance().subscribeToTopic("testfcm");
        String token= FirebaseInstanceId.getInstance().getToken();
        new FireBaseIDTask().execute(token);
    }
}</pre>

ở coding trên, luôn luôn chạy khi App được mở lên, đa tiến trình của ta kiểm tra nó tồn tại hay không thì lưu vào CSDL (vì như Tui giải thích là onTokenRefresh chỉ chạy 1 lần (chạy lại khi có token mới). Nên nếu vì lý do gì đó không lưu được lần đầu, thì các lần sau vẫn lưu được.

==>Bây giờ các em chạy Ứng dụng FCMCLient này vào thiết bị, thì ta lưu được Token do Firebase gửi về như hình dưới đây:

b72_52

Vào admin.aspx để gửi thông báo tới toàn bộ thiết bị mà cài đặt phần mềm của ta:

b72_53Ở trên em thấy nó báo thành công 2, thất bại 5 không… Như vậy Token nào đúng thì nó sẽ gửi được em nhé

Tới đây em có thể test gửi Message trực tiếp từ console của firebase được rồi nhé.

Khi các em test OK thì sẽ có kết quả như sau:

b72_54

Như vậy là Tui đã hướng dẫn đầy đủ và chi tiết từ A-z cách xây dựng Firebase Cloud Message(FCM) rồi nhé. Các em nhớ làm lại nhiều lần. Có source code ở đầu bài này các em có thể lấy nó tham khảo.

Chúc các em thành công.

Bài 71: Xây dựng Web Service dùng API RESTful Service(phần 4)


Trong bài bài 68bài 69bài 70 các bạn đã hiểu được RESTful cũng như cách thức hoạt động của HttpPost, HttpGet, HttpPut và HttpDelete. Tuy nhiên để tương tác được với nó thì cần cấu hình lên Webserver, cụ thể là IIS, trước đây Tui có hướng dẫn các bạn cách tạo lên somee.com, các bạn có thể xem lại bài hướng dẫn này ở đây

Trong bài này Tui sẽ hướng dẫn các bạn từng bước cài đặt lên IIS Server ở máy local của các bạn, việc test trên máy local cũng khá quan trọng vì khi test hoàn chỉnh xong thì ta mới publish ra ngoài.

Dưới đây là chi tiết từng bước cách dựng IIS Server và cách triển khai FoodServer lên IIS này (Tui setup trên Win 10, 64 bit)

Bước 1: Vào Control panel chọn Programs and Features

h71-0Bước 2: Chọn Turn Windows features on or off:

h71-1Bước 3: Tiến hành lựa chọn để cài IIS Web Server theo màn hình dưới đây:

h71-2Sau khi lựa chọn giống như khung khoanh màu đỏ, nhấn OK để tiến hành cài đặt, tùy thuộc vào máy mà chương trình có thể cài từ 5-10 phút.

Bước 4: Sử dụng IIS Web Server:

Sau khi cài xong IIS Web Server, bạn quay lại màn hình Control panel, bạn sẽ thấy Administrative Tools:

h71-3Bạn click vào biểu tượng Administrative Tools, ta có giao diện tiếp theo:

h71-4Bạn chọn “Internet Information Services (IIS) Manager” như hình trên:

h71-5Trong màn hình quản trị bạn thấy có 2 vùng: Application Pools và Default Web site.

Bước 4.1 Cấu hình Application Pools:

Application Pool là gì?
Application Pool có thể chứa một hoặc nhiều ứng dụng và cho phép chúng ta cấu hình cấp độ giữa các ứng dụng web khác nhau. Ví dụ, nếu bạn muốn cô lập tất cả các ứng dụng web chạy trong cùng một máy, bạn có thể làm điều này bằng cách tạo ra Application Pool riêng biệt cho mỗi ứng dụng web và đặt chúng trong Application Pool tương ứng. Bởi vì mỗi Application Pool chạy trong quá trình làm việc riêng của mình, các lỗi trong Application Pool sẽ không ảnh hưởng đến các ứng dụng đang chạy trong Application Pool khác. Triển khai ứng dụng trong Application Pool là lợi thế chính của IIS trong quá trình làm việc ở chế độ cách ly bởi vì bạn có thể tùy chỉnh Application Pool để đạt được cấp độ tách biệt ứng dụng mà bạn cần.
Khi bạn cấu hình Application Pool để sẵn sàng tối ưu, bạn cũng nên xem xét làm thế nào để cấu hình Application Pool bảo mật ứng dụng. Ví dụ, bạn có thể cần phải tạo ra Application Pool riêng cho ứng dụng đòi hỏi mức độ bảo mật cao, trong khi cho phép các ứng dụng đòi hỏi một mức độ thấp hơn của bảo mật để chia sẻ cùng Application Pool.
Bạn bấm chuột phải vào màn hình Application Pools/ chọn Add Application Pool… như hình dưới đây:h71-6Màn hình tạo mới Application Pool hiển thị lên, ta nhập “FoodServer_Pool” rồi bấm OK:
h71-7Sau khi bấm OK, bạn quan sát:
h71-8Ở màn hình trên bạn tiếp tục chọn Advanced Settings.. cho FoodServer_Pool:
h71-9Bạn cần chỉnh ApplicationPoolIdentity qua LocalSystem.
Bước 4.2: Cấu hình WebService lên IIS Server
Bấm chuột phải vào Default Web Site / chọn Add Application
h71-10
Màn hình hiển thị Add Application:
h71-11Mục Alias (1): Đặt tên cho Service, ở đây ta đặt foodserver
Mục Application pool (2): Nhấn nút Select… và chọn đúng FoodServer_Pool
Mục Physical path (3): Trỏ tới đường dẫn chứa source code của project
Sau đó bấm OK để tạo.
Bạn quan sát kết quả:
h71-12http://localhost/foodserver/api/food chính là kết quả sau khi cấu hình xong. Tới đây hệ thống đã chạy 24/24.
Các bạn có thể dùng Postman và HttpRequester để test HttpPost, HttpGet, HttpPut và HttpDelete.
Các bạn chú ý rằng khi từ Mobile kết nối tới Web Service này thì không thể dùng localhost (vì nó lầm tưởng là của chính mobile), đo dó bạn cần đưa localhost về 1 địa chỉ IP để test.
Cách lấy địa chỉ IP của máy local của ta:
– Nhấn tổ hợp phím có biểu tượng Windows + R để mở cửa sổ Run:
h71-13– gõ lệnh cmd, màn hình command line hiển thị lên, tiếp tục gõ lệnh ipconfig
h71-14Ở trên máy local của Tui có địa chỉ IP: 192.168.100.3
Bây giờ Tui thay thế cho localhost:
h71-15Như vậy ta cũng có được kết quả mong muốn.
Các bạn cố gắng cấu hình để được kết quả như trên.
Bài sau Tui sẽ hướng dẫn cách tương tác từ Mobile Android lên RESTful WebService, các bạn chú ý theo dõi.
Chúc các bạn thành công!

Bài 70: Xây dựng Web Service dùng API RESTful Service(phần 3)


Trong bài này Tui hướng dẫn các bạn cách sử dụng 2 công cụ HttpRequester (firefox addon) và Postman (chrome addon) . Các bạn cần nắm rõ bài 68bài 69 để hiểu và triển khai được Web API RESTful.

  1. Cách sử dụng HttpRequester.

Bạn mở trình duyệt Firefox, vào google tìm từ khóa “httprequester addon” hoặc vào link: https://addons.mozilla.org/en-US/firefox/addon/httprequester/, bạn nhấn Add to Firefox:

h70-0Bạn tiến hành cài, cài xong khởi động lại trình duyệt Firefox, nhìn vào góc phải trên cùng trình duyệt:

h70-1Bạn bấm vào biểu tượng đó, chương trình HttpRequester sẽ xuất hiện như hình dưới đây:

h70-2Mục URL: Nhập URL Web API của bạn vào (http://localhost:8888/api/food). Bạn nhấn GET, chương trình sẽ lấy toàn bộ danh sách Food vào màn hình bên phải (bạn quan sát sẽ thấy).

Để Test lấy 1 Food theo mã nào đó bạn làm như sau:

h70-3Bạn vào tab Parameters, nhập tên biến + giá trị rồi nhấn Add. Sau đó bấm nút GET để lấy dữ liệu, như bạn quan sát đó Tui nhập id=15 thì chương trình lấy ra được Food “Hột mít vùi tro”.

-Test HTTP POST:

h70-4Đối với POST bạn cũng vào Parameters, nhập đủ parameters (phải giống như viết trong Web API), sau đó nhấn nút “POST”, bạn thấy kết quả trả về là true—> tức là thêm thành công. Bạn có thể test lại chức năng HTTP GET để xem lại kết quả thêm mới này.

Trường hợp PUT tương tự bạn tự làm.

Giờ Tui làm tiếp trường hợp Delete:

h70-5Trong combobox, bạn chọn DELETE, nhập Parameter rồi bấm Submit, thấy kết quả là true==> xóa thành công.

2.Cách sử dụng Postman.

Mở trình duyệt Chrome, tìm từ khóa “postman plugin”, hoặc https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en tiến hành cài đặt, sau khi cài thành công:

h70-6Kích hoạt postman để sử dụng.

Để lấy toàn bộ dữ liệu (HttpGet) ta chọn Get như hình dưới đây:

h70-7Để lấy 1 Food theo mã ta làm theo các bước dưới đây (Ví dụ lấy Food có id=1):h70-8Để sử dụng HttpPost (tạo Food mới) ta làm theo các bước dưới đây:

h70-9Ở trên khi bấm Send, trả về true==> thêm Food thành công.

Để xóa một Food có mã bất kỳ:

h70-10Trên đây là cách sử dụng HttpRequesterPostman, 2 công cụ này rất hiệu quả giúp chúng ta kiểm tra quá trình thực hiện HttpPost,HttpGet,HttpPut,HttpDelete trước khi triển khai vào hệ thống thực.

Chúc các bạn thành công.

Bài 69: Xây dựng Web Service dùng API RESTful Service(phần 2)


Trong bài này Tui sẽ hướng dẫn chi tiết cách tạo Web API (lý thuyết ở đây), cách cấu hình IIS, cách sử dụng công cụ Postman(với những ai dùng chrome), cách sử dụng HttpRequester (với những ai dùng Firefox). PostmanHttpRequester là một trong những công cụ hiệu quả nhất để TEST coding của ta, nếu code của ta pass qua được công cụ này thì có thể kết luận rằng Webservice của ta chắc chắn hoạt động tốt.

Để cho có cảm giác Tui sẽ tạo một cơ sở dữ liệu SQL Server, WebAPI sẽ tương tác dữ liệu này bằng cách sử dụng LinQ to SQL:

Bước 1: Tạo cơ sở dữ liệu tên “dbFood”, có một bảng “Food” gồm 4 cột (id để auto) như dưới đây:

h69-0Các bạn có thể tải SQL Script ở đây để tạo CSDL cho lẹ: http://www.mediafire.com/download/48dkwoqka2e1w07/dbFood.sql

Bước 2: Tiến hành viết Web API

Để tạo Project sử dụng Web API có nhiều cách tạo, ở đây Tui sử dụng cách đơn giản nhất để các bạn bớt rối.

Từ Visual Studio 2013 vào menu File/chọn new/ chọn Project:

h69-1Sau khi chọn Project, màn hình sau xuất hiện:

h69-2Chọn các cấu hình như trên, đặt tên Project là “FoodServer” rồi nhấn OK.

Project mặc định ban đầu như sau:

h69-3Giờ ta tiến hành tạo LinQ to SQL cho CSDL dbFood để dễ xử lý như sau:

Bấm chuột phải vào Project/ chọn :

h69-4Màn hình tạo tên LINQ to SQL hiển thị lên, ta tạo tên rồi nhấn OK:

h69-5(chú ý đôi khi bạn sẽ không thấy LINQ to SQL Classes ở màn hình này), nếu không thấy thì chọn New Item:

h69-6Ta chọn các mục giống như bên dưới, tìm tới LINQ to SQL Classes rồi đặt tên DBFood tương tự như trên:

h69-7Cả 2 cách cuối cùng cũng trạo được DBFood LINQ như sau:

h69-8– Ta tiến hành cấu hình để kéo Cơ sở dữ liệu vào làm các lớp tương tác:

Bạ mở Server Explorer (vào menu View/Server Explorer), bấm chọn theo các bước như bên dưới (lệ thuộc vào Server của bạn mà chọn Server name, User đăng nhập cho phù hợp):

h69-9Khi khi bấm OK, bạn sẽ thấy Server Explorer có thêm mục sau:

h69-10Bạn kéo thả bảng Food vào mục bên phải như hình trên.

Tiếp theo bạn tạo 1 thư mục (tên gì cũng được), ở đây Tui đặt đại tên Controllers (bấm chuột phải vào Project/chọn Add/chọn New Folder):

h69-11Sau khi thư mục Controllers được tạo ra, bạn bấm chuột phải vào Thư Mục này rồi chọn Add/Controller..:

h69-12Sau khi bạn chọn Controller… màn hình sau xuất hiện:

h69-13Ta chọn Web API 2 Controller – Empty rồi bấm Add, Visual sẽ hiển thị màn hình đặt tên cho Controller:

h69-14Mặc định là chữ Default, bây giờ bạn đổi lại thành Food (thường ta làm API cho bảng nào thì lấy tên bảng đó), đó là lý do vì sao Tui đặt là Food:

h69-15Tập tin FoodController.cs sẽ được tạo ra, nhưng ta chỉ lấy Food(bỏ chữ Controller đằng sau đi) để tương tác (đây là cơ chế hoạt động). Ta xem cấu trúc Controller được tạo ra:

h69-16Cấu trúc có gì?

  • File WebApiConfig.cs được sinh ra trong thư mục App_Start, bạn để ý  routeTemplate: “api/{controller}/{id}”, tức là khi ta dùng thì viết: “api/food” để lấy toàn bộ danh sách, hay “api/food/3” để lấy chi tiết  1 Food có mã là 3.
  • File FoodController.cs kế thừa từ ApiController

Bây giờ ta tiến hành viết các chức năng (viết trong file FoodController.cs) :

  • HttpGet: Truy vấn thông tin
  • HttpPost: Thêm mới thông tin
  • HttpPut: Thay đổi thông tin
  • HttpDelete: Xóa thông tin

Trước tiên ta làm HttpGet:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace FoodServer.Controllers
{
public class FoodController : ApiController
{
///

<summary>
/// Dịch vụ lấy toàn bộ Food
/// </summary>


/// <returns></returns>
[HttpGet]
public List<Food> GetFoodLists()
{
DBFoodDataContext db = new DBFoodDataContext();
return db.Foods.ToList();
}
///

<summary>
/// Dịch vụ lấy 1 Food theo khóa chính nào đó
/// </summary>


/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public Food GetFood(int id)
{
DBFoodDataContext db = new DBFoodDataContext();
return db.Foods.FirstOrDefault(x => x.id == id);
}
}
}

Chú ý là Web API nó không quan tâm tới tên phương thức (viết tên gì cũng được, nó tự động lấy chính xác Service yêu cầu), (không cho phép trùng tên biến). Ví dụ nếu bạn cố tình tạo thêm 1 hàm:


[HttpGet]
public Food GetFood_test(int id)
{
DBFoodDataContext db = new DBFoodDataContext();
return db.Foods.FirstOrDefault(x => x.id == id);
}

Khi chạy sẽ báo lỗi ngày (vì hệ thống không quan tâm tên hàm), nó thấy 2 biến id giống nhau ở trên 2 hàm nó sẽ không biết dùng cái nào (vì chúng cùng nhóm HttpGet). Cụ thể là lỗi sau:

Multiple actions were found that match the request:
GetFood on type FoodServer.Controllers.FoodController
GetFood_test on type FoodServer.Controllers.FoodController

Tiếp theo ta viết HttpPost (thêm mới):


///

<summary>
/// Dịch vụ này để thêm mới 1 Food, các thông số gửi từ client lên
/// </summary>


/// <param name="name">tên </param>
/// <param name="type">loại-nhóm</param>
/// <param name="price">đơn giá</param>
/// <returns>true thành công, false thất bại</returns>
[HttpPost]
public bool InsertNewFood(string name,string type,int price)
{
try
{
DBFoodDataContext db = new DBFoodDataContext();
Food food = new Food();
food.name = name;
food.type = type;
food.price = price;
db.Foods.InsertOnSubmit(food);
db.SubmitChanges();
return true;
}
catch
{
return false;
}
}

Để chỉnh sửa thông tin ta viết HttpPut:


///

<summary>
/// Dịch vụ chỉnh sửa thông tin
/// </summary>


/// <param name="id">mã food muốn sửa</param>
/// <param name="name">tên mới</param>
/// <param name="type">loại mới</param>
/// <param name="price">giá mới</param>
/// <returns></returns>
[HttpPut]
public bool UpdateFood(int id,string name,string type,int price)
{
try
{
DBFoodDataContext db = new DBFoodDataContext();
//lấy food tồn tại ra
Food food = db.Foods.FirstOrDefault(x=>x.id==id);
if (food == null) return false;//không tồn tại false
food.name = name;
food.type = type;
food.price = price;
db.SubmitChanges();//xác nhận chỉnh sửa
return true;
}
catch
{
return false;
}
}

Cuối cùng để xóa 1 Food ta viết HttpDelete như sau:


///

<summary>
/// Dịch vụ dùng để xóa Food có id
/// </summary>


/// <param name="id">id muốn xóa</param>
/// <returns></returns>
[HttpDelete]
public bool DeleteFood(int id)
{
DBFoodDataContext db = new DBFoodDataContext();
//lấy food tồn tại ra
Food food = db.Foods.FirstOrDefault(x => x.id == id);
if (food == null) return false;
db.Foods.DeleteOnSubmit(food);
db.SubmitChanges();
return true;
}

Sau cùng ta có coding tổng hợp của FoodController như sau:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace FoodServer.Controllers
{
public class FoodController : ApiController
{
///

<summary>
/// Dịch vụ lấy toàn bộ Food
/// </summary>


/// <returns></returns>
[HttpGet]
public List<Food> GetFoodLists()
{
DBFoodDataContext db = new DBFoodDataContext();
return db.Foods.ToList();
}
///

<summary>
/// Dịch vụ lấy 1 Food theo khóa chính nào đó
/// </summary>


/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public Food GetFood(int id)
{
DBFoodDataContext db = new DBFoodDataContext();
return db.Foods.FirstOrDefault(x => x.id == id);
}
///

<summary>
/// Dịch vụ này để thêm mới 1 Food, các thông số gửi từ client lên
/// </summary>


/// <param name="name">tên </param>
/// <param name="type">loại-nhóm</param>
/// <param name="price">đơn giá</param>
/// <returns>true thành công, false thất bại</returns>
[HttpPost]
public bool InsertNewFood(string name,string type,int price)
{
try
{
DBFoodDataContext db = new DBFoodDataContext();
Food food = new Food();
food.name = name;
food.type = type;
food.price = price;
db.Foods.InsertOnSubmit(food);
db.SubmitChanges();
return true;
}
catch
{
return false;
}
}
///

<summary>
/// Dịch vụ chỉnh sửa thông tin
/// </summary>


/// <param name="id">mã food muốn sửa</param>
/// <param name="name">tên mới</param>
/// <param name="type">loại mới</param>
/// <param name="price">giá mới</param>
/// <returns></returns>
[HttpPut]
public bool UpdateFood(int id,string name,string type,int price)
{
try
{
DBFoodDataContext db = new DBFoodDataContext();
//lấy food tồn tại ra
Food food = db.Foods.FirstOrDefault(x=>x.id==id);
if (food == null) return false;//không tồn tại false
food.name = name;
food.type = type;
food.price = price;
db.SubmitChanges();//xác nhận chỉnh sửa
return true;
}
catch
{
return false;
}
}
///

<summary>
/// Dịch vụ dùng để xóa Food có id
/// </summary>


/// <param name="id">id muốn xóa</param>
/// <returns></returns>
[HttpDelete]
public bool DeleteFood(int id)
{
DBFoodDataContext db = new DBFoodDataContext();
//lấy food tồn tại ra
Food food = db.Foods.FirstOrDefault(x => x.id == id);
if (food == null) return false;
db.Foods.DeleteOnSubmit(food);
db.SubmitChanges();
return true;
}
}
}

Bây giờ ta tiến hành cấu hình Port để test trên IIS express hoặc bạn cấu hình IIS full. Trong bài này Tui hướng dẫn cách sử dụng IIS Express.

Bạn bấm chuột phải vào FoodServer Project/ chọn Properties:

h69-17Tại màn hình Properties / chọn mục Web:

h69-18Bạn cấu hình như trên, Port tui chỉnh là 8888, bạn chọn Port nào cũng được, nhưng thường là 4 chữ số.

Sau đó bấm Create Virtual Directory:

h69-19Nếu Visual thông báo màn hình trên coi như bạn thành công.

Bây giờ ta thử chức năng HttpGet để lấy toàn bộ Food và lấy 1 Food theo id bất kỳ:

F5 để chạy Project:

h69-20Bạn chỉnh lại: http://localhost:8888/api/food để lấy toàn bộ Food:

h69-21Để lấy 1 Food có mã bất kỳ:

Ví dụ: Lấy Food có mã id=15: http://localhost:8888/api/food/15

h69-22Hoặc: http://localhost:8888/api/food?id=15

h69-23Ta cần phải biết các công cụ để test HttpGet,HttpPost,HttpPutHttpDelete.

Bài kế tiếp Tui sẽ hướng dẫn cách dùng công cụ Postman và HttpRequester để xử lý 4 tác vụ trên.

Bây giờ các bạn hãy làm theo hướng dẫn này để có thể tạo được 1 Web API hoàn chỉnh, test trước phần HttpGet mà Tui đã trình bày ở trên trước.

Các bạn tải source code FoodServer ở đây: http://www.mediafire.com/download/c24sm4hg19v8grz/FoodServer.rar

Chúc các bạn thành công.

Bài 68: Xây dựng Web Service dùng API RESTful Service(phần 1)


Nếu bạn nào muốn rèn luyện thêm lập trình Java, lập trình Android, lập trình Webservice với tổng thời lượng học >80 giờ thì có thể đăng ký học theo các link sau:

1) Lập trình java trong 4 tuần – 19 giờ(chỉ dành cho những ai CHƯA BIẾT GÌ VỀ LẬP TRÌNH hoặc đã biết lơ mơ về Java, lý thuyết và các bài tập phong phú tạo nền tảng lập trình Android và các hướng khác liên quan tới Java):
https://kyna.vn/lap-trinh-java-trong-4-tuan/325931
2) Lập trình Android cơ bản (>24 giờ học) – toàn bộ kiến thức về Android cơ bản:
https://kyna.vn/lap-trinh-android-co-ban/325931
3) Lập trình Android nâng cao (23 giờ học) – toàn bộ kiến thức về Android nâng cao:
https://kyna.vn/lap-trinh-android-nang-cao/325931
4) Lập trình Webservice cho Di Động – 14 giờ (dành cho những ai ĐÃ BIẾT ANDROID), những ai chưa biết Android tuyệt đối không đăng ký, khóa học hướng dẫn tỉ mỉ từ A->Z để có thể xây dựng được một phần mềm hoàn chỉnh tương tác client-server:
https://kyna.vn/lap-trinh-webservice-cho-di-dong/325931

Ở các bài trước (.Net Web Service & KSOAP API) Tui có trình bày về cách tạo và sử dụng Web Service bằng .asmx, nó có một số hạn chế nhất định. Trong bài này Tui sẽ trình bày cách tạo web service dùng API RESTful Service, một nền tảng mới được hỗ trợ từ .net version 4.0 trở lên. Những bạn lập trình về thiết bị di động cần phải hiểu được các khái niệm cũng như cơ chế vận hành sử dụng API RESTful, theo Tui thấy nó khá hay và rất tiện lợi trong việc triển khai các dự án liên quan tới tương tác dữ liệu trên Server.

Trước khi triển khai webservice, các bạn cần đọc và hiểu khái niệm qua 4 mục dưới đây:

  1. Giới thiệu về ASP.NET Web API
  2. Giới thiệu cơ bản về RESTful Service
  3. Các nguyên tắc cơ bản để tạo ra RESTful Service
  4. Xây dựng Web Service

1.Giới thiệu về ASP.NET Web API

ASP.NET Web API là ?

Là framework giúp chúng ta tạo ra các Web API API trên nền web (HTTP).

Web API là các dịch vụ Web (Web service) được xây dựng dựa trên HTTP sử dụng mô hình lập trình convention (như ASP.NET MVC).

h68-0Đặc điểm Web API (.NET 4.0 trở lên)

  • Giúp cho việc xây dựng các HTTP service rất đơn giản, nhanh chóng
  • Mã nguồn mở (Open Source) và có thể được sử dụng bởi bất kì client nào hỗ trợ XML, JSON.
  • Hỗ trợ đầy đủ các thành phần HTTP: URI, request/response headers, caching, versioning, content formats.
  • Có thể host trong ứng dụng hoặc trên IIS.
  • Kiến trúc lý tưởng cho các thiết bị có băng thông giới hạn như các thiết bị di động.
  • Định dạng dữ liệu có thể là JSON, XML hoặc một kiểu dữ liệu bất kỳ.
  • Làm mới và hiện đại hóa các mẫu dự án mặc định
  • Mẫu dự án trên điện thoại di động
  • Nhiều tính năng mới để hỗ trợ các ứng dụng di động
  • Tùy chỉnh sinh mã(code).
  • Tăng cường hỗ trợ cho các phương pháp bất đồng bộ
  • Đọc danh sách đầy đủ tính năng trong các ghi chú phát hành

Ưu điểm của Web API

  • Cấu hình đơn giản hơn nhiều so với WCF.
  • Hiệu suất(performance) cao.
  • Hỗ trợ RESTfull đầy đủ.
  • Hỗ trợ đầy đủ các thành phần MVC như: routing, controller, action result, filter, model binder, IoC container, dependency injection, unit test, …
  • Mã nguồn mở (Open source).

2. Giới thiệu cơ bản về RESTful Service

-Là một dịch vụ web đơn giản sử dụng HTTP và tính chất của REST.

-Nó tuân thủ theo 4 nguyên tắc thiết kế cơ bản sau:

  • Sử dụng các phương thức HTTP một cách rõ ràng
  • Phi trạng thái
  • Hiển thị cấu trúc thư mục như URls
  • Chuyển đổi linh hoạt JavaScript Object Notation (JSON) và XML hoặc cả hai.

3. Nguyên tắc cơ bản để tạo ra RESTful Service

4 nguyên tắc thiết kế cơ bản sau:

Nguyên tắc 1: Sử dụng các phương thức HTTP một cách rõ rng

Thiết lập một ánh xạ 1-1 giữa các hành động: tạo, đọc, cập nhật và xoá (CRUD) các quá trình vận hành và các phương thức HTTP:

  • POST (HttpPost) – Tạo một tài nguyên trên máy chủ
  • GET (HttpGet) – Truy xuất một tài nguyên
  • PUT (HttpPut) – Thay đổi trạng thái một tài nguyên hoặc để cập nhật nó
  • DELETE (HttpDelete) – Huỷ bỏ hoặc xoá một tài nguyên

Nguyên tắc 2: Phi trạng thái

Ta xem mô hình giữa trạng thái và phi trạng thái để dễ so sánh:

Mô hình phi trạng thái:

h68-2Mô hình trạng thái:

h68-1Nguyên tắc 3: Hiển thị cấu trúc thư mục như URls

Cấu trúc địa chỉ của RESTful service:

  • Giấu các đuôi tài liệu mở rộng của bản gốc trong máy chủ (.jsp, .php, .asp).
  • Để mọi thứ là chữ thường (thực ra là không phân biệt, nhưng cũng nên tuân thủ để khỏi phải nhớ HOA-thường lung tung).
  • Thay thế các khoảng trống bằng gạch chân hoặc gạch nối (một trong hai loại).
  • Tránh các chuỗi yêu cầu.
  • Thay vì sử dụng mã (404 Not Found) khi yêu cầu địa chỉ cho một phần đường dẫn thì luôn luôn cung cấp một trang mặc định hoặc tài nguyên như một phản hồi.

Nguyên tắc 4: Chuyển đổi JavaScript Object Notation (JSON) và XML hoặc cả hai.

  • Là một bản tóm tắt các thuộc tính của những thứ trong mô hình dữ liệu hệ thống.
  • Định dạng dữ liệu mà ứng dụng và trao đổi dịch vụ trong mức đáp ứng yêu cầu/ phản hồi hoặc trong phần thân của HTTP.
  • Các chủ thể trong mô hình dữ liệu có liên quan với nhau.
  • Cấu trúc dịch vụ sao cho nó tận dụng được phần đầu chấp nhận HTTP có sẵn bên trong – một loại MIME

 

4.Xây dựng Web Service

Tui liệt kê các bước tương đối (chi tiết sẽ trình bày trong bài kế tiếp):

Bước 1:

Khởi động Visual Studio → tạo một project ASP.NET Web Application và chọn template Web API.

Bước 2:

Tạo Data Model sử dụng Entity Framework để Web API service có thể tương tác CRUD (Create, Read, Update, Delete) dữ liệu được (không tạo cũng được).

Bước 3: Tạo ra các Web API

Nhấp chuột phải vào thư mục Controllers và chọn thêm controller.

  • Web API 2 Controller Empty: tự viết các phương thức từ đầu.
  • Web API 2 Controller with read/write actions: phát sinh các phương thức ví dụ để bạn có thể biết cách viết các service này.

Bước 4: Chạy thử và kiểm tra.


Bài kế tiếp Tui sẽ trình bày chi tiết cách tạo Web API service, cách cấu hình cũng như sử dụng Service.