Let people know about Peerbind:
  • What is Peerbind

  • Peerbind is a new method of event binding that converts a webpage into a massively interconnected website.

    Peerbind adds an event listener to an element, however the triggered events will be shared with all visitors in the peerset. The default peerset contains visitors of the same page.

    To best appreciate the examples below, be sure to open two different browsers - either on different machines or on the same machine but whose maker is different (like Firefox and Safari).

    A public server is available so you can get started! You can always launch your own later. (If ours is too slow see documentation for the built-in simple migration details.)

  • How it works

  • First some code...

    
    <script src="http://code.jquery.com/jquery-1.4.4.js"></script>
    <script src="http://js.peerbind.com/jQuery.peerbind.js"></script>
    ... 
    
    Type a message: <input type="text"> 
    <div id="chats"></div>
    
    $("input").peerbind("change", {
        peer:  function(e) { addChat(e.srcPeer + ": " + e.peerInfo.value);},
        local: function(e) { addChat("You: " + e.peerInfo.value); $(this).val("");}
    }); 
    
    function addChat(msg) {
      $("#chats").prepend("<br>").prepend($("<span/>").text(msg));
    }
    
    See Code
    Copy Code
  • Try it

  • Type a message:
    Waiting for messages...
  • Explanation

  • When the script binds an event, the Peerbind library creates a unique identifier and registers with the peerbind server. From that point forward all "change" events are broadcast amongst the peerset.

  • Custom Events

  • Peerbind makes it easy to pass around custom events. Try this:

    
    <!DOCTYPE html>
    <html>
    <head>
      <script src="http://code.jquery.com/jquery-1.4.4.js"></script>
      <script src="http://js.peerbind.com/jQuery.peerbind.js"></script>
    </head>
    <body>
      Visitors: <span>0</span>
      <script>
        var visitors = 0;
        $(document.body).peerbind("arrived", function(e) {
            if ( e.srcPeer ) {
                visitors++;
                $("div").text(visitors); 
            }
        }); 
    
        $(document.body).peertrigger("arrived");
      </script>
    
    </body>
    </html>
    See Code
    Copy Code
  • Try it

  • Visitors (since you arrived): 0
  • Bundling Events

  • Given the networked nature of peerbind, high-volume mouse events can become choppy, or unstable, derailing the experience. We have solved this problem by creating a new event, called "peerbundle". Peerbundle allows Peerbind to manage a group of events like, "mousedown, mousemove, mouseup".

    The peerbundle call can group multiple events into a single message. You can specify an event to start the bundle (e.g. mousedown), events to include in the bundle (e.g. mousemove), and an event to terminate the bundle (e.g. mouseup).

    You can also specify that the bundle automatically send at a specific frequency (e.g. every 100 milliseconds), and events are discarded if they come too close together (e.g. discard mousemove events that occur less than 25 milliseconds apart).

    Timing of the original events is maintained by default (e.g. a mouse drag that took place over five seconds would be replayed over five seconds.) To disable timing - clear the 'timeing' flag.

    Unlike peerbind, peerbundle does not allow you to specify bound functions to be called on the events. Instead, use the regular jQuery bind function. Bound functions will be called on both the sender and the receiver.

    Example: Using peerbundle to share a drawing canvas.

    
      <canvas id="can" width="500" height="500"></canvas>
      <script>
        var ctx = document.getElementById("can").getContext("2d");
        var drawing = false;
        var lastMouse;
    
        $("#can").peerbundle({
            startEvent:   "mousedown touchstart",
            event:        "mousemove touchmove",
            endEvent:     "mouseup touchend",
            collapseTime: 25,
            timing:       false
        }).bind("mousedown touchstart", function(e) {
            e.preventDefault();
            drawing   = true;
            lastMouse = getXY(e);
        }).bind("mousemove touchmove", function(e) {
            e.preventDefault();
            if ( drawing ) {
                ctx.beginPath();
                ctx.moveTo(lastMouse.x, lastMouse.y);
                lastMouse = getXY(e);
                ctx.lineTo(lastMouse.x, lastMouse.y);
                ctx.stroke();
            }
        }).bind("mouseup touchend", function(e) { e.preventDefault(); drawing = false; });
        
        function getXY(e) {
            if ( e.srcPeer ) {
                return { x:e.pageX - e.peerInfo.currentTargetOffset.left, 
                         y:e.pageY - e.peerInfo.currentTargetOffset.top };
            } else {
                var offset = $(e.currentTarget).offset();
                return { x:e.pageX-offset.left, y:e.pageY-offset.top};
            }
        }
      </script>
    
    See Code
    Copy Code

  • Try it

  •  
  • Note: The sample code above is a simplified version of the demo. The demo includes code to associate peerbundles with peers to prevent them from interfering with one another, and to assign a color.

  • A New Event Type

  • Introducing "mousebundle". Mousebundle is an alternative to peerbundle, specifically designed for replaying drag and drop events. It uses a new event, called "mousebundle". Mousebundle allows Peerbind to manage a group of events like, "mousedown, mousemove, mouseup".

    To use it bind the "mousebundle" eventType to an element and replay those events using the "peerbundleplay" method in the handler.

    Example: Bind and replay the "mousebundle" event.

    var colors = "Azure,Bisque,Black,Blue,BlueViolet".split(/,/);
    
    for ( var i = 0; i < 5; i++ ) {
        $('<div/>',{
             css:{
                height:50,
                width:50,
                position:"absolute",
                padding:5,
                left:((i%10) * 100),
                top:Math.floor(i/10) * 100,
                backgroundColor:colors[i%colors.length]
            }
        }).addClass("box").text("dragme").appendTo(document.body);
    }
    
    $(".box").peerbind("mousebundle",function(e) {
        if ( e.srcPeer ) {
            $(this).peerbundleplay(e);
        }
    }).draggable();
                
    See Code
    Copy Code

  • Try it

  • New Methods

  • .peerbind( eventType, [eventData], handler(eventObject)) Returns: jQuery
    Registers the event for broadcast and attaches a handler for received events for the elements.
    .peerbind( eventType, [eventData], handler(eventObject))
    eventType A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names.
    eventData A map of data that will be passed to the event handler.
    handler(eventObject) A function to execute each time the event is triggered.
    .peerbind( eventType, [eventData], handlerObject)
    eventType A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names.
    eventData A map of data that will be passed to the event handler.
    handlerObject A map containing functions for "local" and "peer" events and an optional "data" object that will be passed to the handlers.

    * For more information on the underlying "bind" function provided by jQuery see: http://api.jquery.com/bind/

    .peertrigger( eventType, [eventData], peerTarget) Returns: jQuery
    Execute all handlers and behaviors attached to the matched elements for the given event type.
    .peertrigger( eventType, [eventData], peerTarget)
    eventType A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names.
    eventData A map of data that will be passed to the event handler.
    peerTarget optional guid of peer who should receive the event.

    * For more information on the underlying "trigger" function provided by jQuery see: http://api.jquery.com/trigger/

    .peerunbind( eventType ) Returns: jQuery
    Removes peerbound event from bound element of type eventType. Warning: This method differs from jQuery "unbind".
    .peerunbind( eventType )
    eventType A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names.
    .peerregister( callback ) Returns: jQuery
    This function will ensure "callback" is executed when peerbind has successfully registered with the server. This function also allows the client to re-register with the server. (Userful when the peerset has changed.)
    .peerregister( callback )
    callback Function to be called when peerbind has successfully registered with the server.
    .peerbundle( config ) Returns: jQuery
    This function configures a peerbundle. This will bundle up multiple events into a small number of messages, and replay them, optionally retaining timeing information.
    .peerbundle( config )
    config An Object containing the configuration for the peerbundle. Most parameters are optional. The parameters are:
    startevent A string containing one or more JavaScript event types, such as "mousedown" or custom event names. The bundle will start when a startevent is received. If startevent is omitted, the bundle will start when the first event specified by the event parameter is received.
    event A string containing one or more JavaScript event types, such as "mousemove" or custom event names. The bundle will collect these events after a startevent is received until an endevent is received.
    endevent A string containing one or more JavaScript event types, such as "mouseup" or custom event names. After a startevent is received, the bundle will collect events until an endevent is received. At that time, the bundle will be sent and closed.
    startsel An optional jQuery selector for the elements on which startevent is bound. If omitted, the selector to which peerbundle was passed is used.
    eventsel An optional jQuery selector for the elements on which event is bound. If omitted, the selector to which peerbundle was passed is used.
    endsel An optional jQuery selector for the elements on which endevent is bound. If omitted, the selector to which peerbundle was passed is used. When using bundles with mouse events, it is often useful to set endsel to $("body"), to ensure that the mouseup is caught even if it occurs outside the initial element.
    sendtime An optional timeout before sending the bundle, even if the endevent is not received. For example, if set to 100, the bundle messages will be sent every 100 ms, as long as at least one event was received. If omitted, the bundle will not be sent until the endevent is received.
    collapsetime An optional time during which events are discarded. For example, if set to 25, any event occurring within 25 seconds of the previous bundled event will be discarded. If omiited, all events are sent. The startevent and endevent are always sent.
    timing If true (default), events are timestamped, and the receiver uses timeouts to attempt to replay the events using the same timing that was originally used. If omitted or false, the events are replayed immediately upon receipt. Note that the value of timing at the sender controls this behavior. Because of the asynhronous nature of JavaScript and due to network delays, accurate replay of timing is not guaranteed.
  • The Event Object

  • The peerbind version of bind provides the same event object but contains a couple new fields:

    • event.srcPeer null if the event is locally generated, otherwise it contains the guid of the peer that generated the event.
      event.peerData contains the eventData that was passed to the peerbind call on the sender. For compatibility with previous versions of peerbind, a "change" event will store the new value of the input that was changed if no eventData was included, however, this usage is deprecated in favor of peerInfo.value.
      event.peerInfo contains extra information that is filled in by peerbind depending on the type of event. This is information that would normally be obtained by the client using DOM methods, but would not be available in the distributed environment of peerbind. peerInfo is only guaranteed to be available on the receiver side (event.srcPeer is non null). event.peerInfo is an Object which may contain the following fields:
      value If the event was a change event, this will contain the value of the input that was changed.
      currentTargetOffset If the event was a mouse event, this will contain an object with top and left attributes showing the offset of the currentTarget on the page. Because different browsers render the page differently, an object may not be at the same location in all browsers, and use of the standard pageX and pageY event attributes may result in unpredictable behavior. You can use event.peerInfo.offset to normalize the position.

    Example: Bind the "mouseenter" event for all peers.

    $("div").peerbind("mouseenter",function(e) {
        if ( e.srcPeer )
            $(this).text(e.srcPeer+" entered.");
    });
                

    Example: Bind the "mouseenter" event for all peers using the conveinience object.
    
    $("div").peerbind("mouseenter", {
        peer: function(e){$(this).text(e.srcPeer+" entered."),
        local:function(){$(this).text("You entered.")
    });
                
  • Peersets

  • A peerset is the set of people who will receive peer generated events from each other.

    Peerbind provides several set types. Each of the following set types creates a peerset:

    • page (default) All visitors of the exact same URL.
      domain All visitors of the same domain will receive events generated by each other - Note: This only work for Peerbind pages that are configured to listen for domain. This mode makes it possible to have a "stats" page that can listen for broadcasted events about visitors... and lots of other neat things.
      ip All visitors originating from the same network IP address (e.g. 64.23.12.123).
      geo All visitors originating from approximately the same Longitude and Latitude. (TODO: make the variance configurable)
      string All visitors to the current domain who register, using the same "string". This method is also called "shared-secret" and allows people to hear events by only those who have registered with the same value.

    Example: Bind the "mouseenter" event for all peers on the same domain.

    $.fn.peerbind.defaults.type = "domain";
    
    //All users on this domain will now "hear" the mouseenter events.
    $("div").peerbind("mouseenter",function(e) {
        if ( e.srcPeer )
            $(this).text(e.srcPeer+" entered.");
    });
                

    Example: Bind the "mouseenter" event for all peers using the shared-secret. (In this case the secret is: "algorithm".)
    
    $.fn.peerbind.defaults.type = "string"; 
    $.fn.peerbind.defaults.regstring = "algorithm"; 
    
    //All users who have registered on this domain
    //with the string "algorithm" will "hear" these
    //mouseenter events.
    $("div").peerbind("mouseenter",function(e) {
        if ( e.srcPeer )
            $(this).text(e.srcPeer+" entered.");
    });
                
  • Configuration

  • Peerbind configuration parameters allows developers to control how the feature operates.

    The configuration parameters are:

    • .peerbind.defaults.type the string value representing the type of peerset the visitors of this page should register for to become peerbound. The full list of strings is available here: .peerbind.types
      .peerbind.defaults.regstring the string used to create a "channel" of communication. Warning: Nothing is private that runs through the peerbind server. Its public nature makes it easy to use and therefore easy to eavesdrop.
      .peerbind.defaults.endpoint string value of the domain infront of your peerbind server. By default this value is the public server, "peerbind.com" change it through a bit of configuration like this:

      $.fn.peerbind.defaults.endpoint = "mypeerbindserver.com"
                                

      .peerbind.defaults.endpointprefixes array of strings to prefix the value held in "endpoint". Spreading the peerbind poll calls to a collection of sub-domains prevents avoids the browser connection limit. By default the endpoint prefixes are: www, www1, www2, www3, www4, www5, www6, www7, www8, www9, www10. They can be modified like this:

      
      // Makes peerbind call pb1.peerbind.com, pb2.peerbind.com, etc...
      $.fn.peerbind.defaults.endpointprefixes = ["pb1","pb2","pb3"];
                            

      If you don't have the ability to create multiple endpoints. Clear the endpoint array:

      
      // Makes peerbind call pb1.peerbind.com, pb2.peerbind.com, etc...
      $.fn.peerbind.defaults.endpointprefixes = [];
                            

  • Your Server

  • While peerbind provides a free public server to run against, this server is a generally available resource that provides no guarantees about security, reliability, or anything else.

    Running your own will give you more control, and possibly reliability.

  • Troubleshooting

  • Peerbind is a new way to think about coding in javascript - below are a few things to watch out for while exploring.

    • Mousebundle Trouble - Mousebundle's work by recording and modifying(in playback) the absolute position of an element. Sometimes the absolute position of an element can be different from one browser to the next. Even when its the same maker but a different OS - due to the fonts used.
    • To Solve: Check the "line-height" attribute, and other items that might modify the top or left position of the element. Once you find the culprit, modify your CSS to lock down the heights or widths to make it function as expected between users. Another thing to watch for: positions of elements may be different between users due to personlized or generated content - lock down and allocate the space for those or account for them in the element positioning.

  • FAQ

    • Is Peerbind secure? - No. Peerbind is a new way to get behavior onto a page and therefore a new attack vector. The code controlling behavior is visible to anyone so there is no way to effectively secure it. Please familiarize yourself with javascript security before making any assumptions on behalf of your users.

      Sanatize data coming from the server as you would any other data from an untrusted source. Anyone can drop any event into your event handlers.

    • What is Peerbind for? - Peerbind allows javascript developers to get something social and interactive up quickly. It removes the need to create a server before creating an interactive prototype that can be "felt".