Web Chat: Talk to the French Guy
By thomas.ford. Thursday, 9. November 2006, 14:04:33
By thomas.ford. Thursday, 9. November 2006, 14:04:33
By thomas.ford. Monday, 16. October 2006, 00:17:21
By thomas.ford. Monday, 25. September 2006, 16:38:44
By thomas.ford. Tuesday, 19. September 2006, 15:42:18
By virtuelvis. Friday, 1. September 2006, 14:28:56
One cool feature we added to Opera 9 is Server-Sent Events from the WHATWG Web Applications 1.0 specification. Using SSE you can push DOM events continously from your web server to the visitor's browser. This creates a lot of exciting opportunities for web application authors.
Traditionally, when building an Ajax application, the browser continually polls the server, sending requests to the server, asking to get data back, making new HTTP requests for every single poll, putting more strain on the server than needed.
The event streaming approach instead opens a persistent connection to the server, sending data to the client when new information is available, eliminating the need for continuous polling. This method for doing remoting offers a tremendous advantage, since the server no longer has to handle the overhead associated with clients asking for new data. Instead, the server simply sends back data every connected client when appropriate, thus reducing the load on the server, with the added advantage of offering instant feedback to the user.
To provide you with a starting point on how to build your own event streaming application, we have built Opera Web Chat. This is a web based chatroom offering some of the features from the built in to the Opera IRC client. Currently the chat only offers one single chatroom. (A screenshot is available here)
Keep in mind that it is an experimental service, which means it may not always be available for use.
To use Server-Sent Events in a web application, add an <event-source> element to the document, with a src attribute pointing to a event source URL. This URL should provide a persistent HTTP connection that sends a data stream containing the events. The connection must use the content type application/x-dom-event-stream.
It is possible to send events with any name, and specify the properties of the event object. Opera 9.01 only supports the data property of the event, so this is what we are going to use in these examples.
The server side event source writes the events whenever they occur, and sends them over HTTP to the client. This is a basic example of event data. This is more thoroughly explained in the specification.
Event: server-time
data: [time on the server]
Event: the-answer
data: 42
This will send two events to the browser, and it's possible to catch them as DOM events. The following JavaScript example listens for the "server-time" event, and alerts the content.
document.getElementsByTagName("event-source")[0]
.addEventListener("server-time", eventHandler, false);
function eventHandler(event)
{
// Alert time sent by the server
alert(event.data);
}
This is a very simple Python CGI example which sends a new event every 3 seconds. Every event is named "server-time", and sends an event with the data property set to the current time of the server in seconds.
Keep in mind that when a CGI script outputs data, there is no guarantee that it is sent immediately. There are often caching mechanisms and so on in place. For this reason it may be necessary to explicitly flush the output.
Here is the example code written in python.
#!/usr/bin/python
import sys
import time
print "Content-Type: application/x-dom-event-stream\n\n"
while True:
print "Event: server-time"
print "data: %f\n" % (time.time(),)
sys.stdout.flush()
time.sleep(3)
The same example written in PHP:
<?php
header("Content-Type: application/x-dom-event-stream");
while(true) {
echo "Event: server-time\n";
$time = time();
echo "data: $time\n";
echo "\n";
flush();
sleep(3);
}
?>
In addition to the chat application we made, there are lots of different applications that can be made with Server-Sent Events. For instance games or instant messaging clients, such as MSN Messenger, Jabber or AIM. You could also build stock and news tickers, status and log file monitors, or anyhing you can come up with.
What will you build?
By virtuelvis. Wednesday, 21. June 2006, 14:51:09
One of the last additions we made to widgets in the stages before releasing Opera 9.0 was giving widgets the ability to resize and move themselves.
The main use for resizing behavior is in those cases where you want to emulate UI widgets (yes, that other kind of widget) like maximize, restore, and regular resize and drag handlers.
interface Window {
void resizeTo( in int w, in int h );
void resizeBy( in int delta_w, in int delta_h );
void moveTo( in int x, in int y );
void moveBy( in int delta_x , in int delta_y );
};
window.resizeTo()The window.resizeTo() method takes two positive integers as arguments: A width w and height h. These sizes are the desired dimensions of the widgets in pixels, and correspond to the width and height elements in a widget's configuration file. The method sets the window.outerWidth and window.outerHeight properties. Example:
// Resize the widget to 400x300 px
window.resizeTo( 400, 300 );
window.resizeBy()The window.resizeBy method takes two integers as arguments: A delta_w that is the desired change in width, measured in pixels, and a delta_h that is the desired change in height, again measured in pixels. The width and height of the widget is then recalculated to be equivalent to the following pseudocode:
window.resizeTo( window.outerWidth + delta_x, window.outerHeight + delta_y );
In all cases of window resizing, the resizing happens from the lower-right corner of the widget window, while the upper-left corner remains static.
// Grow the widget by 100px horizontally
window.resizeBy( 100, 0 );
window.moveTo()The window.moveTo method takes two integers as arguments: An x that is the desired x coordinate for the upper-left corner of the widget, and an y that is the desired y coordinate for the upper-left corner of the widget, with both values mentioned in pixels.
// Move the widget to the upper-left corner of the screen window.moveTo( 0, 0 )
window.moveBy()The window.resizeBy method takes two integers as arguments: A delta_x that is the desired change in x position, measured in pixels, and a delta_y that is the desired change in y position, again measured in pixels. Both values can be negative. Example:
// Move the 50px left and 50px down window.moveBy( -50, 50 )
If you change these settings for a widget, the settings are volatile, and the change will be lost if the widget is closed and then reopened. This means that if your widget relies on being a certain size, which may be different from the install-time default, you should make sure that you store the widget size in the persistent storage. The widget storage interface is compatible with Apple's interface, using the methods preferenceForKey and setPreferenceForKey.