Class: Live::Page

Inherits:
Object
  • Object
show all
Defined in:
lib/live/page.rb

Overview

Represents a connected client page with bound dynamic content areas.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(resolver) ⇒ Page

Returns a new instance of Page.



33
34
35
36
37
38
# File 'lib/live/page.rb', line 33

def initialize(resolver)
	@resolver = resolver
	
	@elements = {}
	@updates = Async::Queue.new
end

Instance Attribute Details

#updatesObject (readonly)

The queue of outstanding events to be sent to the client.



41
42
43
# File 'lib/live/page.rb', line 41

def updates
  @updates
end

Instance Method Details

#bind(element) ⇒ Object

Bind a client-side element to a server side element.



45
46
47
48
49
# File 'lib/live/page.rb', line 45

def bind(element)
	@elements[element.id] = element
	
	element.bind(self)
end

#closeObject



74
75
76
77
78
# File 'lib/live/page.rb', line 74

def close
	@elements.each do |id, element|
		element.close
	end
end

#handle(id, event, details) ⇒ Object

Handle an event from the client. If the element could not be found, it is silently ignored.



64
65
66
67
68
69
70
71
72
# File 'lib/live/page.rb', line 64

def handle(id, event, details)
	if element = @elements[id]
		return element.handle(event, details)
	else
		Console.logger.warn(self, "Could not handle event:", event, details)
	end
	
	return nil
end

#resolve(id, data) ⇒ Object

Resolve a client-side element to a server side instance.



54
55
56
# File 'lib/live/page.rb', line 54

def resolve(id, data)
	@resolver.call(id, data)
end

#run(connection) ⇒ Object

Run the event handling loop with the given websocket connection.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/live/page.rb', line 82

def run(connection)
	queue_task = Async do
		while update = @updates.dequeue
			Console.logger.debug(self, "Sending update:", update)
			
			connection.write(update)
			connection.flush if @updates.empty?
		end
	end
	
	while message = connection.read
		Console.logger.debug(self, "Reading message:", message)
		
		if id = message[:bind] and data = message[:data]
			if element = self.resolve(id, data)
				self.bind(element)
			else
				Console.logger.warn(self, "Could not resolve element:", message)
			end
		elsif id = message[:id]
			self.handle(id, message[:event], message[:details])
		else
			Console.logger.warn(self, "Unhandled message:", message)
		end
	end
ensure
	self.close
	queue_task&.stop
end