call() và apply()

2 phương thức hữu dụng của các đối tượng function là call() và apply().

Chúng cho phép các đối tượng mượn các phương thức từ các đối tượng khác và gọi chúng ngay bên trong bản thân chúng.đây là 1 cách rất mạnh mẽ và dễ dàng để giảm thiểu mã code Ta xét ta có 1 đối tượng some_obj object, chứa 1 phương thức say()

var some_obj = {
    name: ‘Ninja’,
    say: function(who) {
          return ‘Haya ‘ + who + ‘, I am a ‘ + this.name;
    }
}
Ta có thể gọi phương thức say() như sau :
>>> some_obj.say(‘Dude’);
“Haya Dude, I am a Ninja”

Giờ ta tạo ra 1 đối tượng đơn giản my_obj, mà chỉ có 1 thuộc tính name :
>>> my_obj = {name: ‘Scripting guru’};

Bên trong đối tượng my_obj không có phương thức say() tuy nhiên ta lại muốn mược phương thức say() này từ đối tượng some_obj vào trong đối tượng my_obj thì ta làm như sau :
>>> some_obj.say.call(my_obj, ‘Dude’);

Nó đã hoạt động.nhưng chuyện gì sẽ xảy ra ? ta gọi phương thức call() của phương thức say() , 2 tham số được chuyển tiếp là đối tượng my_obj và chuỗi ‘Dude’.kết quả khi phương thức say() được gọi, thì có tham chiếu tới đối tượng this, khi này đối tượng this chỉ
tới đối tượng my_obj.do vậy this.name không trả về Ninja nhưng lại trả về

Scripting guru
Nếu ta có nhiều hơn các tham số được chuyển tiếp vào khi gọi phương thức call(), thì cứ việc chuyển tiếp chúng :
some_obj.someMethod.call(my_obj, ‘a’, ‘b’, ‘c’);

nếu ta không chuyển tiếp 1 đối tượng như 1 tham số đầu tiên bên trong call() hay là null, thì đối tượng toàn cục sẽ được giả định phương thức appy() là việc giống với cách của call() nhưng với 1 chút khác biệt là tất cả các tham số mà ta muốn chuyển tiếp vào phương thức của 1 đối tượng khác thì chúng phải được chuyển tiếp như 1 mảng như ví dụ sau :
some_obj.someMethod.apply(my_obj, [‘a’, ‘b’, ‘c’]);

some_obj.someMethod.call(my_obj, ‘a’, ‘b’, ‘c’);

hay như làm trong ví dụ trên :
>>> some_obj.say.apply(my_obj, [‘Dude’]);

“Haya Dude, I am a Scripting guru”

Cài đặt node.js, RabbitMQ trên Centos 6.3

Ghi nhớ thao tác cài đặt node.js trên CentOS 6.3

Cài đặt node.js

Image

$ cd /tmp
$ wget -N http://nodejs.org/dist/node-latest.tar.gz
$ tar xzvf node-latest.tar.gz ← giải nén
$ cd node-v0.x.xx ← chuyển đến thư mục node.js đã giải nén
$ make
$ sudo make install
$ node -v ←Kiểm tra version

Đoạn make và make install hơi lâu một tý. 🙁

Kiểm tra version của NPM ( Node Package Manager)

$ npm -v

Update Python nếu cần thiết

    Traceback (most recent call last):
      File "tools/waf-light", line 157, in ?
        import Scripting
      File "/home2/rianders/src/node/tools/wafadmin/Scripting.py", line 9, in ?
        import Utils, Configure, Build, Logs, Options, Environment, Task
      File "/home2/rianders/src/node/tools/wafadmin/Build.py", line 18, in ?
        import Runner, TaskGen, Node, Scripting, Utils, Environment, Task, Logs, Options
      File "/home2/rianders/src/node/tools/wafadmin/TaskGen.py", line 54, in ?
        class task_gen(object):
      File "/home2/rianders/src/node/tools/wafadmin/TaskGen.py", line 87, in task_gen
        traits = Utils.DefaultDict(set)
    NameError: name 'set' is not defined
    make: *** [program] Error 1

Trường hợp Python cài bằng yum (vesion  2.6) không thực hiện được make thì update lên version mới.

Cài đặt các thư viện cho python 2.7.3
$ sudo yum install gcc-c++ zlib zlib-devel tk-devel tcl-devel sqlite-devel 
ncurses-devel gdbm-devel readline-devel bzip2-devel db4-devel openssl-devel
Cài đặt python
$ cd /tmp
$ wget http://python.org/ftp/python/2.7.3/Python-2.7.3.tgz
$ tar zxvf Python-2.7.3.tgz
$ ./configure --with-threads --enable-shared $ make $ sudo make install
$ ln -s /usr/local/lib/libpython2.7.so.1.0 /lib64/
$ python

Cài đặt RabbitMQ

$ wget -O /etc/yum.repos.d/epel-erlang.repo http://repos.fedorapeople.org/repos/peter/erlang/epel-erlang.repo
$ sudo wget -O /etc/yum.repos.d/epel-erlang.repo http://repos.fedorapeople.org/repos/peter/erlang/epel-erlang.repo
$ sudo yum install erlang
 Cài đặt RabbitMQ
$ wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.0.4/rabbitmq-server-3.0.4-1.noarch.rpm
$ sudo rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
$ sudo  yum install rabbitmq-server-3.0.4-1.noarch.rpm

Khởi động và kích hoạt màn hình quản lý

$ sudo service rabbitmq-server start
$ sudo rabbitmq-plugins enable rabbitmq_management
$ sudo service rabbitmq-server restart
Chú ý: RabbitMQ mặc định đòi hỏi phải có dung lượng disk còn trống khoảng 1GB để hoạt động ( http://www.rabbitmq.com/configure.html)
  • /etc/rabbitmq/rabbitmq.config
  • Mặc định disk_free_limit Default: 1000000000 tỉ lệ với dung lượng memory {mem_relative, 1.0}
  • Nếu trường hợp không đủ dung lượng ổ cứng thì có thể set mem_relative tầm 0.5 hay bé hơn.
Màn hình quản lý rabbitMQ

http://localhost:15672/

Tạo đây có thể xem tình trang hoạt động và thiết định các Channel, exchange, queue, ….

của rabbitmq

 

 

 

 

TÌm hiểu cấu trúc dữ liệu request và response cho GCM.

Lần trước mình đã tìm hiểu cơ bản về Google  Cloud Message for Android (GCM).
http://tuantranf.wordpress.com/2013/04/16/android-notification-by-nodejs-1-google-cloud-messaging-for-android/
Tool hỗ trợ: Một add-on của chrome dùng để thực hiện request.
DEV HTTP CLIENT
Cottonballs:
Server giả lập trên local host để thay thế cho GCM. Thay vì gửi message đến GCM có thể gửi đến cottonballs để test.Ngoài ra có các chức năng tạo delay, failure để test.
Hôm nay mình sẽ tìm hiểu kĩ hơn về cấu trúc dữ liệu khi tạo request và giải mãi response từ server của GCM trước khi bắt tay vào thiết kế ứng dụng.
Nguồn http://developer.android.com/google/gcm/gcm.html

Cấu trúc dữ liệu request

Header của HTML

  • Authorization: key=YOUR_API_KEY
  • Content-Type:
    •  application/json (Nếu request là JSON)
    •  application/x-www-form-urlencoded;charset=UTF-8 (nếu request là plain text)

Cụ thể nội dung của Header sẽ như sau.(Vì mình chỉ dùng Json nên sẽ lược bỏ phần chú thích về plain text.

Content-Type:application/json
Authorization:key=AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA

Về dữ liệu JSON gửi đi:

{
// ID đăng ký của các device cần gửi (được quản lý trong DB)
"registration_ids":["4", "8", "15", "16", "23", "42"],
// Một số thiết định khác
// Tên group dùng để nhóm các notification cùng nhóm lại với nhau.
"collapse_key": "update",
// Thời gian sống sót của message trên server GCM khi failure do device offline.Mặc định là 4 tuần.
"time_to_live": 180,
// Đợi đến khi device idle thì mới gửi
"delay_while_idle": true,
// Tên package khi chỉ định chỉ gửi cho các device có pakage này
"restricted_package_name": "package_name",
// chế độ dryrun để test.
"dry_run": false,
// Dữ liệu cần gửi
"data": {
"score": "4x8",
"time": "15:16.2342"
}
}

Chú ý: Tổng kích thước của một lần gửi (RegistrationIDs + Options + Data) giới hạn là 4kb, khi số lượng Registration IDs càng nhiều thì dung lượng data giới hạn lại càng bé đi.

Giải mã GCM Response

Status code trả về khi gửi message
200 Message được xử lý thành công (POST OK).Thực tế có push đến từng device hay không thì ??? 🙁
Khi gửi thành công thì sẽ trả về thông tin của message.
400 Xử lý JSON đã gửi trướng hợp parse request thất bại, hoặc thiếu các mục yêu cầu trong JSON, phải sửa lại JSOn trước khi thử lại
401 Có lỗi thì xử ly đăng nhập, xác nhận của ID người gửi (YOUR_API_KEY)
5xx Các lỗi trong khoảng 500-599  lỗi của server GCM khi thực hiện request và sẽ thử lại nếu Header thiết định parameter Retry-After
Nội dung GCM response// Trường hợp gửi message đến 6 ID (IDs 4, 8, 15, 16, 23, và 42)
// 3 messages thành công , 3 thất bại ta sẽ có response JSON như sau
{"multicast_id": 216, // ID của message
"success": 3, // Số lượng xử lý thành công
"failure": 3, // Số lượng xử lý thất bại
"canonical_ids": 1, // ID of the last registration requested by your application là ID đăng ký cuối cùng trường hợp 1 device đăng ký nhiều ID
"results": [ // Kết quả gửi message
{ "message_id": "1:0408" }, // Message id 1 thành công , không cần gì (ID4)
{ "error": "Unavailable" },  // Cần gửi lại (ID8)
{ "error": "InvalidRegistration" }, // Lỗi dữ liệu đăng ký (ID15)
{ "message_id": "1:1516" }, // Gửi thành công (ID16)
{ "message_id": "1:2342", "registration_id": "32" }, // Gửi thành công như có yêu cầu update registration ID từ 23->23 (ID23)
{ "error": "NotRegistered"} // Lỗi ID không đăng ký / bị xoá do remove application trên device (ID42)
]
}

Conclusion

Hôm nay mình đã tìm hiểu về cấu trúc (format) dữ liệu khi request thông tin đến GCM server và giải mã response của GCM để xử lý retry hay hiển thị lỗi.