From b53b916218dad0196a064ef436778ccb898067db Mon Sep 17 00:00:00 2001 From: Seth Call Date: Tue, 4 Sep 2012 20:23:34 -0500 Subject: [PATCH] * adding check in session-topic blast to clients--if you originate a message, you shouldn't have it bounce back to you --- lib/jam_websockets/router.rb | 32 +++++++++++++++++++++++------- spec/jam_websockets/router_spec.rb | 5 +++-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/lib/jam_websockets/router.rb b/lib/jam_websockets/router.rb index 83e29d16f..afac38298 100644 --- a/lib/jam_websockets/router.rb +++ b/lib/jam_websockets/router.rb @@ -13,7 +13,7 @@ include Jampb module EventMachine module WebSocket class Connection < EventMachine::Connection - attr_accessor :encode_json + attr_accessor :encode_json, :client_id # client_id is uuid we give to each client to track them as we like end end end @@ -176,11 +176,25 @@ module JamWebsockets @log.debug "received session-directed message for session: #{session_id}" msg = Jampb::ClientMessage.parse(msg) + + # ok, its very odd to have your own message that you sent bounce back to you. + # In one small favor to the client, we purposefully disallow messages a client + # sent from bouncing back to itself. + properties = headers.properties unless headers.nil? + inner_headers = properties.headers unless properties.nil? + origin_client_id = inner_headers["client_id"] + + # counter-intuitively, even though a string is passed in when you send the header, an (apparently) auto-generated class is sent back which, if you to_s, returns the original value + origin_client_id = origin_client_id.to_s unless origin_client_id.nil? + + @log.debug "message received from client #{origin_client_id}" contexts.each do |context| - EM.schedule do - @log.debug "sending session message to #{context}" - send_to_client(context.client, msg) - end + if context.client.client_id != origin_client_id + EM.schedule do + @log.debug "sending session message to #{context}" + send_to_client(context.client, msg) + end + end end end end @@ -242,6 +256,10 @@ module JamWebsockets def new_client(client) + # give a unique ID to this client. This is used to prevent session messages + # from echoing back to the sender, for instance. + client.client_id = UUIDTools::UUID.random_create.to_s + @semaphore.synchronize do @pending_clients.add(client) end @@ -543,9 +561,9 @@ module JamWebsockets # belong to session = access_jam_session?(session_id, context.user) - @log.debug "publishing to session #{session}" + @log.debug "publishing to session #{session} from client_id #{client.client_id}" # put it on the topic exchange for sessions - @sessions_exchange.publish(client_msg.to_s, :routing_key => "session.#{session_id}") + @sessions_exchange.publish(client_msg.to_s, :routing_key => "session.#{session_id}", :properties => { :headers => { "client_id" => client.client_id } } ) end def handle_user_directed(user, client_msg, client) diff --git a/spec/jam_websockets/router_spec.rb b/spec/jam_websockets/router_spec.rb index 529cdea78..7c33e23fe 100644 --- a/spec/jam_websockets/router_spec.rb +++ b/spec/jam_websockets/router_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' require 'thread' LoginClient = Class.new do - attr_accessor :onmsgblock, :onopenblock, :encode_json + attr_accessor :onmsgblock, :onopenblock, :encode_json, :client_id def initiaize() @@ -100,6 +100,7 @@ describe Router do client.should_receive(:onerror) client.should_receive(:onmessage) client.should_receive(:encode_json=) + client.should_receive(:client_id=) @router.new_client(client) @@ -130,7 +131,7 @@ describe Router do it "should not allow login of bogus user", :mq => true do TestClient = Class.new do - attr_accessor :onmsgblock, :onopenblock, :encode_json + attr_accessor :onmsgblock, :onopenblock, :encode_json, :client_id def initiaize()