Everybody knows that there are a number of ways for users to share and organize information in a traditional “desktop” environment. For example, Unix users are used to “piping” output from one program to use as input for another program. Similarly, the average desktop user has grown accustomed to dragging-and-dropping files from one location to another. Both are so familiar to their respective users that they are often taken for granted. We wanted to build an interaction modeled on these more traditional interactions, which would serve as a building block for similar functionality over the web.

Our “pipes” interaction was designed with the goal of allowing web application programmers and average end-users to leverage the massive amounts of data on the web with the simplicity of these more traditional interactions. Web application programmers will appreciate the new ways that their users can integrate information across many different pages. On the client-side, users will appreciate the simplicity with which they can capture and share a variety of elements within a webpage. Even in this early stage, our “pipes” interaction serves as a powerful proof-of-concept of a new way for sharing information on the web.


The front-end design has two main components which allow different users to send and receive information across the web (note that previous links are not integrated with any backend). Together they are meant to simulate the simplicity of drag-and-drop functionality on graphical operating systems, but instead of moving files between folders, our web “pipe” offers users a way to share images from different web pages between many different users. In our demonstration we only transmitted images through our pipes, however, the “piping” functionality could easily be extended to any combination of DOM elements (div tags, for example).

The front-end is built on top of jQuery and can be added to any webpage with the appropriate <script> tags. The “sending” and “receiving” functionality of a pipe make up the two distinct components of the front-end and each component comes with its own custom script built on top of standard jQuery components. Our script on the sender’s webpage will make all of the images draggable, animate each image as it moves off-screen, and post the appropriate information (i.e. sender, receiver, and image source) to the server when any given image finally moves off-screen. Overall, this part of the front-end adds about 50 kB of overhead (jQuery core, 30.3 kB; UI core, 3.66 kB; UI Draggable, 9.36 kB; jquery.physics.0.3, 3.59 kB; custom code, 3.2 kB) to each page after all of the JavaScript has been compressed. The JavaScript for the “receiving” page is even simpler. The code used to receive new images issues an asynchronous call to the server every 2 seconds to check for updates. Every time the client receives a non-empty response, the script parses the response and displays the new images along with the name of the sender by adding rows to a table embedded in the page. This part of the front-end does not do any animation and only requires the jQuery core, which can be compressed to 30.3 kB. The client-side code for “sending” and “receiving” information across our “pipes” is relatively lightweight, unobtrusive, and easily encapsulated through the proper use of HTML <script> tags.

Except for the initial dialog boxes, which prompt the user for the usernames of the sender and the receiver, the end-user may not immediately realize that a page offers our “piping” functionality. The first username prompt corresponds to the name of the sender (i.e. the current user; user A) and the second username prompt corresponds to the name of the user which will be receiving images (user B). If either username is missing, the page is loaded without any additional functionality or alterations. If both usernames are provided, user A has implicitly created a “pipe” from user A to B in the backend database. Note that pipes are directed, meaning that after the aforementioned pipe is created, user A can push information to user B, but user B will not be able to push information to user A. Also note that in the current version, there is no method for authenticating user A and there is no way of verifying that user B actually wants to receive information from user A. Once the pipe has been created, the user may begin dragging images off the page to send them over the pipe. In our code, we have made all of the images draggable using a function provided by jQuery’s “UI Draggable” library:

       start: function(ev, ui) {…},
       stop: function(ev, ui) {…},
       axis: “x”,
       containment: “document”

In general, the “draggable” function is called on an initial nodeset specifying which nodes should be draggable objects on the page and then a number of other options are passed in to further customize the dragging behavior. In our case, we have specified that all “img” tags should be draggable, but we could easily change “img” to be “div” instead. Similarly, we could specify the set of nodes associated with a particular CSS class by changing “img” to “.class,” where “class” is the name of the corresponding CSS class. The “axis” option specifies that dragging should be constrained to the “x” axis and the “containment” option means that the user cannot drag an image beyond the boundaries of the page. Containment is only important, because without it the page would automatically expand (i.e. add scrollbars) when an image was dragged beyond the edge of a page and we were concerned about how this would alter the layout of the rest of the page. Most of the interesting work is done within the “stop” function, which is called after the user stops dragging an image by releasing the mouse click. If the image has moved to the left of its original position, the stop function creates a copy of the image and appends it to the DOM tree at its original position on the page. From this original position, the jQuery physics library is used to assign a velocity to the copy of the image and start a loop (i.e. setInterval()), which animates the image until it moves off-screen. Once the image is off-screen, an asynchronous post request is sent to:

   (“http://localhost:8000/DragAndDrop/put/" + sender + "/" + receiver + "/" + image_url)

and the appropriate tuple is inserted into the backend database. After the data has been sent to the server, another client must retrieve the update by constantly querying the server. In particular, it sends requests to:

   (“http://localhost:8000/DragAndDrop/get/” + receiver)

which returns a JSON object that contains image urls and the name of the sender. The JSON object is parsed and images are added one-by-one to a table using the appendChild() function to add new rows.

Front-end extensionsEdit

The front-end provides a lot of functionality and is easily added to new pages, but is ultimately more of a proof of concept than a final product. First and foremost, any meaningful implementation would have to have a way of authenticating users and connections so that the pipe mechanism is not abused to push undesired images or information to other users. Once the ability to authenticate users is added, it seems like it could be useful to add a number of new features. Pipes could be made more dynamic if the sender (i.e. user A) could send information to multiple users and change which users receive updates without refreshing the page. In particular, we thought that a different recipient could be specified for each edge of the screen. Unfortunately, there did not seem to be any easy way to move images off of the right and bottom edges of the window, because scrollbars were being automatically added by the browser. Currently, if user A would like to change which user(s) he is pushing information to he must refresh the page and fill out the username prompts again, but it would obviously be more convenient if recipients could easily be changed without leaving the page. Our script could make it easy to change usernames by providing a function call to set senders and receivers. In the end, however, the specific way in which users are prompted to create and change recipients is probably best left to the designer of a particular web application since each application will have its own look and feel.

Lastly, the current method for retrieving updates from the server is not ideal. We arbitrarily poll the server every two seconds without any way of knowing how rapidly updates are actually occurring. We may be wasting bandwidth if updates are much less frequent than two seconds or limiting interactivity if new images are arriving much more frequently. Originally, we wanted to use Comet (also known as Reverse AJAX) to maintain a single connection between the server and the recipient. Specifically, we wanted to use an API known as Orbited with Django to allow a server to push information to the client. Orbited would have allowed us to reduce network overhead and provide seamless integration between sender and receiver, regardless of the frequency of updates. However, the technology is relatively new and there was not nearly enough documentation to allow us to learn how to use Orbited in the limited time span that we had.


From the user’s perspective, the backend appears as a “pipe”, a first in first out queue, which moves messages from a sender to a receiver. A new pipe is created by specifying a sender and receiver. If a pipe is already created for that directional pair, the existing pipe will be used instead. On the client-side, the sender then creates messages which are sent down the pipe. If the receiver is currently logged in and polling for updates, the messages are delivered immediately, otherwise the messages begin queuing.

A message is never “removed” from the pipe. In fact, all messages are cached. When a sender places a message in the pipe, it is immediately date stamped. By default, when a receiver requests information from the pipe, the pipe looks up the last time the receiver accessed the pipe and transmits any new information since that last access. Alternatively, the receiver can request all of the messages which have been delivered since the pipe was created. This functionality allows a user to review all of the outdated messages at a later time.

The send and receive actions are backed by two tables in a MySQL database. The first table stores all the messages and associated metadata, including when the message was sent and which channel it was sent over. The channel table stores information about each channel, including which users own the channel and when it was last checked by those users. The pipes functionality can be easily added to any application because it is a Django Application. An application in Django is a self contained set of models, views, and urls that define a set of related functions. An application can then be installed in a Django Project to provide the project with a specific set of features. Thus, a single project can contain many applications. Each application is built so that all paths are relative and name spaces are utilized to prevent naming collisions between different applications.

To install the Pipes application, edit the file in your project directory:


where imgae_share is the name of the project and pipes is the name of the application. When the project is run, all of the needed tables will be made and code placed in the right place. With this turn-key functionality, the project can now start piping data between browsers.


Pipes are a very reusable component because they can be used to transmit any type of information. The functionality of pipes affords itself well to being encapsulated because it can run on top of an already existing application.

Of course pipes are not just easily encapsulated, they are also useful. Pipes allow people to easily share information that they find interesting with a third party. We envision a future where this third party can take many forms. For example, a web user might pipe photos directly from their browser to a web enabled picture frame. Another example of a possible use would be for a user to pipe all the information they find interesting directly to their online blog.

Overall, we see pipes as being an integral part of highly interactive web applications. By creating this piping module, we hope to have furthered the state of the art in highly interactive web applications and look forward to seeing it in cutting edge web applications in the near future.

Community content is available under CC-BY-SA unless otherwise noted.