Gởi request cho server

Một phần của tài liệu tìm hiểu các dịch vụ WEB cho ứng dụng GIS và xây dựng ứng dụng minh họa khai thác dịch vụ (Trang 146 - 155)

™ Sau khi xây dựng xong chuỗi request bằng Xml, ta cần phải gởi chuỗi request này lên cho server.

™ Trong .NET, ta có thể thực hiện việc gởi 1 request lên cho server theo 2 cách là: đồng bộ và bất đồng bộ

7.1.2.1.Thực hiện việc gởi request bằng phương pháp đồng bộ

™ Đối với phương pháp đồng bộ, sau khi thực hiện 1 request thì client phải chờ cho đến khi nhận xong response từ server, nó mới có thể thực hiện tiếp các tác vụ khác. Do đó, trong lúc nhận response từ server thì client không thể làm được việc gì khác.

™ Để gởi request bằng phương pháp đồng bộ, ta sử dụng 2 lớp là

HttpWebRequest HttpWebResponse.

7.1.2.1.1. Gởi request bằng phương pháp dồng bộ với giao thức HTTP GET

™ Trong trường hợp này chuỗi URL có thể chứa thêm các thông tin khác. ™ Ví dụ dưới đây gởi request đến 1 server có chuỗi URL là

string sURL =

“http://localhost/OpenGISServer/VNesOpenGISServer.aspx?SERVIC E=WFS&

VERSION=1.0.0&REQUEST=GetFeature&TypeName=buudien,quan,duong”

ƒ Chuỗi URL này có thêm các tham số là SERVICE, VERSION,

REQUEST, TypeName.

ƒ Tạo đối tượng HttpWebRequest và gởi chuỗi URL System.Net.HttpWebRequest httpRequest =

Chương 7. Cài đặt các chương trình client

ƒ Nhận kết quả trả về dưới dạng 1 stream. System.Net.WebResponse httpResponse = httpRequest.GetResponse();

System.IO.Stream stream = httpResponse.GetResponseStream(); ƒ Sau khi nhận dòng dữ liệu này, ta có thể lấy dữ liệu trong dòng dữ liệu dưới dạng chuỗi hoặc lưu dòng dữ liệu xuống file.

StreamReader reader = new StreamReader(stream); ƒ Chuyển kết quả sang 1 chuỗi.

string response = reader.ReadToEnd(); ƒ Lưu dòng dữ liệu xuống file.

FileStream file = new

FileStream("c:\\xml.xml",FileMode.Create,FileAccess.Write); int ch; do{ ch = stream.ReadByte(); if (ch!= -1) file.WriteByte((byte)ch); }while (ch != -1); file.Close();

7.1.2.1.2. Gởi request bằng phương pháp đồng bộ với giao thức HTTP POST

™ Trong trường hợp này nội dung cần gởi lên server được lưu trong phần body của request.

™ Ví dụ dưới đây gởi 1 request dưới dạng POST lên server. ƒ Server có địa chỉ là

sAddress=http://localhost/OpenGISServer/VNesOpenGISServer.aspx ƒ Nội dung cần gởi lên server này được lưu trong chuỗi sPostContent.

Chương 7. Cài đặt các chương trình client

• Tạo đối tượng HttpWebRequest và ghi nội dung của chuỗi sPostContent vào phần body của request.

System.Net.HttpWebRequest myHttpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Creat e(sAddress); System.Text.ASCIIEncoding encoding=new System.Text.ASCIIEncoding(); byte[] byte1=encoding.GetBytes(sPostContent); //Chọn loại ContentType của dữ liệu cần gởi lên myHttpWebRequest.ContentType="application/x-www-form- urlencoded";

// Xác định chiều dài của chuỗi cần gởi lên

myHttpWebRequest.ContentLength=sPostContent.Text. Length;

myHttpWebRequest.Method = "POST"; (adsbygoogle = window.adsbygoogle || []).push({});

Stream newStream = myHttpWebRequest.GetRequestStream(); newStream.Write(byte1,0,byte1.Length); newStream.Close(); System.Net.WebResponse httpResponse = myHttpWebRequest.GetResponse(); System.IO.Stream stream = httpResponse.GetResponseStream();

StreamReader reader = new StreamReader(stream); //Chuyển kết quả sang 1 chuỗi.

string response = reader.ReadToEnd(); stream.Close(); httpResponse.Close(); //Lấy kết quả trả về. System.Net.WebResponse httpResponse = httpRequest.GetResponse(); System.IO.Stream stream =

Chương 7. Cài đặt các chương trình client

7.1.2.2.Gởi request bằng phương pháp không đồng bộ

Khi gởi 1 request bằng phương pháp không đồng bộ, ta có thể tiếp tục thực hiện các tác vụ khác trong lúc nhận kết quả trả về bởi vì tác vụ nhận kết quả

từ server sẽđược thực hiện trong 1 tiểu trình khác.

7.1.2.2.1. Gởi request bằng phương pháp không đồng bộ với giao thức HTTP GET

™ Ví dụ dưới đây minh họa việc gởi request đến server bằng phương pháp không đồng bộ với giao thức HTTP GET.

ƒ Chương trình dưới đây là 1 chương trình dưới dạng console, có chức năng nhận 1 chuỗi URI từ dòng lệnh, yêu cầu tài nguyên từđịa chỉđó, in dữ liệu ra màn hình sau khi nó nhận xong dữ liệu từ server.

ƒ Chương trình định nghĩa 2 lớp là lớp RequestState, có tác dụng chuyển dữ liệu qua lại giữa các các lời gọi không đồng bộ và lớp ClientGetAsync dùng để tạo 1 request bằng phương pháp không đồng bộ

• Lớp RequestState lưu trạng thái của request trong suốt quá trình gọi các hàm để phục vụ request. Nó chứa 1 đối tượng WebRequest và 1 đối tượng Stream, đối tượng WebRequest chứa request hiện tại đến tài nguyên trên server và đối tượng Streamchứa dòng dữ liệu nhận được từ response của server, và 1 đối tuợng StreamBuilder chứa toàn bộ chuỗi response. Một đối tượng RequestState được dùng làm tham sốstate khi

hàm AsyncCallback được đăng kí với

hàmWebRequest.BeginGetResponse.

• Lớp ClientGetAsync chứa các hàm và các thuộc tính dưới đây:

o Thuộc tính allDone chứa 1 đối tượng của lớp ManualResetEvent,

dùng để báo hiệu khi request hoàn thành.

o Hàm Main() đọc thông tin từ dòng lệnh và tạo 1 request đến 1 tài nguyên trên internet. Nó tạo 1 đối tuợng WebRequest wreq và đối tượng RequestState rs, gọi hàm BeginGetResponse để bắt đầu quá

Chương 7. Cài đặt các chương trình client

trình thực hiện request. Sau đó nó gọi hàm allDone.WaitOne()để cho chương trình sẽ không kết thúc khi vẫn chưa nhận xong response. Sau

khi đọc được response, 1 hàm này xuất nội dung trong response ra

màn hình và chương trình kết thúc.

o Hàm RespCallBack() dùng để cài đặt 1 hàm callback không đồng bộđến tài nguyên trên internet. Nó tạo ra 1 đối tượng WebResponse

dùng để chứa response từ server, lấy dòng dữ liệu từ response này và bắt đầu quá trình đọc dữ liệu từ dòng dữ liệu 1 cách không đồng bộ. o Hàm ReadCallBack() dùng để cài đặt 1 hàm callback không đồng

bộ, hàm callback này có tác dụng đọc dữ liệu từ dòng dữ liệu của chuỗi response. Nó chuyển dữ liệu nhận được tài nguyên internet và gán nó cho thuộc tính ResponseData của đối tượng RequestState, sau đó nó lại bắt đầu tiếp thao tác đọc dữ liệu không đồng bộ trong dòng dữ liệu của response từ server cho đến khi không còn dữ liệu trả về. Sau khi toàn bộ dữ liệu đã được đọc xong, hàm ReadCallBack() đóng dòng dữ liệu của response lại và gọi hàm allDone.Set() để chỉ ra rằng toàn bộ dữ liệu từ server trả vềđã được ghi vào ResponseData. ƒ Chú ý: Một điều đáng lưu ý là tất cả các dòng dữ liệu giữa client và mạng

bên ngoài phải được đóng lại. Nếu ta không đóng các dòng dữ liệu của các request và các response, chương trình của ta sẽ không còn kết nối nào đến server nữa và không thể thực hiện tiếp request nào.

using System; using System.Net;

using System.Threading; using System.Text;

using System.IO;

// Lớp RequestState dùng để chuyển dữ liệu qua lại giữa các lời gọi hàm. (adsbygoogle = window.adsbygoogle || []).push({});

Chương 7. Cài đặt các chương trình client

public class RequestState

{

const int BufferSize = 1024;

public StringBuilder RequestData; public byte[] BufferRead;

public WebRequest Request; public Stream ResponseStream;

//Tạo bộ giải mã tương ứng với loại mã hóa

public Decoder StreamDecode = Encoding.UTF8.GetDecoder(); public RequestState()

{

BufferRead = new byte[BufferSize];

RequestData = new StringBuilder(String.Empty); Request = null;

ResponseStream = null; }

}

// Lớp ClientGetAsync thực hiện 1 request không đồng bộ

class ClientGetAsync

{

public static ManualResetEvent allDone = new ManualResetEvent(false);

const int BUFFER_SIZE = 1024;

public static void Main(string[] args)

{ if (args.Length < 1) { showusage(); return; } // Lấy chuỗi URI từ dòng lệnh

Chương 7. Cài đặt các chương trình client

// Tạo đối tượng dùng để gởi request

WebRequest wreq = WebRequest.Create(httpSite);

// Tạo đối tượng state

RequestState rs = new RequestState();

// Gán request vào state để cho nó có thể được

chuyển đi đến các hàm khác rs.Request = wreq; // Thực hiện 1 request không đồng bộ IAsyncResult r = (IAsyncResult) wreq.BeginGetResponse(new AsyncCallback(RespCallback), rs);

// Chờ cho đến khi lớp ManualResetEvent được

//thiết lập sao cho ứng dụng sẽ không dừng lại

//cho đến khi hàm callback được gọi (adsbygoogle = window.adsbygoogle || []).push({});

allDone.WaitOne();

Console.WriteLine(rs.RequestData.ToString()); }

public static void showusage() {

Console.WriteLine("Nhận chuỗi URL"); Console.WriteLine("\r\nDùng cho:");

Console.WriteLine(" ClientGetAsync URL"); Console.WriteLine(" Ví dụ:");

Console.WriteLine(" ClientGetAsync http://www.contoso.com/");

}

private static void RespCallback(IAsyncResult ar)

{

//Lấy đối tượng RequestState từ kết quả trả về //của lời gọi request không đồng bộ.

RequestState rs = (RequestState) ar.AsyncState;

//Lấy đối tượng WebRequest từ đối tượng RequestState

Chương 7. Cài đặt các chương trình client

//Gọi hàm EndGetResponse, hàm này tạo ra 1 đối

//tượng WebResponse từ request được gởi ở trên

WebResponse resp = req.EndGetResponse(ar);

//Bắt đầu đọc dữ liệu từ dòng dữ liệu trả về

Stream ResponseStream=resp.GetResponseStream();

// Lưu dòng dữ liệu trả về trong RequestState để đọc //dòng dữ liệu này 1 cách không đồng bộ

rs.ResponseStream = ResponseStream;

//Gởi tham số rs.BufferReader cho hàm BeginRead.

//Đọc dữ liệu vào rs.BufferRead

IAsyncResult iarRead =

ResponseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack),rs); }

private static void ReadCallBack(IAsyncResult

asyncResult)

{

// Lấy đối tượng RequestState từ đối tượng AsyncResult

RequestState rs = RequestState)asyncResult.AsyncState;

// Lấy ResponseStream khởi tạo trong hàm RespCallback (adsbygoogle = window.adsbygoogle || []).push({});

Stream responseStream = rs.ResponseStream;

// Đọc rs.BufferRead để kiểm tra xem nó có còn

//dữ liệu không

int read = responseStream.EndRead( asyncResult); if (read > 0)

{

// Tạo 1 mảng Char để chuyển sang Unicode

Char[] charBuffer = new Char[BUFFER_SIZE];

//Chuyển từ dòng dữ liệu kiểu byte sang mảng

Char và sau đó sang String

Chương 7. Cài đặt các chương trình client

int len = rs.StreamDecode.GetChars( rs.BufferRead, 0,read, charBuffer, 0);

String str = new String(charBuffer, 0, len); // Gắn phần dữ liệu vừa đọc được vào đối

//tượng RequestData nằm trong RequestState rs.RequestData.Append( Encoding.ASCII.GetString(rs.BufferRead, 0, read)); // Tiếp tục đọc dữ liệu đến khi hàm responseStream.EndRead trả về -1 IAsyncResult ar = responseStream.BeginRead( rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs); } else { if(rs.RequestData.Length>0) { //Hiển thị dữ liệu ra màn hình string strContent; strContent = rs.RequestData.ToString(); } // Đóng dòng dữ liệu trả về responseStream.Close();

//Thiết lập ManualResetEvent để cho tiểu trình

chính có thể đóng lại

}

return; }

Chương 7. Cài đặt các chương trình client

Một phần của tài liệu tìm hiểu các dịch vụ WEB cho ứng dụng GIS và xây dựng ứng dụng minh họa khai thác dịch vụ (Trang 146 - 155)