Initial implementation of chat.
This commit is contained in:
parent
f723ea3cdb
commit
06c4b25e7c
9 changed files with 80 additions and 12 deletions
|
@ -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()
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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' )
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 = =>
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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|
|
||||||
|
@ -164,7 +187,7 @@ EventMachine.run {
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def log( level, data, client_id = '-' )
|
def log( level, data, client_id = '-' )
|
||||||
if !@options[:d]
|
if !@options[:d]
|
||||||
return if level == 'debug'
|
return if level == 'debug'
|
||||||
|
|
Loading…
Reference in a new issue