       socket.addEventListener(
         "close" 
         (code, reason) => 
+
           @socket = null
+          
+          request.reject("socket closed") for request in @pendingRequests
+          @pendingRequests.length = 0
+          
           console?.error("socket closed", "#{code}: #{reason}")
+
+        false
+      )
+
+      socket.addEventListener(
+        "message"
+        (event) =>
+          
+          buffer = event.data
+          handle = new Float32Array(buffer, 0, 1)[0]
+          
+          for request in @pendingRequests when request.handle == handle
+            
+            _.removeElement(@pendingRequests, request)
+
+            if buffer.byteLength > 4
+              request.resolve(new @responseBufferType(buffer, 4))
+            else
+              request.reject()
+            
+            break
         false
       )
       

  fallbackMode : false
  
  constructor : (options) ->
    _.extend(@, options)
    @sender = @defaultSender
    @sender.open(@)
  
  switchToFallback : ->
    unless @fallbackMode
      @sender.close()
      @fallbackMode = true
      @sender = @fallbackSender
      @sender.open(@)

  send : (data) ->


    
    @openDeferred.promise()


  close : ->
    if @socket
      @socket.close()
      @socket = null
      @openDeferred = null


  send : (data) ->

    @initialize().pipe =>
    
      { transmitBuffer, socketHandle } = @createPackage(data)

      deferred = $.Deferred()
      deferred.handle = socketHandle
      
      @pendingRequests.push(deferred)
      @socket.send(transmitBuffer.buffer)
    
      setTimeout(
        => 
          _.removeElement(@pendingRequests, deferred)
          deferred.reject("timeout")
        @MESSAGE_TIMEOUT
      )

      deferred.promise()


  createPackage : (data) ->

