- Jun 04 Wed 2014 15:49
-
[Design] How to Get a Professional Look With Color
http://www.webdesignerdepot.com/2009/12/how-to-get-a-professional-look-with-color/
- May 27 Tue 2014 15:24
-
[CS] 深入淺出教你寫編譯器
http://dukeland.hk/2012/03/29/a-simple-tutorial-of-writing-a-compiler-part-2-scanner-lexical-analysis-section-1/
http://dukeland.hk/2012/03/30/a-simple-tutorial-of-writing-a-compiler-part-2-scanner-lexical-analysis-section-2/
http://dukeland.hk/2012/04/05/a-simple-tutorial-of-writing-a-compiler-part-3-parser-syntactic-analysis-section-1/
http://dukeland.hk/2012/04/06/a-simple-tutorial-of-writing-a-compiler-part-3-parser-syntactic-analysis-section-2/
http://dukeland.hk/2012/03/30/a-simple-tutorial-of-writing-a-compiler-part-2-scanner-lexical-analysis-section-2/
http://dukeland.hk/2012/04/05/a-simple-tutorial-of-writing-a-compiler-part-3-parser-syntactic-analysis-section-1/
http://dukeland.hk/2012/04/06/a-simple-tutorial-of-writing-a-compiler-part-3-parser-syntactic-analysis-section-2/
- Mar 18 Tue 2014 23:17
-
[Test] Auto Selenium on PHPUnit
The required tools : {
* PHPUnit : {
> How to install : {
# Reference : {
http://nishutayaltech.blogspot.in/2011/04/installing-phpunit-on-windows.html,
http://www.mark-leong.com/installing-php-and-phpunit-on-windows-7/,
http://pear.phpunit.de/
},
[0] Install PEAR : {
Method 1: Run go-pear.bat in your php dir
Method 2: If no go-pear.bat in your php dir, then => {
# Reference: http://stackoverflow.com/questions/8276682/wamp-2-2-install-pear
[1] Download this file(http://pear.php.net/go-pear.phar) to your php dir. For example C:\Appserv\PHP5.4.6
[2] Open Windows's cmd.exe with the admin priviledge
[3] Change to your php dir, like cd C:\Appserv\PHP5.4.6
[4] Enter the command: php -d phar.require_hash=0 go-pear.phar
[5] Select whether you like or not a local copy or a system one. By typing system:local and pressing enter you'll install a local copy. By typing system and pressing enter you'll install a system-wide copy.
[6] Type yes to confirm the option chosen
[7] The next list of directories, will be the referring directories that PEAR will install its components. If you select from 1 - 12 you can change the directory you'd like to install. By typing all and pressing Enter you'll be able to change them all in a queued manner. In my case, I just pressed Enter and left all defaults
[8] If all fine, you shall see: WARNING! The include+path defined in the currently used php.ini does not contain the PEAR PHP directory you just specified: If the specified directory is also not in the include_path used by your scripts, you will have problems getting any PEAR packages working.
[9] If all fine, you shall be asked with "Would you like to alter php.ini ? [Y/n]". Type "y" to proceed.
[10] Execute the PEAR_ENV.reg to add some ENV variable into your windows enviroment
[11] Change to C:\ then type "pear" in the command line, you will see PEAR runs and lists a list commands for use.
}
},
[1] Register the PHPUnit channel with PEAR. Type the commands in the cmd.exe : {
> pear channel-discover pear.phpunit.de
> pear channel-discover components.ez.no
> pear channel-discover pear.symfony-project.com
> pear update-channels
},
[2] Install PHPUnit, typing > pear install phpunit/PHPUnit
}
},
* Selenium IDE
* Selenium 2.x server : {
> How to install & run : {
[0] Extract the downloaded .jar file to the place you like
[1] Run with command line: java -jar /path/to/yout_selenium_server.jar
}
},
* PHP Formatters for Selenium IDE : {
> https://addons.mozilla.org/en-US/firefox/addon/selenium-ide-php-formatters/
> https://github.com/brokenthumbs/PHP-Formatter
}
* PHPUnit_Selenium package in PEAR: {
> Please make sure PEAR and Selenium Server installed and run
> To install, run the command > pear install phpunit/PHPUnit_Selenium
}
}
Run a auto Selenium test on PHPUnit : {
* Reference: http://www.jaceju.net/blog/archives/1293/
[0] Go to Options > Options > General and enable the checkbox of "Enable experimental features" so as to enable the function of PHP Formatters for Selenium IDE
[1] Levarge the Selenium IDE to create one test case
[2] Click Options > Format > PHP(PHPUnit) to generate the PHPUnit test code based on the created test case. (You will be prompted with a warning message, just click OK to continue)
[3] In the Selenium IDE, click the Source tab next to the Table tab. You will see the PHP test codes generated.
[4] Save these generate PHP test codes in the proper PHP file.
[5] Open the cmd.exe and make sure the Selenium server in on
[6] Type the command > phpunit /path/to/the_saved_php_test_code_file to execute the Selenium test on PHPUnit
}
Tips : {
* Shutdown the Selenium server : {
> Selenium server operates a web server under Jetty it can receive commands via http through browsers. The following URL will be used to shut down the server => http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer
> If we want to leave the server running and just close down the current session we could issue the following URL in a browser => http://localhost:4444/selenium-server/driver/?cmd=shutDown
}
}
* PHPUnit : {
> How to install : {
# Reference : {
http://nishutayaltech.blogspot.in/2011/04/installing-phpunit-on-windows.html,
http://www.mark-leong.com/installing-php-and-phpunit-on-windows-7/,
http://pear.phpunit.de/
},
[0] Install PEAR : {
Method 1: Run go-pear.bat in your php dir
Method 2: If no go-pear.bat in your php dir, then => {
# Reference: http://stackoverflow.com/questions/8276682/wamp-2-2-install-pear
[1] Download this file(http://pear.php.net/go-pear.phar) to your php dir. For example C:\Appserv\PHP5.4.6
[2] Open Windows's cmd.exe with the admin priviledge
[3] Change to your php dir, like cd C:\Appserv\PHP5.4.6
[4] Enter the command: php -d phar.require_hash=0 go-pear.phar
[5] Select whether you like or not a local copy or a system one. By typing system:local and pressing enter you'll install a local copy. By typing system and pressing enter you'll install a system-wide copy.
[6] Type yes to confirm the option chosen
[7] The next list of directories, will be the referring directories that PEAR will install its components. If you select from 1 - 12 you can change the directory you'd like to install. By typing all and pressing Enter you'll be able to change them all in a queued manner. In my case, I just pressed Enter and left all defaults
[8] If all fine, you shall see: WARNING! The include+path defined in the currently used php.ini does not contain the PEAR PHP directory you just specified: If the specified directory is also not in the include_path used by your scripts, you will have problems getting any PEAR packages working.
[9] If all fine, you shall be asked with "Would you like to alter php.ini ? [Y/n]". Type "y" to proceed.
[10] Execute the PEAR_ENV.reg to add some ENV variable into your windows enviroment
[11] Change to C:\ then type "pear" in the command line, you will see PEAR runs and lists a list commands for use.
}
},
[1] Register the PHPUnit channel with PEAR. Type the commands in the cmd.exe : {
> pear channel-discover pear.phpunit.de
> pear channel-discover components.ez.no
> pear channel-discover pear.symfony-project.com
> pear update-channels
},
[2] Install PHPUnit, typing > pear install phpunit/PHPUnit
}
},
* Selenium IDE
* Selenium 2.x server : {
> How to install & run : {
[0] Extract the downloaded .jar file to the place you like
[1] Run with command line: java -jar /path/to/yout_selenium_server.jar
}
},
* PHP Formatters for Selenium IDE : {
> https://addons.mozilla.org/en-US/firefox/addon/selenium-ide-php-formatters/
> https://github.com/brokenthumbs/PHP-Formatter
}
* PHPUnit_Selenium package in PEAR: {
> Please make sure PEAR and Selenium Server installed and run
> To install, run the command > pear install phpunit/PHPUnit_Selenium
}
}
Run a auto Selenium test on PHPUnit : {
* Reference: http://www.jaceju.net/blog/archives/1293/
[0] Go to Options > Options > General and enable the checkbox of "Enable experimental features" so as to enable the function of PHP Formatters for Selenium IDE
[1] Levarge the Selenium IDE to create one test case
[2] Click Options > Format > PHP(PHPUnit) to generate the PHPUnit test code based on the created test case. (You will be prompted with a warning message, just click OK to continue)
[3] In the Selenium IDE, click the Source tab next to the Table tab. You will see the PHP test codes generated.
[4] Save these generate PHP test codes in the proper PHP file.
[5] Open the cmd.exe and make sure the Selenium server in on
[6] Type the command > phpunit /path/to/the_saved_php_test_code_file to execute the Selenium test on PHPUnit
}
Tips : {
* Shutdown the Selenium server : {
> Selenium server operates a web server under Jetty it can receive commands via http through browsers. The following URL will be used to shut down the server => http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer
> If we want to leave the server running and just close down the current session we could issue the following URL in a browser => http://localhost:4444/selenium-server/driver/?cmd=shutDown
}
}
- Mar 11 Tue 2014 15:50
-
[UX] Users as Co-creators: Player-centric Game Design
http://www.usabilityprofessionals.org/uxmagazine/users-as-co-creators/?utm_source=feedly&utm_reader=feedly&utm_medium=rss&utm_campaign=users-as-co-creators
- Mar 11 Tue 2014 15:46
-
[UX] Why UX design can make or break your game
From: http://www.develop-online.net/opinions/why-good-user-experience-design-in-games-is-no-longer-a-luxury/0189456
-------------------------------------------------------------
Ella Romanos & Martin Darby on why UX design can make or break your game
[Ella Romanos is the CEO of Remode and former programmer and UX designer. Martin Darby is the CCO of Remode and the company’s game director and designer. www.remodestudios.com]
It used to be simple. In the 1980s, most games were played on arcade machines or early iterations of consoles. The game mechanics and the design were straightforward out of necessity – the limited graphics and computing power wouldn’t allow for much else.
From 1990s onwards, game play shifted to PCs and games became more complicated, like The Sims, Command & Conquer and Dune II, encouraging deep engagement from the player. Over the last few years, things became even more complex as players moved online and genres such as MMOs evolved.
While hardcore PC and console gamers remain enthusiasts who are likely to dedicate themselves to a game, newer platforms online and on mobile are more available to casual gamers, who want quick access, convenience, and as little upfront commitment as possible before being able to enjoy and feel rewarded by their experience. For these gamers, user experience (UX) design will make or break a game, and while all games can benefit from better UX design, this is particularly the case with UI heavy genres like MMOs, sims, strategy games and social games.
What is UX and why is it important?
UX design is neither game design nor UI design. It’s a separate but intrinsically linked role, because it holds UI and game design together, providing the glue for the game you are making. It should be the starting point for any game design, and the blueprint from which everything else is created. Just as you would get an architect, not a builder to design your building, so a UX designer is comparable to an architect, creating a user journey for the player. And just like the most effective architectural planning, the best UX design is the one where the user doesn’t even notice it, removing any friction between the player and the fun they’re having with the game.
The challenge of UX design is that simplicity is complicated. UX design involves several steps, the key ones being:
Defining project goals and user needs
Functional specification (key feature breakdown)
Interaction design (user flow diagrams)
Interface design (wireframes)
Visual design (created by a 2D/UI artist, from the wireframes)
Most of the research and processes for UX have been developed outside of the games industry, primarily in web and software development. Having come from a web background, we brought these processes to our game development process naturally, not quite realising that it wasn’t the norm in our industry. We still use web UX books and resources to train our staff, as there is very little about UX design directly related to games.
There are now companies like Player Research, who offer brilliant user research services and playtesting. The work that they do supports and enhances your UX design process, but does not replace it. If you can afford to hire a company like Player Research, we highly recommend it, having worked with them ourselves, but this article focuses on the UX process that you can implement in your own studio.
Effective UX design: what you need to know
1. UX design takes a different mindset, and skillset, to game design. That is not to say a game designer cannot be a UX designer, but being good at game design does not necessarily equate to being good at UX design. UX design is definitive; it produces a blueprint from which to develop the game system. By comparison game design is open-ended and requires iteration as it evolves over the development process. Therefore, UX design should be treated as a separate task to game design, but they need to work closely together to complement and strengthen each other.
2. UX design is not something you bolt on to a good game idea, or do as an afterthought after you do your game design, or create some user flows or wireframes to add into your game design document. It’s a fundamental way of approaching your entire design and production pipeline that starts right from the initial game idea and follows through to release.
3. A UX design process should make your game design documentation better. There is always debate about GDDs being relevant or not. The way we approach game design is to think of the document being made up of two things:
The user flows, which come from the UX designer
The rule set, which comes from the game designer
The user flows provide the fundamental basis for our GDDs, the rule set is created around that. You can then move onto more detail, like wireframes from the UX designer, which leads into the visual design of the UI (from your UI artist). Creating a GDD this way allows for the rule set to be broadly designed, but allows for iteration and changes during the development process, whilst have a structure to work from that keeps the game focused, reducing risk of scope creep and major flaws in the overall game design.
4. A good UX designer needs to have a certain set of skills and what we refer to as “systems thinking” – an ability to map out complex systems in their head. He or she is the sort of person who uses every day things and gets frustrated if the user experience isn’t quite perfect, whether it’s the fact that light switches are not aesthetic, or that doors that need to be pushed have handles. Your UX designer needs to not just have an extreme attention to detail but also be driven to find the simplest solution to each problem.
5. This brings us to the final point and that is programmers vs UX designers. In one sense, programmers can make great UX designers, and this is how Ella moved into UX design. They can actually be a better fit for the role than game designers, because they have the same problem solving and attention to detail traits. However, there is a natural conflict between what is best for the user, and what is the easiest way to code, which can only be solved if you have two separate entities working from and representing each point of view. The way we approach this is to never allow the same person to program and do UX design on a project, even if they have the ability to do both.
Further reading:
The Elements of User Experience Design – Jesse J Garrett
The Inmates are Running the Asylum – Alan Cooper
The Design of Everyday Things – Donald Norman
How the Mind Works – Steven Pinker
-------------------------------------------------------------
Ella Romanos & Martin Darby on why UX design can make or break your game
[Ella Romanos is the CEO of Remode and former programmer and UX designer. Martin Darby is the CCO of Remode and the company’s game director and designer. www.remodestudios.com]
It used to be simple. In the 1980s, most games were played on arcade machines or early iterations of consoles. The game mechanics and the design were straightforward out of necessity – the limited graphics and computing power wouldn’t allow for much else.
From 1990s onwards, game play shifted to PCs and games became more complicated, like The Sims, Command & Conquer and Dune II, encouraging deep engagement from the player. Over the last few years, things became even more complex as players moved online and genres such as MMOs evolved.
While hardcore PC and console gamers remain enthusiasts who are likely to dedicate themselves to a game, newer platforms online and on mobile are more available to casual gamers, who want quick access, convenience, and as little upfront commitment as possible before being able to enjoy and feel rewarded by their experience. For these gamers, user experience (UX) design will make or break a game, and while all games can benefit from better UX design, this is particularly the case with UI heavy genres like MMOs, sims, strategy games and social games.
What is UX and why is it important?
UX design is neither game design nor UI design. It’s a separate but intrinsically linked role, because it holds UI and game design together, providing the glue for the game you are making. It should be the starting point for any game design, and the blueprint from which everything else is created. Just as you would get an architect, not a builder to design your building, so a UX designer is comparable to an architect, creating a user journey for the player. And just like the most effective architectural planning, the best UX design is the one where the user doesn’t even notice it, removing any friction between the player and the fun they’re having with the game.
The challenge of UX design is that simplicity is complicated. UX design involves several steps, the key ones being:
Most of the research and processes for UX have been developed outside of the games industry, primarily in web and software development. Having come from a web background, we brought these processes to our game development process naturally, not quite realising that it wasn’t the norm in our industry. We still use web UX books and resources to train our staff, as there is very little about UX design directly related to games.
There are now companies like Player Research, who offer brilliant user research services and playtesting. The work that they do supports and enhances your UX design process, but does not replace it. If you can afford to hire a company like Player Research, we highly recommend it, having worked with them ourselves, but this article focuses on the UX process that you can implement in your own studio.
Effective UX design: what you need to know
1. UX design takes a different mindset, and skillset, to game design. That is not to say a game designer cannot be a UX designer, but being good at game design does not necessarily equate to being good at UX design. UX design is definitive; it produces a blueprint from which to develop the game system. By comparison game design is open-ended and requires iteration as it evolves over the development process. Therefore, UX design should be treated as a separate task to game design, but they need to work closely together to complement and strengthen each other.
2. UX design is not something you bolt on to a good game idea, or do as an afterthought after you do your game design, or create some user flows or wireframes to add into your game design document. It’s a fundamental way of approaching your entire design and production pipeline that starts right from the initial game idea and follows through to release.
3. A UX design process should make your game design documentation better. There is always debate about GDDs being relevant or not. The way we approach game design is to think of the document being made up of two things:
The user flows provide the fundamental basis for our GDDs, the rule set is created around that. You can then move onto more detail, like wireframes from the UX designer, which leads into the visual design of the UI (from your UI artist). Creating a GDD this way allows for the rule set to be broadly designed, but allows for iteration and changes during the development process, whilst have a structure to work from that keeps the game focused, reducing risk of scope creep and major flaws in the overall game design.
4. A good UX designer needs to have a certain set of skills and what we refer to as “systems thinking” – an ability to map out complex systems in their head. He or she is the sort of person who uses every day things and gets frustrated if the user experience isn’t quite perfect, whether it’s the fact that light switches are not aesthetic, or that doors that need to be pushed have handles. Your UX designer needs to not just have an extreme attention to detail but also be driven to find the simplest solution to each problem.
5. This brings us to the final point and that is programmers vs UX designers. In one sense, programmers can make great UX designers, and this is how Ella moved into UX design. They can actually be a better fit for the role than game designers, because they have the same problem solving and attention to detail traits. However, there is a natural conflict between what is best for the user, and what is the easiest way to code, which can only be solved if you have two separate entities working from and representing each point of view. The way we approach this is to never allow the same person to program and do UX design on a project, even if they have the ability to do both.
Further reading:
The Elements of User Experience Design – Jesse J Garrett
The Inmates are Running the Asylum – Alan Cooper
The Design of Everyday Things – Donald Norman
How the Mind Works – Steven Pinker
- Feb 23 Sun 2014 20:05
-
[CS] Unit Testing Fundamentals
From: http://java.dzone.com/articles/unit-testing-fundamentals
--------------------------------------------------------------------------------
This article describes the principles of unit testing, rather than the technical details. It's aimed at beginners. Experienced unit-testers will get little from it, except perhaps the pleasure of pointing out mistakes.
(Edit: a few sentences redrafted as a result of the mistakes that were pointed out. ;-)
--------------------------------------------------------------------------------
This article describes the principles of unit testing, rather than the technical details. It's aimed at beginners. Experienced unit-testers will get little from it, except perhaps the pleasure of pointing out mistakes.
(Edit: a few sentences redrafted as a result of the mistakes that were pointed out. ;-)
- Feb 23 Sun 2014 19:51
-
[CS] 12 Unit Testing Tips for Software Engineers
From: http://readwrite.com/2008/08/13/12_unit_testing_tips_for_software_engineers#awesm=~owGUSURL9EcRcG
--------------------------------------------------------------
1. Unit Test to Manage Your Risk
A newbie might ask Why should I write tests? Indeed, aren't tests boring stuff that software engineers want to outsource to those QA guys? That's a mentality that no longer has a place in modern software engineering. The goal of software teams is to produce software of the highest quality. Consumers and business users were rightly intolerant of buggy software of the 80s and 90s. But with the abundance of libraries, web services and integrated development environments that support refactoring and unit testing, there's now no excuse for software with bugs.
--------------------------------------------------------------
1. Unit Test to Manage Your Risk
A newbie might ask Why should I write tests? Indeed, aren't tests boring stuff that software engineers want to outsource to those QA guys? That's a mentality that no longer has a place in modern software engineering. The goal of software teams is to produce software of the highest quality. Consumers and business users were rightly intolerant of buggy software of the 80s and 90s. But with the abundance of libraries, web services and integrated development environments that support refactoring and unit testing, there's now no excuse for software with bugs.
- Jan 20 Mon 2014 10:18
-
[Design] 21 Most Used Fonts By Professional Designers
http://www.instantshift.com/2008/10/05/21-most-used-fonts-by-professional-designers/
1. Helvetica
2. Frutiger
3. Myriad Pro
1. Helvetica
2. Frutiger
3. Myriad Pro
- Jan 17 Fri 2014 00:49
-
[CSS] 純CSS解決div垂直置中

Reference: http://blog.yam.com/hanasan/article/35806444 & http://blog.yam.com/hanasan/article/85889063
---------------------------------------------------------------------------------------------------------------------------------
方法一
- Jan 05 Sun 2014 02:25
-
[WEB] A Standards Based Approach to Comet Communication with REST
By Kris Zyp: http://cometdaily.com/2007/12/27/a-standards-based-approach-to-comet-communication-with-rest/
-------------------------------------------------------------
The HTTP protocol is the basis of the web, and provides many powerful capabilities for building Comet communication. In particular, HTTP is built on the principals of Representational State Transfer (REST). The REST concepts that underlie HTTP facilitate important scalability capabilities for agents that choose to take advantage of them, and enable meaningful communication about resources, which can benefit Comet usage. Comet was not specifically incorporated into HTTP, but HTTP provides a powerful vocabulary that can provide a substantial foundation for Comet communication. I propose an approach for RESTful Comet that would utilize the existing HTTP 1.1 and MIME standards as much as possible. This approach has important implications for future scalability possibilities, proxy service utilization, and REST data/messaging interaction. This approach maintains the critical HTTP principle of statelessness which reduces server resource consumption. This proposal can be integrated into proxy servers to provide increased scalability through distributed messaging with HTTP proxy servers. It could also even be utilized by proxy servers to maintain fresher caches independently of Comet applications.
A Simple HTTP Comet Protocol for Single Resources
For simple single resource HTTP GETs, it is possible to add a single simple header and provide a very intuitive technique for using Comet with a single resource that maintains the principles of HTTP. A “When-Modified-After” header is defined on a GET request that instructs an HTTP server that it should not respond to a request until a modification to a resource is made. The value of the header should be a time stamp, indicated the point in time after which new data should trigger a response. If a modification has already been made since the given time stamp, the server should immediately respond to the request with the current resource using a standard HTTP response. If there have been no modifications to the resource since the given “When-Modified-After” date, then the server should wait until a modification is made before responding to the request (with a standard HTTP response). The response should include a standard “Last-Modified” date, so the client knows what date value to use for the next “When-Modified-After” date to resume monitoring.
Using this simple extension to standard HTTP protocol, a client can create a connection and issue a request that stays open, and the response will not occur until a change has been made to the resource. This is effectively a long-polling Comet connection for monitoring a single resource. Here is an example:
In the meantime, suppose the resource content is replaced with “Hello World!”, which triggers the monitored resource response below:
One very useful application of this approach would be for monitoring an Atom feed. Rather than polling for changes in an Atom feed, a newsreader client could issue a request with a “When-Modified-After” header, and the connection would remain open and waiting for a response until a new Atom entry was added.
REST Methods
While we can simply return a standard HTTP 200 (OK) response to provide an updated copy of the current resource, the REST concepts behind HTTP provide the impetus for a wider vocabulary of HTTP responses, which yields more flexible and efficient communication of resource modifications. When a resource is deleted while monitoring, a 404 (Not Found) response can be used to indicate that the resource has been removed. When data has been appended to a resource while monitoring, the HTTP range capabilities can be utilized to return a 206 (Partial Content) response. A 404 response is very simple, but returning partial content in a response is a bit more nuanced. A response may only return a 206 if the request has included a Range header indicating what range is desired. By including a Range header specifying the range units and range, a request can make it known that a 206 response is acceptable and which range units are acceptable. However, a Range header alone should only receive a successful response of 206 (not 200). In order to allow a 200 or a 206 response, the If-Range header can be used conditionally allow for a 200 or a 206 response, but with resource monitoring, the If-Range header as defined by HTTP is not useful. The condition for selecting between a 200 or a 206 response is based on the date of the resource, where resource monitoring should select the response type based on whether the resource had been modified in such a way that a partial content delivery is applicable. Therefore, I propose that combining the When-Modified-After header with the Range header should indicate that both 200 and 206 responses are acceptable and the selection should be based on the utility of a 206 response in communicating the modification. The HTTP specifications define a range unit of bytes. Below is an example:
In the meantime, suppose the string “How are you?” was appended to the resource’s content. This action triggers the monitored resource response below:
With allowance for conditional 206 responses, monitored resource HTTP response codes have a correspondence to their causal HTTP method verbs:
PUT action -> 200 - full resource content replacement results in a 200 full content response for monitoring request)
DELETE action -> 404 - deletion of a resource results in a 404 response for monitoring request)
POST action -> 206 - if the POST results in simple appending or replacement of data to the resource, and the response modification can be described with a content range, the result is a 206 response. Otherwise a full content 200 response may be necessary.
The byte range units may not be the most appropriate range unit for many modern format types. While the HTTP specification only defines the byte range unit, it allows for other range units. For modern data formats such as XML/Atom and JSON, the alternate range unit “updated” defined by the Atom Publishing Protocol is generally preferable. Let us consider the case of an Atom feed. When a new news entry is added to an Atom feed, it does not result in data being appended to the end of the content; instead the entry is embedded in the XML file. However, we can easily use a updated range unit to efficiently communicate the addition of a new entry:
In the meantime a new entry is added to the Atom feed, triggering this response:
Streaming for Resource Monitoring
In a simple implementation of the “When-Modified-After” approach, the response will be a standard HTTP response to a GET request, which will end the HTTP conversation. To resume monitoring, a new HTTP request needs to be issued. However, it may often be preferable to keep the HTTP response alive and indefinitely continue to receive updates on a resource rather than only receiving a single update. The HTTP protocol is designed for streaming data (in particular with chunked encoding). However, it is still necessary to have some protocol for the partitioning of update messages from the data stream. Here the MIME standard provides standards-based direction for coherent segmentation. We can use multipart/mixed to break the stream into individual resource updates. In particular, we can use the multiplepart/mixed variant MIME type of multipart/mixed-replace, which indicates that each message is intended to be a replacement for the resource, superseding the previous message. When a 200 response is provided, the HTTP response can remain open indefinitely receiving new updates/replacements to the resource. This MIME type, in particular, has received attention for Comet because of Firefox’s support for it in its XmlHttpRequest object.
The multipart/mixed-replace is limiting, lacking the ability to transfer REST information with each update. The parts of the multipart/mixed MIME type are defined to only contain the content and content-type. Each update must be full replacement; partial content and deletion updates can not be included. However, another MIME type is applicable for this purpose. The multipart/digest MIME type is for sending whole messages as the parts of the outer message. While the MIME protocol defines its usage for email messages as being embedded email messages, it is easily inferred that in a different context such as HTTP, the parts would be the same type as the outer message, in this case HTTP response messages. Therefore a monitoring response could consist of a content stream of the multipart/digest type and contain within it multiple HTTP response messages with their own status codes, headers, and content.
Some browsers engines (Gecko, WebKit, and Opera) support incremental loading through XmlHttpRequest, but Internet Explorer does not. Without incremental loading, using a multipart response to provide a stream of data that remains open for future messages is problematic. If the stream stays open, an IE XHR request will not return until the response is finished. Therefore content negotiation via the Accept header should be used to indicate the browser’s preference for multipart. For example, a client that can handle multipart/digest and multipart/mixed-replace may send an Accept header on Firefox to indicate that multipart/digest (for the purpose of streaming) is preferred:
And in Internet Explorer it could send:
When multipart/digest is a lower preference than the default content type, it can be assumed that no advantage is provided through multipart streaming (because the client does not support incremental loading).
Monitoring Multiple Resources with One Connection
If each resource requires its own HTTP request/response connection, we will quickly encounter scalability problems when attempting to monitor multiple resources. Here again, the multipart/digest type can rescue us with a means to deliver multiple HTTP requests in one HTTP request. The Content-Type of an HTTP request can be set to multipart/digest, and then multiple requests can be included in the body of the HTTP request using the MIME multipart definition. It may be useful when sending a request that encapsulates multiple monitoring requests to designate a single location as the target for these types of requests. For now, I will suggest “/subscribe”. I would also suggest that one can assume that the sub-requests can conceptually inherit headers from their parent request.
This technique does introduce a problem in correlating responses with requests. In HTTP, responses are normally correlated to requests simply by their TCP/IP connection, but when sending multiple HTTP requests embedded within a single HTTP request, this clearly is not adequate. In this case responses must use the HTTP Content-Location header to indicate what resource the HTTP response message is referring to. It is important to note that using multipart/digest type to encapsulate multiple responses in a single response does not necessitate multipart requests, nor vice versa. Request and response multiparts can be used independently or in combination. A multipart request can receive a single response, a single request can receive a multipart stream of response messages, and a multipart request can receive a multipart stream response.
Now let us look at an example incorporating these ideas. The following request encompasses two requests that indicate that the
The response will now send parts of the content stream as resource modifications take place.
after a news event occurred:
after the weather update:
if the news feed is deleted, this would occur:
Message Delivery Reliability with Incremental Time
Rather than relying on a stateful session to reliably receive a stream of messages, this proposal relies on time segments to define message delivery. When an agent subscribes to a Comet resource, the agent provides a beginning timestamp in the When-Modified-After header (which is normally the current time). When a response message arrives, the response message must include a timestamp (in the Last-Modified header or the Content-Range header if it is using a dated range). The agent can then be assured that it has received all (relevant) messages up to that timestamp. If the connection is broken (or ended in the case of long-polling), the agent can send the last timestamp in the When-Modified-After request header when reconnecting to the server. If another message that should be sent to the client was triggered while the connection was broken, the server can immediately fulfill the request; if no messages are ready to be sent, the server can wait for the next available message. If a server sends a message but the client does not receive it due to a broken connection, the client can still resume the connection with the previous timestamp. This technique allows clients to seamlessly receive all messages for a given timeframe even with an unreliable underlying connection. Furthermore this technique does not rely on a session and is therefore not prone to session timeouts and unnecessary server resource utilization.
An implication of this technique is that it is necessary for servers and clients to be capable of giving every message a unique timestamp. Therefore, servers must be able to assign timestamps with decimals for the seconds and provide a means for continually incrementing the timestamp for uniqueness when multiple messages are prepared within a single second.
Publish/Subscribe Messaging
A publish/subscribe event-based messaging system can still be handled with this approach. This type of system is important for some applications like a chat application. A resource can be treated like a pub/sub channel, and subscribing to a channel is done by monitoring a resource as described above. Messages can be published by posting to a resource using the HTTP POST method. A POST, as the HTTP protocol suggests, can imply appending a record/message to the resource. This can easily translate into the message being broadcast to all resource subscribers as 206 Partial Content messages. In this way the message can be published and subscribers will receive it.
Authentication
Since this proposal is basically an interpretation of the HTTP/1.1 specification for Comet, one can naturally use existing HTTP means for authentication, including the authentication scheme defined in the HTTP specification or alternate application level security that may use cookies or other methods for authentication.
Conclusion
This proposal for using existing different definitions in the HTTP tool set with minimal addition provides a standards-based approach for Comet with integrated REST resource interaction. Only one necessary addition is defined here (When-Modified-After)—everything else is leveraging existing standards. While there may be other approaches that are less verbose and more efficient for particular applications, I believe an approach like this that relies on existing standards and includes the capabilities for interacting with highly scalable world of RESTful resources has potential for significantly improving the interoperability of Comet applications and their integration with RESTful data services. I would like to follow up on this with some more discussion of practicalities like browser limitations, optimizations, globbing, and making this work with other transports like streaming iframes and JSONP scripts.
-------------------------------------------------------------
The HTTP protocol is the basis of the web, and provides many powerful capabilities for building Comet communication. In particular, HTTP is built on the principals of Representational State Transfer (REST). The REST concepts that underlie HTTP facilitate important scalability capabilities for agents that choose to take advantage of them, and enable meaningful communication about resources, which can benefit Comet usage. Comet was not specifically incorporated into HTTP, but HTTP provides a powerful vocabulary that can provide a substantial foundation for Comet communication. I propose an approach for RESTful Comet that would utilize the existing HTTP 1.1 and MIME standards as much as possible. This approach has important implications for future scalability possibilities, proxy service utilization, and REST data/messaging interaction. This approach maintains the critical HTTP principle of statelessness which reduces server resource consumption. This proposal can be integrated into proxy servers to provide increased scalability through distributed messaging with HTTP proxy servers. It could also even be utilized by proxy servers to maintain fresher caches independently of Comet applications.
A Simple HTTP Comet Protocol for Single Resources
For simple single resource HTTP GETs, it is possible to add a single simple header and provide a very intuitive technique for using Comet with a single resource that maintains the principles of HTTP. A “When-Modified-After” header is defined on a GET request that instructs an HTTP server that it should not respond to a request until a modification to a resource is made. The value of the header should be a time stamp, indicated the point in time after which new data should trigger a response. If a modification has already been made since the given time stamp, the server should immediately respond to the request with the current resource using a standard HTTP response. If there have been no modifications to the resource since the given “When-Modified-After” date, then the server should wait until a modification is made before responding to the request (with a standard HTTP response). The response should include a standard “Last-Modified” date, so the client knows what date value to use for the next “When-Modified-After” date to resume monitoring.
Using this simple extension to standard HTTP protocol, a client can create a connection and issue a request that stays open, and the response will not occur until a change has been made to the resource. This is effectively a long-polling Comet connection for monitoring a single resource. Here is an example:
-->
GET /myResource HTTP/1.1
Accept: */*
When-Modified-After: Wed, 26 Dec 2007 16:00:15 GMT
In the meantime, suppose the resource content is replaced with “Hello World!”, which triggers the monitored resource response below:
<--
HTTP/1.1 200 OK
Last-Modified: Wed, 26 Dec 2007 18:00:15 GMTHello World!
One very useful application of this approach would be for monitoring an Atom feed. Rather than polling for changes in an Atom feed, a newsreader client could issue a request with a “When-Modified-After” header, and the connection would remain open and waiting for a response until a new Atom entry was added.
REST Methods
While we can simply return a standard HTTP 200 (OK) response to provide an updated copy of the current resource, the REST concepts behind HTTP provide the impetus for a wider vocabulary of HTTP responses, which yields more flexible and efficient communication of resource modifications. When a resource is deleted while monitoring, a 404 (Not Found) response can be used to indicate that the resource has been removed. When data has been appended to a resource while monitoring, the HTTP range capabilities can be utilized to return a 206 (Partial Content) response. A 404 response is very simple, but returning partial content in a response is a bit more nuanced. A response may only return a 206 if the request has included a Range header indicating what range is desired. By including a Range header specifying the range units and range, a request can make it known that a 206 response is acceptable and which range units are acceptable. However, a Range header alone should only receive a successful response of 206 (not 200). In order to allow a 200 or a 206 response, the If-Range header can be used conditionally allow for a 200 or a 206 response, but with resource monitoring, the If-Range header as defined by HTTP is not useful. The condition for selecting between a 200 or a 206 response is based on the date of the resource, where resource monitoring should select the response type based on whether the resource had been modified in such a way that a partial content delivery is applicable. Therefore, I propose that combining the When-Modified-After header with the Range header should indicate that both 200 and 206 responses are acceptable and the selection should be based on the utility of a 206 response in communicating the modification. The HTTP specifications define a range unit of bytes. Below is an example:
-->
GET /myResource HTTP/1.1
Accept: */*
When-Modified-After: Wed, 26 Dec 2007 16:00:15 GMT
Range: bytes 12-/* This indicates that the bytes after byte 12 (the current end of the resource) should be returned
In the meantime, suppose the string “How are you?” was appended to the resource’s content. This action triggers the monitored resource response below:
<--
HTTP/1.1 206 OK
Content-Range: bytes 12-23/24
How are you?
With allowance for conditional 206 responses, monitored resource HTTP response codes have a correspondence to their causal HTTP method verbs:
The byte range units may not be the most appropriate range unit for many modern format types. While the HTTP specification only defines the byte range unit, it allows for other range units. For modern data formats such as XML/Atom and JSON, the alternate range unit “updated” defined by the Atom Publishing Protocol is generally preferable. Let us consider the case of an Atom feed. When a new news entry is added to an Atom feed, it does not result in data being appended to the end of the content; instead the entry is embedded in the XML file. However, we can easily use a updated range unit to efficiently communicate the addition of a new entry:
GET /myAtomFeed HTTP/1.1
Accept: */*
When-Modified-After: Wed, 26 Dec 2007 16:00:15 GMT
Range: updated Wed, 26 Dec 2007 16:00:15 GMT-/*
In the meantime a new entry is added to the Atom feed, triggering this response:
HTTP/1.1 206 Partial Content
Content-Range: updated Wed, 26 Dec 2007 16:00:15 GMT-/Wed, 26 Dec 2007 20:00:25 GMT
<?xml version="1.0" encoding="UTF-8"?>
<feed>
<entry>
<title>REST Comet Protocol Possibilities</title>
<author>Kris Zyp</author>
<published>2007-12-26T20:00:25Z</published>
<content>...</content>
</entry>
</feed>
Streaming for Resource Monitoring
In a simple implementation of the “When-Modified-After” approach, the response will be a standard HTTP response to a GET request, which will end the HTTP conversation. To resume monitoring, a new HTTP request needs to be issued. However, it may often be preferable to keep the HTTP response alive and indefinitely continue to receive updates on a resource rather than only receiving a single update. The HTTP protocol is designed for streaming data (in particular with chunked encoding). However, it is still necessary to have some protocol for the partitioning of update messages from the data stream. Here the MIME standard provides standards-based direction for coherent segmentation. We can use multipart/mixed to break the stream into individual resource updates. In particular, we can use the multiplepart/mixed variant MIME type of multipart/mixed-replace, which indicates that each message is intended to be a replacement for the resource, superseding the previous message. When a 200 response is provided, the HTTP response can remain open indefinitely receiving new updates/replacements to the resource. This MIME type, in particular, has received attention for Comet because of Firefox’s support for it in its XmlHttpRequest object.
The multipart/mixed-replace is limiting, lacking the ability to transfer REST information with each update. The parts of the multipart/mixed MIME type are defined to only contain the content and content-type. Each update must be full replacement; partial content and deletion updates can not be included. However, another MIME type is applicable for this purpose. The multipart/digest MIME type is for sending whole messages as the parts of the outer message. While the MIME protocol defines its usage for email messages as being embedded email messages, it is easily inferred that in a different context such as HTTP, the parts would be the same type as the outer message, in this case HTTP response messages. Therefore a monitoring response could consist of a content stream of the multipart/digest type and contain within it multiple HTTP response messages with their own status codes, headers, and content.
Some browsers engines (Gecko, WebKit, and Opera) support incremental loading through XmlHttpRequest, but Internet Explorer does not. Without incremental loading, using a multipart response to provide a stream of data that remains open for future messages is problematic. If the stream stays open, an IE XHR request will not return until the response is finished. Therefore content negotiation via the Accept header should be used to indicate the browser’s preference for multipart. For example, a client that can handle multipart/digest and multipart/mixed-replace may send an Accept header on Firefox to indicate that multipart/digest (for the purpose of streaming) is preferred:
Accept: multipart/digest, multipart/mixed-replace;q=0.7, */*;q=0.5And in Internet Explorer it could send:
Accept: */*, multipart/digest;q=0.5When multipart/digest is a lower preference than the default content type, it can be assumed that no advantage is provided through multipart streaming (because the client does not support incremental loading).
Monitoring Multiple Resources with One Connection
If each resource requires its own HTTP request/response connection, we will quickly encounter scalability problems when attempting to monitor multiple resources. Here again, the multipart/digest type can rescue us with a means to deliver multiple HTTP requests in one HTTP request. The Content-Type of an HTTP request can be set to multipart/digest, and then multiple requests can be included in the body of the HTTP request using the MIME multipart definition. It may be useful when sending a request that encapsulates multiple monitoring requests to designate a single location as the target for these types of requests. For now, I will suggest “/subscribe”. I would also suggest that one can assume that the sub-requests can conceptually inherit headers from their parent request.
This technique does introduce a problem in correlating responses with requests. In HTTP, responses are normally correlated to requests simply by their TCP/IP connection, but when sending multiple HTTP requests embedded within a single HTTP request, this clearly is not adequate. In this case responses must use the HTTP Content-Location header to indicate what resource the HTTP response message is referring to. It is important to note that using multipart/digest type to encapsulate multiple responses in a single response does not necessitate multipart requests, nor vice versa. Request and response multiparts can be used independently or in combination. A multipart request can receive a single response, a single request can receive a multipart stream of response messages, and a multipart request can receive a multipart stream response.
Now let us look at an example incorporating these ideas. The following request encompasses two requests that indicate that the
/news and /weather resources should be subscribed to or monitored:
-->
POST /subscribe HTTP/1.1
Accept: multipart/digest, multipart/mixed-replace;q=0.7, */*;q=0.5
When-Modified-After: Wed, 26 Dec 2007 16:00:15 GMT
Content-Type: multipart/digest; boundary=separation
--separation
GET /weather
Range: updated Wed, 26 Dec 2007 16:00:15 GMT-/*
--separation
GET /news
Range: updated Wed, 26 Dec 2007 16:00:15 GMT-/*
--separationThe response will now send parts of the content stream as resource modifications take place.
<--
HTTP/1.1 200 OK
Content-Type: multipart/digest; boundary=separation
Transfer-Encoding: chunked
after a news event occurred:
50; chunked encoding length
–separation
HTTP/1.1 206 Partial Content append to the news stories
Content-Location: /news
Content-Type: text/xml
Content-Range: updated Wed, 26 Dec 2007 16:00:15 GMT-/Wed, 26 Dec 2007 20:00:25 GMT<?xml version="1.0" encoding="UTF-8"?>
<feed><entry><title>Big news today...</title>....</entry></feed>--separation
after the weather update:
30
HTTP/1.1 200 OK replace the old weather report
Content-Type: text/plain
Content-Location: /weatherNew weather report: Sunny weather ahead.--separation
if the news feed is deleted, this would occur:
20
HTTP/1.1 404 Not Found
Content-Location: /news--separation
Message Delivery Reliability with Incremental Time
Rather than relying on a stateful session to reliably receive a stream of messages, this proposal relies on time segments to define message delivery. When an agent subscribes to a Comet resource, the agent provides a beginning timestamp in the When-Modified-After header (which is normally the current time). When a response message arrives, the response message must include a timestamp (in the Last-Modified header or the Content-Range header if it is using a dated range). The agent can then be assured that it has received all (relevant) messages up to that timestamp. If the connection is broken (or ended in the case of long-polling), the agent can send the last timestamp in the When-Modified-After request header when reconnecting to the server. If another message that should be sent to the client was triggered while the connection was broken, the server can immediately fulfill the request; if no messages are ready to be sent, the server can wait for the next available message. If a server sends a message but the client does not receive it due to a broken connection, the client can still resume the connection with the previous timestamp. This technique allows clients to seamlessly receive all messages for a given timeframe even with an unreliable underlying connection. Furthermore this technique does not rely on a session and is therefore not prone to session timeouts and unnecessary server resource utilization.
An implication of this technique is that it is necessary for servers and clients to be capable of giving every message a unique timestamp. Therefore, servers must be able to assign timestamps with decimals for the seconds and provide a means for continually incrementing the timestamp for uniqueness when multiple messages are prepared within a single second.
Publish/Subscribe Messaging
A publish/subscribe event-based messaging system can still be handled with this approach. This type of system is important for some applications like a chat application. A resource can be treated like a pub/sub channel, and subscribing to a channel is done by monitoring a resource as described above. Messages can be published by posting to a resource using the HTTP POST method. A POST, as the HTTP protocol suggests, can imply appending a record/message to the resource. This can easily translate into the message being broadcast to all resource subscribers as 206 Partial Content messages. In this way the message can be published and subscribers will receive it.
Authentication
Since this proposal is basically an interpretation of the HTTP/1.1 specification for Comet, one can naturally use existing HTTP means for authentication, including the authentication scheme defined in the HTTP specification or alternate application level security that may use cookies or other methods for authentication.
Conclusion
This proposal for using existing different definitions in the HTTP tool set with minimal addition provides a standards-based approach for Comet with integrated REST resource interaction. Only one necessary addition is defined here (When-Modified-After)—everything else is leveraging existing standards. While there may be other approaches that are less verbose and more efficient for particular applications, I believe an approach like this that relies on existing standards and includes the capabilities for interacting with highly scalable world of RESTful resources has potential for significantly improving the interoperability of Comet applications and their integration with RESTful data services. I would like to follow up on this with some more discussion of practicalities like browser limitations, optimizations, globbing, and making this work with other transports like streaming iframes and JSONP scripts.
- Sep 01 Sun 2013 23:47
-
[CS] UTF-8 with/without BOM
ANSI和Unicode、UTF-8和UTF-16、BOM
http://dnowba.blogspot.tw/2012/07/ansiunicodeutf-8utf-16bom.html
What is “ANSI as UTF-8” and how can I make fputcsv() generate UTF-8 w/BOM?
- Jul 16 Tue 2013 11:24
-
[Linux] 在Linux Mint 上安裝中文輸入
STEP 1 : 開啟 "漢語" 的語言支援
"帳號" > "系統設定值" > "語言支援",之後下載 "漢語" 的相關套件
STEP 2 : 使用Synatic套件管理程式安裝 gcin