第二节:WAP基础
WAP (Wireless Application Protocol) v1.1是一种开放性规范,它试图规范移动电话访问信息和服务行业。这个规范是由
WAP Forum来开发的,一个民间组织。1.2版本的WAP协议将会被认为是最后的WAP规范。
关于wap最基本的概念就是重复利用internet协议,这个协议必须很清楚地在现有的技术上轻松地调用wap服务。
WAP协议利用一种很像我们电脑网络的分层结构。较低层次不太像我们常用的web应用,但是顶层还是我们的老朋友----HTTP。
数据一样是从服务器上发出,从服务器上接收,信息能够储存在服务器上,调用也可能用CGI,也可以用其它的方法,比如ASP.也就
是说只要你会ASP,那么你就可以在轻松地写出你的第一个WAP应用程序了。
当然,就手机的带宽和用户能力方面来看,手机需要不同(更严格)的设备,所以在目前的条件下HTML就不能适应WAP所能提
供的带宽。
WAP Forum 的定位是WML (Wireless Mark-up Language),一种xml格式的语言。WML是精简的HTML。
WAP Forum同时也指定了WMLScript,很像JavaScript,只是用于手机而已,它能够处理客户端的程序。
第三节:WML
尽管我已经讲解了手机与服务器的通讯,但是真正的客户端不是手机。一个软件(wap gateway),实际上允当了这个角色。它
将手机的请求转换为HTTP请求,同时也将服务器的回应返回给手机,WML文件此时就被WAP GateWay编译成二进制文件。尽管有些
WAP geteway能够将HTML直接转换为WML,但是也不要指望它们能任意地将HTML转换为我们在手机上能看懂的东东。
当然,仿真器就不需要WAP gateway来工作了,它会直接从服务器下载WML文件(或者直接在本地机上打开WML),同时将它显示
在手机的屏幕上。图一WAP 结构
WAP 仿真器
为了使用WAP服务,像吾等穷人买不起手机,就需要一个wap 仿真器。你可以去Nokia website下载一个 Nokia Toolkit
1.2,同时你也得装上Java Virtual Machine 1.2.2,可以免费从SUN公司下载,这里是个例子。
WML 结构
一个WML文档是由板块组成的,一个板块包含有许多的卡片。在实际中,你可以把一个板块看成一个由许多有名字的标签组成的
HTML。
手机下载一个完整的板块,但是在一次只能显示一个卡片。通过链接浏览不同的地方。
我们将会看到一个简单的WML文档,你得懂点最基本的XML。
以下是引用片段: <?xml version="1.0"?> <!DOCTYPE WML PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"> <wml> <!-- root element --> <card id="card1" title="Example 1"> <p> <!-- 卡片只能支持p和do块 --> <do type="accept" label="go to card 2"> <go href="#card2"/> </do> This is the first card. </p> </card> <card id="card2" title="Example 1"> <p> This is the second card. </p> </card> </wml> |
以下是引用片段: < !--#include file=\"conn.asp\" -- >< % 'send the right MIME type Response.ContentType = \"text/vnd.wap.wml\" 第一件事就是声明wml,仿真器如何不在正确的地方声明XML,它是不会接受WML的尽管Nokia 7110可以忽略这一点,但是不能保证其它的手机也行,所以你不得不做这事。同样你也得设置好MIME类型。 < ?xml version=\"1.0\"? > < !DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\" > < wml > 在进入下一个card以前会有一个闪烁的屏幕来显示一个图片WBMP一种新的格式。这个事件是由timer属性决定的,这里我们设置的时间为5秒.ontimer事件引发后将带你去另一个card.(wmbp的photoshop插件可以从网上免费下载). < card id=\"splash\" ontimer=\"#card1\" title=\"Welcome to\" > < timer value=\"50\"/ > < p align=\"center\" > < br / > < img src=\"pix/logo.wbmp\" alt=\"WAP movies\"/ > < /p > < /card > < card id=\"card1\" title=\"choose a film\" > < % sqlQuery = \"SELECT [Movie_ID], [title] FROM Movie\" set rsMovies = conn.Execute(SQLquery) : % > < p > < select name='movie' > < % Do while not rsMovies.eof response.write(\"< option value='\" & rsMovies(\"Movie_ID\") & \"' >\" & rsMovies(\"title\") & \"< /option >\" & vbcrlf) rsMovies.MoveNext loop % > < /select > |
以下是引用片段: < small > < anchor title=\"next!\" >Next < go href=\"step2.asp\" method=\"get\" > < postfield name=\"movie\" value=\"$(movie)\" / > < /go > < /anchor > < /small > < /p > |
选择电影院和上映时间
这部分代码让用户来选择看什么时间的电影,所有的记录根据前一页所选的电影来决定。在这里来选择电影院和上映时间.
以下是引用片段: movie_id = Request(\"movie\") sqlQuery = \"SELECT title FROM movie WHERE Movie_id = \" & movie_id set rsMovie = conn.Execute(sqlQuery) movie_title = rsMovie(\"title\") : sqlQuery = \"SELECT [name], [time], [show_id] FROM Show, Theater \" &_ \"WHERE show.movie_id = \" & movie_id &_ \" AND theater.theater_id = show.theater_id\" set rsShows = conn.Execute(SQLquery) |
如果你仔细研究了这个代码,你就会想用Session来保存电影信息,再在这页进行查询更简单。同样很不幸,Session是需要cookies的支持,虽说在WAP规范中也是被支持的,但是在Nokia 7110中也是不被支持,这就是说现在我们还不能把session用在WAP服务中。
下面有一些有趣的事情:
以下是引用片段: < select name='show' > < % Do while not rsShows.eof response.write(\"< option value='\" & rsShows(\"show_id\") & \"' >\" & Left(rsShows(\"name\"),cutter) & \" (\" & rsShows(\"time\") & \")\" & \"< /option >\" &vbcrlf) rsShows.MoveNext loop % > < /select > |
如果你对cutter变量感到疑惑,那么就有一些事让你哭笑不得
以下是引用片段: Dim cutter if InStr(Request.ServerVariables(\"HTTP_USER_AGENT\"), \"Nokia7110\") then cutter = 12 else cutter = 7 end if |
这段代码根据不同的设备来显示选项。我们有充足的理由的这样做,Nokia Toolit 1.2仿真器喜欢把砍掉我的的选项到只有几个字符,而我们要显示电影名字和上映时间,所以我们就不得不减少电影名字的字符。在真的手机中不会出现这种问题,所以我们就必须先判断设备的类型.
一旦我有机会(飞刀我很穷,没有钱,这是仅仅是遥远的梦想.......)在真的Nokia 7110上测试我的代码,我们会立即感到我们有比我们想像更大的屏幕。实际上,有些电影院的名字很古怪,而且这些长名字会占用很大屏幕空间,我们没有必要浪费这些显示空间,尽量把这些名字简化。
下一步就是让用户选择需要的票数.这部分的代码很像其它的部分。我将从数据库中查询相同的数据,因为Session不能在真正的WAP手机中使用,所以我必须对有些内容进行确认,看看是否还有座位出售.
以下是引用片段: SQLquery = \"SELECT * FROM show WHERE Show_id = \" & show_id set rsShow = conn.Execute(SQLquery) : seats = rsShow(\"free_seats\") : if seats = 0 then Response.write(\"Sorry, no more seats\") rsShow.close set rsShow = nothing Response.write(\"< /p >< /card >< /wml >\") Response.end else if seats > 6 then 'book up to 6 tickets or max available max_seats=6 else max_seats = seats end if end if % > < %=movie_title% > at < % =theater_name% > < select name='ticket' > < % dim i i = 1 Do while i < = max_seats response.write(\"< option value='\" & i & \"' >\" & i & \" ticket(s)\" & \"< /option >\" &vbcrlf) i = i + 1 loop % > < /select > |
储存票数
现在我们已经有了所有需要的数据了,我们得把它们保存起来:
以下是引用片段: tickets = Request(\"ticket\") : free_seats = rsShow(\"free_seats\") : free_seats = free_seats - tickets : SQLUpdate = \"UPDATE Show \" &_ \"SET Show.free_seats=\" & free_seats & \" \" &_ \" WHERE Show_ID=\" & show_id conn.Execute(SQLupdate) SQLquery = \"SELECT max([Booking_ID]) as bookingnumber FROM booking\" Set rsBooking = conn.execute(SQLquery) maxbookid = rsBooking(\"bookingnumber\") + 1 SQLinsert = \"INSERT INTO Booking ( show_id, booked_seats ) \" & _ \"VALUES ('\" & show_id & \"', '\" & tickets & \"')\" conn.Execute(SQLinsert) % > You have booked < %=tickets% > ticket(s) for < %=movie_title% >< br / > The show will take place at < %=theater_name% > (< %=time% >) < br / > Your reference number is < %=maxbookid% > |
下面是显示:
Figure 4:完成交易.
交易已经完成了,电影院可以坐着电影院门口收钱了.
结论
WAP现在才刚刚走出它的第一步,然而它是最近几年内最有革命性的IT发展之一。在这篇文章中我介绍了怎样用asp写WAP应用程序,并对你们提出了一些警告,希望对你们以后的发展有用。多媒体技术依然不能太多的用于WAP,但是它的可移动性却是重要的,也为商家提供了不少的商机。