Initial implementation of chat.

This commit is contained in:
Martin Edenhofer 2012-11-02 17:10:22 +01:00
parent f723ea3cdb
commit 06c4b25e7c
9 changed files with 80 additions and 12 deletions

View file

@ -86,7 +86,7 @@ class Index extends App.Controller
App[key].refresh( value, options: { clear: true } ) App[key].refresh( value, options: { clear: true } )
# rebuild navbar with user data # rebuild navbar with user data
App.Event.trigger 'navrebuild', data.session App.Event.trigger 'ajax:auth', data.session
# update websocked auth info # update websocked auth info
App.WebSocket.auth() App.WebSocket.auth()

View file

@ -15,7 +15,7 @@ class Index extends Spine.Controller
@log 'Session', window.Session @log 'Session', window.Session
window.Session = {} window.Session = {}
@log 'Session', window.Session @log 'Session', window.Session
App.Event.trigger 'navrebuild' App.Event.trigger 'ajax:auth'
# redirect to login # redirect to login
@navigate 'login' @navigate 'login'

View file

@ -11,8 +11,8 @@ class App.Navigation extends App.Controller
@update(arguments[0]) @update(arguments[0])
# rebuild nav bar with given user data # rebuild nav bar with given user data
App.Event.bind 'navrebuild', (user) => App.Event.bind 'ajax:auth', (user) =>
@log 'navbarrebuild', user @log 'navbar rebuild', user
if !_.isEmpty( user ) if !_.isEmpty( user )
cache = App.Store.get( 'navupdate_ticket_overview' ) cache = App.Store.get( 'navupdate_ticket_overview' )

View file

@ -45,7 +45,7 @@ class App.Auth
App.WebSocket.auth() App.WebSocket.auth()
# rebuild navbar with new navbar items # rebuild navbar with new navbar items
App.Event.trigger 'navrebuild' App.Event.trigger 'ajax:auth'
return false; return false;
@ -69,10 +69,7 @@ class App.Auth
App.Collection.reset( type: key, data: value ) App.Collection.reset( type: key, data: value )
# rebuild navbar with new navbar items # rebuild navbar with new navbar items
App.Event.trigger 'navrebuild', data.session App.Event.trigger 'ajax:auth', data.session
# rebuild navbar with updated ticket count of overviews
App.Event.trigger 'navupdate_remote'
error: (xhr, statusText, error) => error: (xhr, statusText, error) =>
console.log 'loginCheck:error'#, error, statusText, xhr.statusCode console.log 'loginCheck:error'#, error, statusText, xhr.statusCode

View file

@ -19,10 +19,15 @@ class App.WebSocket
@connect() @connect()
_instance.auth(args) _instance.auth(args)
@_spool: ->
_instance.spool()
# The actual Singleton class # The actual Singleton class
class _Singleton extends App.Controller class _Singleton extends App.Controller
queue: [] queue: []
supported: true supported: true
lastSpoolMessage: undefined
connectionEstablished: false
constructor: (@args) -> constructor: (@args) ->
@ -30,6 +35,11 @@ class _Singleton extends App.Controller
App.Event.bind 'ws:send', (data) => App.Event.bind 'ws:send', (data) =>
@send(data) @send(data)
# get spool messages after successful ws login
App.Event.bind( 'ws:login', (data) =>
@spool()
)
# inital connect # inital connect
@connect() @connect()
@ -58,6 +68,23 @@ class _Singleton extends App.Controller
} }
@send(data) @send(data)
spool: =>
# build data to send to server
data =
action: 'spool'
if @lastSpoolMessage
data['timestamp'] = @lastSpoolMessage
@log 'spool', data
# ask for spool messages
App.Event.trigger(
'ws:send'
data
)
# set timestamp to get spool messages later
@lastSpoolMessage = Math.round( +new Date()/1000 )
close: => close: =>
return if !@supported return if !@supported
@ -103,6 +130,8 @@ class _Singleton extends App.Controller
@ws.onopen = => @ws.onopen = =>
console.log( 'onopen' ) console.log( 'onopen' )
@connectionEstablished = true
# close error message show up (because try so connect again) if exists # close error message show up (because try so connect again) if exists
@clearDelay('websocket-no-connection-try-reconnect') @clearDelay('websocket-no-connection-try-reconnect')
if @error if @error
@ -149,6 +178,11 @@ class _Singleton extends App.Controller
@ws.onclose = (e) => @ws.onclose = (e) =>
console.log( 'onclose', e ) console.log( 'onclose', e )
# set timestamp to get spool messages later
if @connectionEstablished
@lastSpoolMessage = Math.round( +new Date()/1000 )
@connectionEstablished = false
# show error message, first try to reconnect # show error message, first try to reconnect
if !@error if !@error
message = => message = =>

View file

@ -330,3 +330,8 @@ footer {
text-shadow: 0 1px 0 #fff; text-shadow: 0 1px 0 #fff;
opacity: 0.9; opacity: 0.9;
} }
.well-demand {
padding: 8px 15px 0px 15px
}
}

View file

@ -3,6 +3,7 @@
<div id="navigation"></div> <div id="navigation"></div>
<div id="notify"></div> <div id="notify"></div>
<div id="content"></div> <div id="content"></div>
<div id="chat"></div>
</div> </div>
<div class="container"> <div class="container">

View file

@ -12,6 +12,14 @@ module Session
user = { :id => session['id'] } user = { :id => session['id'] }
file.puts Marshal.dump(user) file.puts Marshal.dump(user)
} }
# send update to browser
if session['id']
self.transaction( client_id, {
:event => 'ws:login',
:data => { :success => true },
})
end
end end
def self.get( client_id ) def self.get( client_id )

View file

@ -44,6 +44,7 @@ puts "Starting websocket server on #{ @options[:b] }:#{ @options[:p] } (secure:#
#puts options.inspect #puts options.inspect
@clients = {} @clients = {}
@spool = []
EventMachine.run { EventMachine.run {
EventMachine::WebSocket.start( :host => @options[:b], :port => @options[:p], :secure => @options[:s], :tls_options => tls_options ) do |ws| EventMachine::WebSocket.start( :host => @options[:b], :port => @options[:p], :secure => @options[:s], :tls_options => tls_options ) do |ws|
@ -89,6 +90,27 @@ EventMachine.run {
# check if connection already exists # check if connection already exists
next if !@clients[client_id] next if !@clients[client_id]
# spool messages for new connects
if data['spool']
meta = {
:msg => msg,
:timestamp => Time.now.to_i,
}
@spool.push meta
end
# get spool messages
if data['action'] == 'spool'
@spool.each { |message|
puts message.inspect
puts data['timestamp']
if !data['timestamp'] || data['timestamp'] < message[:timestamp]
puts "send spool msg to #{client_id} #{ message[:msg] }"
@clients[client_id][:websocket].send( "[#{ message[:msg] }]" )
end
}
end
# get session # get session
if data['action'] == 'login' if data['action'] == 'login'
@clients[client_id][:session] = data['session'] @clients[client_id][:session] = data['session']
@ -103,6 +125,7 @@ EventMachine.run {
elsif data['action'] == 'broadcast' elsif data['action'] == 'broadcast'
@clients.each { |local_client_id, local_client| @clients.each { |local_client_id, local_client|
if local_client_id != client_id if local_client_id != client_id
puts "send broadcast to #{local_client_id} #{msg}"
local_client[:websocket].send( "[#{msg}]" ) local_client[:websocket].send( "[#{msg}]" )
end end
} }
@ -137,7 +160,7 @@ EventMachine.run {
} }
} }
EventMachine.add_periodic_timer(0.2) { EventMachine.add_periodic_timer(0.4) {
next if @clients.size == 0 next if @clients.size == 0
log 'debug', "checking for data..." log 'debug', "checking for data..."
@clients.each { |client_id, client| @clients.each { |client_id, client|