Hôm nay ngồi coi lại Sharp-Lite chút, bữa có download về nhưng chỉ xem qua. Lần này mình tính evaluate xem có hợp lý hơn cái framework đang xài hay có gì hay hơn so với S#arp Architecture không.
Lần đầu build không sao, lần sau copy mấy thứ từ project cũ qua, thay StructureMap bằng Windsor tự nhiên gặp lỗi nhảm shit 'At least one ISessionFactory has not been registered with IoC'. Trong khi debug rõ ràng đã register rồi và code cũng chẳng đổi gì để đến nỗi sai. Search 1 vòng trên NET chỉ có 1 chỗ
Google Groups › S#arp Lite › Error while running the sample application. Mới kiểm tra lại, thiệt bó tay Init project reference MVC 4 'C:\Program Files\Microsoft ASP.NET\ASP.NET MVC 4\Assemblies\System.Web.Mvc.dll', Web project reference MVC 3 'C:\Program Files\Microsoft ASP.NET\ASP.NET MVC 3\Assemblies\System.Web.Mvc.dll'.
>>> bị lỗi reference tới 2 assembly khác nhau
2012-02-29
2012-02-14
Multiple output files from a T4 template
Lâu ngày ngồi modify lại T4 template của Subsonic. Thật ra là mình dùng cái template đó rồi modify lại để generate DTO, chứ không dùng Subsonic.
Nhìn thấy rối quá, thật ra lúc trước lười search. Search ra multiple output file solution của Damien Guard ở đây Multiple outputs from T4 made easy.
Note: file T4 bắt buộc sinh ra ít nhất 1 file, vì vậy thay vì output extension là .cs thì chuyển thành .log và ghi những thông tin cần thiết vào đây, ví dụ ngày giờ generated ... Ví dụ như sau:
// -----------------------------------------------------------------------------
// GENERATED AT <#= DateTime.Now.ToShortDateString() + ", " + DateTime.Now.ToLongTimeString() #>
// -----------------------------------------------------------------------------
<#@ template language="C#" debug="False" hostspecific="True" #>
<#@ include file="SQLServer.ttinclude" #>
<#@ include file="Manager.ttinclude"#>
<#@ output extension=".log" #>
Nhìn thấy rối quá, thật ra lúc trước lười search. Search ra multiple output file solution của Damien Guard ở đây Multiple outputs from T4 made easy.
Latest source available at GitHub
Giờ thì sẽ chỉnh lại những template đang có.Note: file T4 bắt buộc sinh ra ít nhất 1 file, vì vậy thay vì output extension là .cs thì chuyển thành .log và ghi những thông tin cần thiết vào đây, ví dụ ngày giờ generated ... Ví dụ như sau:
// -----------------------------------------------------------------------------
// GENERATED AT <#= DateTime.Now.ToShortDateString() + ", " + DateTime.Now.ToLongTimeString() #>
// -----------------------------------------------------------------------------
<#@ template language="C#" debug="False" hostspecific="True" #>
<#@ include file="SQLServer.ttinclude" #>
<#@ include file="Manager.ttinclude"#>
<#@ output extension=".log" #>
Labels:
.NET,
C#,
code generation,
DTO,
Subsonic,
T4,
T4 template,
Visual Studio
2012-02-06
Windows 7 : add Command Prompt in right click context menu
Original: http://www.blogsdna.com/2226/windows-7-add-elevated-command-prompt-option-in-right-click-context-menu.htm
cmd2folder.reg, right click on file -> Merge
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\shell\runas]
@="Command Line (Administrator)"
[HKEY_CLASSES_ROOT\Directory\shell\runas\command]
@="cmd.exe /s /k pushd \"%V\""
cmd2folder.reg, right click on file -> Merge
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\shell\runas]
@="Command Line (Administrator)"
[HKEY_CLASSES_ROOT\Directory\shell\runas\command]
@="cmd.exe /s /k pushd \"%V\""
Labels:
context menu,
run as administrator,
Windows,
Windows 7
2011-11-01
Create self-signed certificate for localhost/DEV web server (enabled https/ssl)
Để enabled SSL dùng trong flow xAuth, https://api.xxxyyy.vn/v1/oauth/access_token. Tạo môi trường test tại localhost hay server dev.
Download OpenSSL binary
1. Download OpenSSL binary http://gnuwin32.sourceforge.net/packages/openssl.htm, bản mới nhất hiện tại là openssl-0.9.8h, extract phần bin (folder bin có chức các file exe như openssl.exe) vào folder giả sử D:\ openssl-0.9.8h.
2. Tạo folder tương ứng certs, config, keys, p12, requests. Có thể chỉ dùng 1 folder cũng được
3. Tạo file text database.txt, command tương ứng là
D:\openssl-0.9.8h>copy con database.txt
^Z
4. Tạo file text serial.txt, nội dung có 1 dòng là 01
D:\openssl-0.9.8h>copy con serial.txt
01
^Z
5. Download file config openssl.cnf, search trên Google là có liền (http://stuff.mit.edu/afs/athena/contrib/crypto/openssl.cnf hoặc copy từ thư mục Apache config của Wamp Server D:/Wamp/bin/apache/Apache2.2.17/conf) và copy vào folder config. Chỉnh lại các giá trị trong file config cho phù hợp: ví dụ dưới dùng dir = thư mục hiện tại (dấu .)
dir = .
certs = $dir/certs
database = $dir/database.txt
new_certs_dir = $dir/certs
serial = $dir/serial.txt
...
dir = .
certs = $dir/certs
database = $dir/database.txt
new_certs_dir = $dir/certs
serial = $dir/serial.txt
...
6. Bắt đầu dùng command line thực hiện các bước mô tả bên dưới, phần đường dẫn D:\ openssl-0.9.8h> trong các command bỏ qua.
Create CA key, self-signed CA cert
1. Tạo CA key, command này sẽ yêu cầu một password
openssl genrsa -des3 -out keys\ca-key.pem 1024
2. Tạo CA self-signed, output vào folder certs, valid 10 năm, dùng config file trong folder config đã chuẩn bị, phần Your Name ví dụ là company.com
openssl req -config config\openssl.cnf -new -x509 -days 3650 -key keys\ca-key.pem -out certs\ca-cert.cer
Backup/Remove passphrase from key
1. Backup CA key
copy keys\ca-key.pem keys\ ca-key-org.pem
2. Tạo RSA private key
openssl rsa -in keys\ca-key-org.pem -out keys\ ca-key.pem
Tới đây đã có CA cert và CA key
Create localhost (web server) private key (optional)
1. Tương tự tạo private key cho web server (ở đây gọi là localhost hay xxxyyy) giả sử password là password localhost.key.
openssl genrsa -des3 -out keys\server-key.pem 1024
2. Backup CA key
copy keys\server-key.pem keys\server-key-org.pem
3. Tạo RSA private key
openssl rsa -in keys\server-key-org.pem -out keys\ server-key.pem
Bước này không cần thiết, vì trong bước sau sẽ thực hiện tạo Certificate Signing Request cùng với Private Key.
Create CSR + Private key
Tạo csr kết quả sẽ output trong folder requests, đồng thời tạo private key cho web server, phần Your Name nên để là localhost, tức địa chỉ localhost hay nếu dùng địa chỉ khác thì là www.company.com
openssl req -new -nodes -days 3650 -config config\openssl.cnf -out requests\server-request.csr -keyout keys\server-key.pem
Sign request WITH CA key
Dùng command openssl ca để ký lên yêu cầu vừa mới tạo trong bước trước
openssl ca -policy policy_anything -config config\openssl.cnf -cert certs\ca-cert.cer -in requests\server-request.csr -keyfile keys\ca-key.pem -days 3650 -out certs\server-cert.cer
Create DER/p12
1. Tạo DER format cer bằng command
openssl x509 -in certs\ca-cert.cer -outform DER -out certs\ca-cert.der
2. Tạo p12 bằng command
openssl pkcs12 -export -in certs\ca-cert.cer -inkey keys\ca-key.pem -certfile certs\ca-cert.cer -out p12\ca.p12
Install CA as Trusted Root CA
Double click vào CA cert và install vào Trusted Root Certification Authorities store.
Install Cert with Wampserver
1. Enable SSL trong file config của Apache, uncomment load module SSL và include HTTPS config
D:\Wamp\bin\apache\Apache2.2.17\conf\httpd.conf
LoadModule ssl_module modules/mod_ssl.so
Include conf/extra/httpd-ssl.conf
2. Copy cert và private key của localhost vừa tạo vào folder config của WampServer Apache D:/Wamp/bin/apache/Apache2.2.17/conf
3. Replace đường dẫn sai trong extra/httpd-ssl.conf dạng path-to-Apache-folder đang bị sai thường là c:/Apache2 thành D:/Wamp/bin/apache/Apache2.2.17 (tùy version và path đang dùng)
4. Uncomment và chỉnh các giá trị SSLCertificateFile và SSLCertificateKeyFile
SSLCertificateFile "D:/Wamp/bin/apache/Apache2.2.17/conf/server-cert.cer"
SSLCertificateKeyFile "D:/Wamp/bin/apache/Apache2.2.17/conf/server-key.pem"
SSLCertificateKeyFile "D:/Wamp/bin/apache/Apache2.2.17/conf/server-key.pem"
5. Chỉnh lại đường đẫn enable SSL, có thể enable cả www của Wamp Server trong httpd-ssl.conf
DocumentRoot "D:/Wamp/www"
ServerName localhost:443
Testing
Nếu không start được wampapache. Có thể bị lỗi sau (xem trong event logs) có thể cần load thêm module mod_socache_shmcb
The Apache service named reported the following error:
>>> SSLSessionCache: 'shmcb' session cache not supported (known names: ). Maybe you need to load the appropriate socache module (mod_socache_shmcb?). .
Labels:
.p12,
Apache,
certificate,
HTTPS,
localhost,
OpenSSL,
private key,
self-signed,
SSL,
web dev,
web server
2011-09-16
Remove SQL Server 2005 Express Tools - Install SQL Server Management Studio Express 2008, stupid installer
Khi install SQL Server Management Studio Express (SSME) bị cái lỗi "The SQL Server 2005 Express Tools are installed. To continue, remove the SQL Server 2005 Express Tools.".
Sau khi search Google mới tìm được cách pass qua đồ khi đó.
http://social.msdn.microsoft.com/Forums/en-US/sqlsetupandupgrade/thread/5fc58507-9f40-4213-acbd-32a57c8822d7/
http://dotnetguts.blogspot.com/2010/06/remove-sql-server-2005-express-tools.html
Solution
1) Open Run Menu and type regedit.
2) It will open Registry Editor
3) Now go to following location.
HKEY_LOCAL_MACHINE > Software > Microsoft > Microsoft SQL Server > 90
4) Remove Registry Key 90.
Thêm nữa cái installer của SSME installer cực kỳ ngu. Phải chọn install new instance, tất nhiên dù có chọn new instance thì cũng chằng có instance mới nào được install cả (yên tâm). Chỉ cần install bình thường với cách chọn new instance và check Management Tools - Basic. Thế là xong.
Sau khi search Google mới tìm được cách pass qua đồ khi đó.
http://social.msdn.microsoft.com/Forums/en-US/sqlsetupandupgrade/thread/5fc58507-9f40-4213-acbd-32a57c8822d7/
http://dotnetguts.blogspot.com/2010/06/remove-sql-server-2005-express-tools.html
Solution
1) Open Run Menu and type regedit.
2) It will open Registry Editor
3) Now go to following location.
HKEY_LOCAL_MACHINE > Software > Microsoft > Microsoft SQL Server > 90
4) Remove Registry Key 90.
Thêm nữa cái installer của SSME installer cực kỳ ngu. Phải chọn install new instance, tất nhiên dù có chọn new instance thì cũng chằng có instance mới nào được install cả (yên tâm). Chỉ cần install bình thường với cách chọn new instance và check Management Tools - Basic. Thế là xong.
2011-09-12
Node.js evented I/O for V8 Javascript.
What is Node.js
Hôm nay mình sẽ note lại mình đã play với Node.js như thế nào. Thực ra thì mình cũng biết sơ về cái món này. Biết thông qua website/blog của Felix http://debuggable.com/. Developer này tất nhiên là quá quen đối với những người xài CakePHP và anh ta hiện giờ chuyển wa chơi với Node.js là core contributor. Mới đầu thì cũng chẳng biết nó là gì, sau thấy viết code server-side bằng Javascript trông rất sáng sủa, mình cũng mê code Javascript, có một chút gì đó tự do :D. Sau một thời gian làm và OK đã biết chút chút thì note lại cho khỏi quên.
Đến version này thì đã có bản build node.exe cho Windows, trước kia thì phải install Cygwin. OK nói đến đây thôi chỉ để biết nó là server-side Javascript. Và nên biết thêm V8 Javascript Engine là gì. Giờ thì play 1 chút.
Installation
Download node.exe dành cho Windows về, chạy lên chỉ ra màn hình có dấu nhắc lệnh > như command prompt. Với Linux hay Mac thì install cũng không mấy khó khăn. Nếu có thể install git hay download source tar và make là xong. Mình lấy Windows làm dev enviroment.
Giờ tạo một function đơn giản thực hiện phép cộng, nhấn Enter nó sẽ tự động indent bằng ... cho mình như trong hình. Cách viết như các ngôn ngữ script khác gọi là REPL read-eval-print loop. Mình không đi sâu nó là gì, chỉ cần biết dùng thử ntn đã.
Felix có một trang gọi là study guide rất đáng để tham khảo.
Demo
Vậy tiếp theo làm gì, tất nhiên không viết code trên cái màn hình như cmd đó được. OK copy cái ví dụ trên trang chủ http://www.nodejs.org/ thành một file gọi là server.js saved cùng thư mục với node.exe. Server này mở port 1337, trả về 200 OK result là Hello World với tất cả request, một simple dummy web server.
Chúng ta sẽ chạy script này, để thuận tiện từ đây chúng ta dùng PowerShell dùng command line cũng OK. Với Windows 7 thì PowerShell được shift sẵn, bình thường mình găm nó vào taskbar luôn (taskbar của mình theo thứ tự là Windows Media Player, Unikey, PowerShell). Nếu chạy bình thường thì gọi Windows + R -> gõ powershell. Nếu đã găm vào taskbar thì đơn giản Windows + số thứ tự trên taskbar như mình là Windows + 3. OK launch PowerShell change dir (cd) tới file server.js và node.exe. Chạy command
Các vấn đề khác thuộc về cách sử dụng hay syntax hay style; ví dụ như closure, sử dụng module, callback; thì có lẽ tự tìm hiểu sẽ tốt hơn là nói ở đây.
What next?
Nhưng giờ có con dao này rồi sẽ làm gì, viết web thì với những gì có thể làm được với PHP -> say no vì ko thể cầm con dao nhỏ mà giết chết con khủng long. Nếu tham khảo bài viết của Felix bạn sẽ biết một vài trường hợp mà Felix kêu là bad use cases.
Vậy nó làm gì, hiện tại thì chưa có gì nhiều nhưng nếu dùng build một light-weight service thì rất phù hợp. Ví dụ một REST API service hay chat server. Nếu để ý thì rất nhiều chat server đã triển khai dùng Node.js. Có thể kể là Ajax IM hay Faye và vô số những ví dụ trên GitHub chỉ cần search 1 chút là ra. Faye giới thiệu là implement Bayeux protocol. Mình không đi sâu mô tả protocol này nhưng mình không lựa chọn Faye cũng như chỉ tham khảo Ajax IM. Có lẽ bạn nên chọn Node.js + Socket.IO và thử viết cái gì đó, rồi từ từ cải tiến theo cách bạn muốn, có thể là tổ chức lại hay implement theo Bayeux.
Authentication with Node.js and Socket.IO
Vấn đề tiếp theo mình đề cập lại việc chứng thực giữa Node.js và Socket.IO. Socket.IO có mục config gọi là handshake function như sau:
Xem thêm tài liệu của Socket.IO tại đây https://github.com/LearnBoost/socket.io/wiki/Authorizing
Bạn có thể tham khảo từ bài viết sau http://anthonyw.net/2011/07/authentication-with-node-js-and-zend-framework/. Tuy nhiên mình sẽ nói rõ hơn chút xíu.
Client khi connect sẽ gửi thông tin lên server bao gồm cả cookie và các thông tin khác. Như vậy hình dung ta có scenario như sau: user login vào site theo cách thông thường, web server sẽ lưu lại thông tin của user trong session: có thể là file session hay memcache. Giả sử trong PHP dùng file session thì thông tin sẽ trong một file mà server sinh ra trong thư mục chỉ định dạng sess_{session-id}. Khi user đã login và chuyển qua page chat, Socket.IO client (Javascript) sẽ kết nối với chat server (Node.js server), Node.js phải thực hiện authorization, quyết định cho phép client connect hay không thông qua thông tin của client cung cấp. Ta chú ý đến thông tin Session ID sẽ được client send thông qua cookie. Nếu OK sẽ gọi callback với tham số true, ngược lại là false và error. Giả sử web server chạy PHP và không dùng memcache. Khi đó session file sẽ có dạng
Thực hiện authorize bằng session như sau:
Lấy PHP SESSION ID trong cookies gửi lên. Lưu ý domain của web site và Node.js server phải giống nhau thì client mới send thông tin cookies.
Example đọc thông tin session trong file
Có thể dùng RegEx để tìm thông tin authentication thay vì unserialize string trong trường hợp thông tin session quá dài và quá khó để unserialize.
Còn một phần nữa nói về cách giao tiếp giữa Node.js server và Java server khác như game server (vì thường game server implement bằng Java. Giải pháp của mình là dùng message queue như RabbitMQ, tuy nhiên có lẽ đề một dịp khác sẽ giới thiệu.
Hôm nay mình sẽ note lại mình đã play với Node.js như thế nào. Thực ra thì mình cũng biết sơ về cái món này. Biết thông qua website/blog của Felix http://debuggable.com/. Developer này tất nhiên là quá quen đối với những người xài CakePHP và anh ta hiện giờ chuyển wa chơi với Node.js là core contributor. Mới đầu thì cũng chẳng biết nó là gì, sau thấy viết code server-side bằng Javascript trông rất sáng sủa, mình cũng mê code Javascript, có một chút gì đó tự do :D. Sau một thời gian làm và OK đã biết chút chút thì note lại cho khỏi quên.
Đến version này thì đã có bản build node.exe cho Windows, trước kia thì phải install Cygwin. OK nói đến đây thôi chỉ để biết nó là server-side Javascript. Và nên biết thêm V8 Javascript Engine là gì. Giờ thì play 1 chút.
Installation
Download node.exe dành cho Windows về, chạy lên chỉ ra màn hình có dấu nhắc lệnh > như command prompt. Với Linux hay Mac thì install cũng không mấy khó khăn. Nếu có thể install git hay download source tar và make là xong. Mình lấy Windows làm dev enviroment.
Giờ tạo một function đơn giản thực hiện phép cộng, nhấn Enter nó sẽ tự động indent bằng ... cho mình như trong hình. Cách viết như các ngôn ngữ script khác gọi là REPL read-eval-print loop. Mình không đi sâu nó là gì, chỉ cần biết dùng thử ntn đã.
Felix có một trang gọi là study guide rất đáng để tham khảo.
Demo
Vậy tiếp theo làm gì, tất nhiên không viết code trên cái màn hình như cmd đó được. OK copy cái ví dụ trên trang chủ http://www.nodejs.org/ thành một file gọi là server.js saved cùng thư mục với node.exe. Server này mở port 1337, trả về 200 OK result là Hello World với tất cả request, một simple dummy web server.
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');
Chúng ta sẽ chạy script này, để thuận tiện từ đây chúng ta dùng PowerShell dùng command line cũng OK. Với Windows 7 thì PowerShell được shift sẵn, bình thường mình găm nó vào taskbar luôn (taskbar của mình theo thứ tự là Windows Media Player, Unikey, PowerShell). Nếu chạy bình thường thì gọi Windows + R -> gõ powershell. Nếu đã găm vào taskbar thì đơn giản Windows + số thứ tự trên taskbar như mình là Windows + 3. OK launch PowerShell change dir (cd) tới file server.js và node.exe. Chạy command
.\node.exe .\server.js
Như vậy ta đã có server, port 1337. Giờ test server bằng Firefox chẳng hạn, localhost:1337 sẽ được hello string. Stop server đơn giản như terminate command, Ctrl + C. Tới đây dể thấy tạo server đơn giản như thế nào.
Các vấn đề khác thuộc về cách sử dụng hay syntax hay style; ví dụ như closure, sử dụng module, callback; thì có lẽ tự tìm hiểu sẽ tốt hơn là nói ở đây.
What next?
Nhưng giờ có con dao này rồi sẽ làm gì, viết web thì với những gì có thể làm được với PHP -> say no vì ko thể cầm con dao nhỏ mà giết chết con khủng long. Nếu tham khảo bài viết của Felix bạn sẽ biết một vài trường hợp mà Felix kêu là bad use cases.
Vậy nó làm gì, hiện tại thì chưa có gì nhiều nhưng nếu dùng build một light-weight service thì rất phù hợp. Ví dụ một REST API service hay chat server. Nếu để ý thì rất nhiều chat server đã triển khai dùng Node.js. Có thể kể là Ajax IM hay Faye và vô số những ví dụ trên GitHub chỉ cần search 1 chút là ra. Faye giới thiệu là implement Bayeux protocol. Mình không đi sâu mô tả protocol này nhưng mình không lựa chọn Faye cũng như chỉ tham khảo Ajax IM. Có lẽ bạn nên chọn Node.js + Socket.IO và thử viết cái gì đó, rồi từ từ cải tiến theo cách bạn muốn, có thể là tổ chức lại hay implement theo Bayeux.
Authentication with Node.js and Socket.IO
Vấn đề tiếp theo mình đề cập lại việc chứng thực giữa Node.js và Socket.IO. Socket.IO có mục config gọi là handshake function như sau:
// create io
var io = sio.listen(PORT);
io.configure(function() {
io.set('authorization', function (data, callback) {
authorizePhpSession(data, callback);
});
});
var io = sio.listen(PORT);
io.configure(function() {
io.set('authorization', function (data, callback) {
authorizePhpSession(data, callback);
});
});
Xem thêm tài liệu của Socket.IO tại đây https://github.com/LearnBoost/socket.io/wiki/Authorizing
Bạn có thể tham khảo từ bài viết sau http://anthonyw.net/2011/07/authentication-with-node-js-and-zend-framework/. Tuy nhiên mình sẽ nói rõ hơn chút xíu.
Client khi connect sẽ gửi thông tin lên server bao gồm cả cookie và các thông tin khác. Như vậy hình dung ta có scenario như sau: user login vào site theo cách thông thường, web server sẽ lưu lại thông tin của user trong session: có thể là file session hay memcache. Giả sử trong PHP dùng file session thì thông tin sẽ trong một file mà server sinh ra trong thư mục chỉ định dạng sess_{session-id}. Khi user đã login và chuyển qua page chat, Socket.IO client (Javascript) sẽ kết nối với chat server (Node.js server), Node.js phải thực hiện authorization, quyết định cho phép client connect hay không thông qua thông tin của client cung cấp. Ta chú ý đến thông tin Session ID sẽ được client send thông qua cookie. Nếu OK sẽ gọi callback với tham số true, ngược lại là false và error. Giả sử web server chạy PHP và không dùng memcache. Khi đó session file sẽ có dạng
var sessionFile = SESSION_PATH + "/sess_" + sessionId;
Thực hiện authorize bằng session như sau:
function authorizePhpSession(data, callback) {
Controller.log("Get handshake data from client: " + sys.inspect(data));
var sessionId = getPhpSessionId(data.headers.cookie);
Controller.log("Receive session ID: " + sessionId);
// extend handshake data with PHP Session ID
data.phpSessionId = sessionId;
try {
if(!USE_MEMCACHE) {
getFileSessionData(data, sessionId, callback);
} else {
getMemcacheSessionData(data, sessionId, callback);
}
} catch(e) {
callback(null, false);
}
}
Controller.log("Get handshake data from client: " + sys.inspect(data));
var sessionId = getPhpSessionId(data.headers.cookie);
Controller.log("Receive session ID: " + sessionId);
// extend handshake data with PHP Session ID
data.phpSessionId = sessionId;
try {
if(!USE_MEMCACHE) {
getFileSessionData(data, sessionId, callback);
} else {
getMemcacheSessionData(data, sessionId, callback);
}
} catch(e) {
callback(null, false);
}
}
Lấy PHP SESSION ID trong cookies gửi lên. Lưu ý domain của web site và Node.js server phải giống nhau thì client mới send thông tin cookies.
function getPhpSessionId(cookies) {
var result = "";
cookies.split(";").forEach(function(a) {
var b = a.split("=");
if(b[0].trim() == PHP_SESSION) {
result = b[1].trim();
}
});
return result;
}
var result = "";
cookies.split(";").forEach(function(a) {
var b = a.split("=");
if(b[0].trim() == PHP_SESSION) {
result = b[1].trim();
}
});
return result;
}
Example đọc thông tin session trong file
function getFileSessionData(data, sessionId, callback) {
Controller.log("Get session data from session file with Session ID: " + sessionId);
var sessionFile = SESSION_PATH + "/sess_" + sessionId;
try {
fs.readFile(sessionFile, "utf8", function(err, fileData) {
if(err) { // not exists session
Controller.log("Can not read session data from file path { session: '" +
sessionFile + "', error: '" + sys.inspect(err) + "' }");
callback(null, false);
} else {
if(fileData.indexOf(SESSION_AUTH + "|") == -1) { // not logged in yet
// not things here, not authorize for this connection
callback(null, false);
} else {
fileData = fileData.substr((SESSION_AUTH + "|").length);
// extend handshake data with user session data
var sobj = utils.unserialize(fileData);
if(sobj.storage) {
data.user = sobj.storage;
callback(null, true);
} else {
Controller.log("Not valid authentication session data for { session: '" +
sessionId + "', result: '" + fileData + "' }");
callback(null, false);
}
}
}
});
} catch(e) {
Controller.log("Error when get authentication information { session: '" + sessionId +
"', error: '" + sys.inspect(e) + "' }");
callback(null, false);
}
}
Controller.log("Get session data from session file with Session ID: " + sessionId);
var sessionFile = SESSION_PATH + "/sess_" + sessionId;
try {
fs.readFile(sessionFile, "utf8", function(err, fileData) {
if(err) { // not exists session
Controller.log("Can not read session data from file path { session: '" +
sessionFile + "', error: '" + sys.inspect(err) + "' }");
callback(null, false);
} else {
if(fileData.indexOf(SESSION_AUTH + "|") == -1) { // not logged in yet
// not things here, not authorize for this connection
callback(null, false);
} else {
fileData = fileData.substr((SESSION_AUTH + "|").length);
// extend handshake data with user session data
var sobj = utils.unserialize(fileData);
if(sobj.storage) {
data.user = sobj.storage;
callback(null, true);
} else {
Controller.log("Not valid authentication session data for { session: '" +
sessionId + "', result: '" + fileData + "' }");
callback(null, false);
}
}
}
});
} catch(e) {
Controller.log("Error when get authentication information { session: '" + sessionId +
"', error: '" + sys.inspect(e) + "' }");
callback(null, false);
}
}
Có thể dùng RegEx để tìm thông tin authentication thay vì unserialize string trong trường hợp thông tin session quá dài và quá khó để unserialize.
function getMemcacheSessionData(data, sessionId, callback) {
Controller.log("Get session data from Memcache Server with Session ID: " + sessionId);
try {
memcache.get(sessionId, function(err, result) {
if(err) {
Controller.log("Can not read session data from Memcache Server { session: '" +
sessionId + "', error: '" + sys.inspect(err) + "' }");
callback(null, false);
} else {
var match = result.match(SESSION_REGEX); // using regex to extract authentication information
if (match != null) {
data.user = {
id: match[1],
username: match[2],
email: match[3],
first_name: (match[4] == null || typeof match[4] == "undefined") ? "" : match[4],
last_name: (match[5] == null || typeof match[5] == "undefined") ? "" : match[5],
}
Controller.log("Authentication information { session: '" +
sessionId + "', user: '" + sys.inspect(data.user) + "' }");
callback(null, true);
} else {
Controller.log("Not valid authentication session data for { session: '" +
sessionId + "', result: '" + result + "' }");
callback(null, false);
}
}
});
} catch(e) {
Controller.log("Error when get authentication information { session: '" + sessionId +
"', error: '" + sys.inspect(e) + "' }");
callback(null, false);
}
}
Controller.log("Get session data from Memcache Server with Session ID: " + sessionId);
try {
memcache.get(sessionId, function(err, result) {
if(err) {
Controller.log("Can not read session data from Memcache Server { session: '" +
sessionId + "', error: '" + sys.inspect(err) + "' }");
callback(null, false);
} else {
var match = result.match(SESSION_REGEX); // using regex to extract authentication information
if (match != null) {
data.user = {
id: match[1],
username: match[2],
email: match[3],
first_name: (match[4] == null || typeof match[4] == "undefined") ? "" : match[4],
last_name: (match[5] == null || typeof match[5] == "undefined") ? "" : match[5],
}
Controller.log("Authentication information { session: '" +
sessionId + "', user: '" + sys.inspect(data.user) + "' }");
callback(null, true);
} else {
Controller.log("Not valid authentication session data for { session: '" +
sessionId + "', result: '" + result + "' }");
callback(null, false);
}
}
});
} catch(e) {
Controller.log("Error when get authentication information { session: '" + sessionId +
"', error: '" + sys.inspect(e) + "' }");
callback(null, false);
}
}
Còn một phần nữa nói về cách giao tiếp giữa Node.js server và Java server khác như game server (vì thường game server implement bằng Java. Giải pháp của mình là dùng message queue như RabbitMQ, tuy nhiên có lẽ đề một dịp khác sẽ giới thiệu.
2011-08-02
Using Link Shell Extension to create NTFS Junction
Trước giờ mọi người nghe nhiều về NTFS, sử dụng Windows không biết bao nhiêu năm và cũng không ai xa lạ gì với create shortcut. Nhưng chắc chắn rất ít người biết rõ về link của NTFS: thế nào là symbolic link hay junction. Những ai tiếp xúc với Linux thì sẽ quen với khái niệm link còn người dùng Wins thì phần lớn chỉ biết shortcut.
Tuy nhiên shortcut không phải khi nào cũng dùng được, nó có nhiều hạn chế hơn những dạng khác mà những dạng này ít người biết mà Wins cũng không hỗ trợ trực tiếp. Mình sẽ không nói gì về lý thuyết cả, chỉ giới thiệu một cách dùng Junction của NTFS trong thực tế như thế nào. Sẵn tiện cài xong game mình viết một vài dòng luôn. Vì sao lại dùng Junction thì có thể tham khảo link http://comptb.cects.com/2268-overview-to-understanding-hard-links-junction-points-and-symbolic-links-in-windows
Mình trích 1 đoạn như sau:
Ví dụ 1: chơi The Sims, download objects phải để trong My Document/EA Games/The Sims 2/Downloads, nhưng việc này dẫn đến 2 vấn đề rắc rối: thứ nhất dung lượng ổ C chẳng hạn có giới hạn, thứ 2 muốn giữ lại download mỗi khi cài lại máy hay muốn để một nơi nào đó (một ổ đĩa khác ổ Data là D:).
Ví dụ 2: một trường hợp nữa là khi không muốn cài hết tất cả trong C: vì lỡ chia partition quá nhỏ mà không resize được, nhưng một số app rất khó chịu, đã chọn installation location là ổ đĩa khác vẫn install vào C: (điển hình là Visual Studio).
Lúc này mình sẽ dùng Junction như sau:
Bước 1: download hardlink shell, một tiện ích miễn phí cho phép tạo các dạng NTFS link khác nhau, ở đây mình sẽ xài Junction
http://schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html
Trong trang download cũng có chỉ cách dùng, tuy nhiên để rõ ràng mình sẽ mô tả cách dùng Junction.
Bước 2: cài đặt link shell extension. Sau khi cài đặt xong, nhấp chuột phải vào một folder nào đó sẽ có một shell extension là 'Pick Link Source'. Tới đây là đã cài Link Shell Extension thành công.
Bước 3: cách dùng
Giả sử với ví dụ 1 ở trên. Chúng ta muốn link The Sims 2/Downloads sang ổ data D: chẳng hạn (có nghĩa là chúng ta cần kết quả cuối cùng trong The Sims 2 có folder Downloads nhưng thực chất nó là một folder ở D:).
- Tạo trong D:\My Games\The Sims 2\Downloads. Phần trước Downloads là gì cũng được tùy bạn quản lý nhưng phần sau chắc chắn là Downloads. Đây là folder thật 100%.
- Chọn chuột phải, hiện ra 'Pick Link Source', thực hiện Pick Link Source bằng cách click vào đó ;-). Sau bước này chúng ta đã chọn link source.
- Vào My Document/EA Games/ tức tại đây chúng ta thấy folder The Sims 2 nghĩa là folder cha của Downloads mà chúng ta sẽ tạo, nhấn chuột phải, lúc này sẽ thấy xuất hiện Cancel Link Creation tức hủy việc tạo link (nếu tạo nhầm chẳng hạn), và Drop As ..., ta chọn Drop As ... -> Chọn Junction, như vậy là đã tạo link xong.
Folder link sẽ có biểu tượng link nhỏ bên góc biểu tượng folder, nếu nhấn chuột phải thì trong menu context sẽ có mục Delete Junction.
- Giờ test thử, new một text document (New Text Document.txt) ngoài desktop chẳng hạn, paste vào My Document/EA Games/The Sims 2/Downloads hay vào trực tiếp tạo text file trong Downloads link folder mới tạo, rồi chuyển sang D:\My Games\The Sims 2\Downloads, trong đó có file text vừa tạo. Bây giờ 2 folder ở 2 vị trí nhưng bản chất là một.
Với ví dụ 2: chúng ta làm tương tự, giả sử cài Visual Studio 2010, tạo trong D: thư mục là D:\Microsoft Visual Studio 10.0 (là default installation folder name). Chọn Pick Link Source, xong vào C:, chọn chuột phải lên folder Program Files, và chọn Drop As ... > Junction. Sau khi thực hiện xong chúng ta cài Visual 2010 bình thường, chọn thư mục cài đặt là C:\Program Files\Microsoft Visual Studio 10.0, thực chất sẽ cài lên ổ D:. Có thể mình cài trước, rồi move cái folder cài đó sang D:, xong tạo link ngược lại cũng OK.
Vậy là có thể bạn đã biết thêm 1 các dùng link trong Windows. Rất cảm ơn developer tạo ra cái shell extension này, rất tiện lợi.
Nice day,
Tuy nhiên shortcut không phải khi nào cũng dùng được, nó có nhiều hạn chế hơn những dạng khác mà những dạng này ít người biết mà Wins cũng không hỗ trợ trực tiếp. Mình sẽ không nói gì về lý thuyết cả, chỉ giới thiệu một cách dùng Junction của NTFS trong thực tế như thế nào. Sẵn tiện cài xong game mình viết một vài dòng luôn. Vì sao lại dùng Junction thì có thể tham khảo link http://comptb.cects.com/2268-overview-to-understanding-hard-links-junction-points-and-symbolic-links-in-windows
Mình trích 1 đoạn như sau:
Junction Point (Directory Hard Link):
- A file that acts like a representation of a target directory, partition or volume on the same system
- Has the same size as the target without duplicating it (doesn’t use any space)
- Interpreted at the operating system level – transparent to SW programs and users
- Deleting the Junction Point does not remove the target*
- If the target is moved, renamed or deleted, the Junction Point still exists, but points to a non-existing directory
- Changing the contents through the Junction Point changes the target contents
- Can reside on partitions or volumes separate from the target on the same system
- Compatible with Win2k and above in Windows
*A Junction Point should never be removed in Win2k, Win2003 and WinXP with Explorer, the del or del /s commands, or with any utility that recursively walks directories since these will delete the target directory and all its subdirectories. Instead, use the rmdir command, the linkd utility, or fsutil (if using WinXP or above) or a third party tool to remove the junction point without affecting the target. In Vista/Win7, it’s safe to delete Junction Points with Explorer or with the rdir and del commands.
Symbolic Link (Soft Link):
- A file containing text interpreted by the operating system as a path to a file or directory
- Has a file size of zero
- Interpreted at the operating system level – transparent to SW programs and users
- Deleting the Symbolic Link does not remove the target
- If the target is moved, renamed or deleted, the link still exists, but points to a non-existing file or directory
- Points to, rather than represents, the target using relative paths
- Can reside on partitions or volumes separate from the target or on remote SMB network paths
- Compatible with UNIX and UNIX-like systems and with Vista and above in Windows
Shortcut:
- A file interpreted by the Windows shell or other apps that understand them as paths to a file or directory
- File size corresponds to the binary information it contains
- Treated as ordinary files by the operating system and by SW programs that don’t understand them
- Deleting the shortcut does not remove the target
- Maintains references to target even if the target is moved or renamed, but is useless if the target is deleted
- Points to, rather than represents, the target
- Can reside on partitions or volumes separate from the target on the same System
- Compatible with all Windows versions
Ví dụ 1: chơi The Sims, download objects phải để trong My Document/EA Games/The Sims 2/Downloads, nhưng việc này dẫn đến 2 vấn đề rắc rối: thứ nhất dung lượng ổ C chẳng hạn có giới hạn, thứ 2 muốn giữ lại download mỗi khi cài lại máy hay muốn để một nơi nào đó (một ổ đĩa khác ổ Data là D:).
Ví dụ 2: một trường hợp nữa là khi không muốn cài hết tất cả trong C: vì lỡ chia partition quá nhỏ mà không resize được, nhưng một số app rất khó chịu, đã chọn installation location là ổ đĩa khác vẫn install vào C: (điển hình là Visual Studio).
Lúc này mình sẽ dùng Junction như sau:
Bước 1: download hardlink shell, một tiện ích miễn phí cho phép tạo các dạng NTFS link khác nhau, ở đây mình sẽ xài Junction
http://schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html
Trong trang download cũng có chỉ cách dùng, tuy nhiên để rõ ràng mình sẽ mô tả cách dùng Junction.
Bước 2: cài đặt link shell extension. Sau khi cài đặt xong, nhấp chuột phải vào một folder nào đó sẽ có một shell extension là 'Pick Link Source'. Tới đây là đã cài Link Shell Extension thành công.
Bước 3: cách dùng
Giả sử với ví dụ 1 ở trên. Chúng ta muốn link The Sims 2/Downloads sang ổ data D: chẳng hạn (có nghĩa là chúng ta cần kết quả cuối cùng trong The Sims 2 có folder Downloads nhưng thực chất nó là một folder ở D:).
- Tạo trong D:\My Games\The Sims 2\Downloads. Phần trước Downloads là gì cũng được tùy bạn quản lý nhưng phần sau chắc chắn là Downloads. Đây là folder thật 100%.
- Chọn chuột phải, hiện ra 'Pick Link Source', thực hiện Pick Link Source bằng cách click vào đó ;-). Sau bước này chúng ta đã chọn link source.
- Vào My Document/EA Games/ tức tại đây chúng ta thấy folder The Sims 2 nghĩa là folder cha của Downloads mà chúng ta sẽ tạo, nhấn chuột phải, lúc này sẽ thấy xuất hiện Cancel Link Creation tức hủy việc tạo link (nếu tạo nhầm chẳng hạn), và Drop As ..., ta chọn Drop As ... -> Chọn Junction, như vậy là đã tạo link xong.
Folder link sẽ có biểu tượng link nhỏ bên góc biểu tượng folder, nếu nhấn chuột phải thì trong menu context sẽ có mục Delete Junction.
- Giờ test thử, new một text document (New Text Document.txt) ngoài desktop chẳng hạn, paste vào My Document/EA Games/The Sims 2/Downloads hay vào trực tiếp tạo text file trong Downloads link folder mới tạo, rồi chuyển sang D:\My Games\The Sims 2\Downloads, trong đó có file text vừa tạo. Bây giờ 2 folder ở 2 vị trí nhưng bản chất là một.
Với ví dụ 2: chúng ta làm tương tự, giả sử cài Visual Studio 2010, tạo trong D: thư mục là D:\Microsoft Visual Studio 10.0 (là default installation folder name). Chọn Pick Link Source, xong vào C:, chọn chuột phải lên folder Program Files, và chọn Drop As ... > Junction. Sau khi thực hiện xong chúng ta cài Visual 2010 bình thường, chọn thư mục cài đặt là C:\Program Files\Microsoft Visual Studio 10.0, thực chất sẽ cài lên ổ D:. Có thể mình cài trước, rồi move cái folder cài đó sang D:, xong tạo link ngược lại cũng OK.
Vậy là có thể bạn đã biết thêm 1 các dùng link trong Windows. Rất cảm ơn developer tạo ra cái shell extension này, rất tiện lợi.
Nice day,
Labels:
games,
hardlink shell,
Link Shell Extension,
NTFS,
NTFS Junction,
The Sims,
The Sims 2,
Windows
Subscribe to:
Comments (Atom)






