Merge branch 'develop' into feature/sprint_12_work
This commit is contained in:
commit
a07fdfe2a8
|
|
@ -671,6 +671,7 @@ message ServerGenericError {
|
|||
// but gives the client a chance to know why.
|
||||
message ServerRejectionError {
|
||||
optional string error_msg = 1;
|
||||
optional string error_code = 2;
|
||||
}
|
||||
|
||||
// route_to: client
|
||||
|
|
|
|||
|
|
@ -197,8 +197,8 @@ module JamRuby
|
|||
end
|
||||
|
||||
# create a server rejection error
|
||||
def server_rejection_error(error_msg)
|
||||
error = Jampb::ServerRejectionError.new(:error_msg => error_msg)
|
||||
def server_rejection_error(error_msg, error_code)
|
||||
error = Jampb::ServerRejectionError.new(:error_msg => error_msg, :error_code => error_code)
|
||||
|
||||
Jampb::ClientMessage.new(
|
||||
:type => ClientMessage::Type::SERVER_REJECTION_ERROR,
|
||||
|
|
|
|||
|
|
@ -1023,6 +1023,11 @@ module JamRuby
|
|||
return
|
||||
end
|
||||
|
||||
if connection.locidispid.nil?
|
||||
@@log.warn("no locidispid for connection's ip_address: #{connection.ip_address}")
|
||||
return
|
||||
end
|
||||
|
||||
# we don't use a websocket login to update the user's record unless there is no addr
|
||||
if reason == JAM_REASON_LOGIN && last_jam_addr
|
||||
return
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
var $messageContents = null;
|
||||
var $dialog = null;
|
||||
var $templateServerConnection = null;
|
||||
var $templateNoLogin = null;
|
||||
var $templateDisconnected = null;
|
||||
var $currentDisplay = null;
|
||||
|
||||
|
|
@ -109,8 +110,10 @@
|
|||
|
||||
// we don't show any reconnect dialog on the initial connect; so we have this one-time flag
|
||||
// to cause reconnects in the case that the websocket is down on the initially connect
|
||||
if (!server.noReconnect &&
|
||||
(initialConnectAttempt || !server.reconnecting)) {
|
||||
if(server.noReconnect) {
|
||||
renderLoginRequired();
|
||||
}
|
||||
else if ((initialConnectAttempt || !server.reconnecting)) {
|
||||
server.reconnecting = true;
|
||||
initialConnectAttempt = false;
|
||||
|
||||
|
|
@ -272,9 +275,13 @@
|
|||
function serverRejection(header, payload) {
|
||||
logger.warn("server rejected our websocket connection. reason=" + payload.error_msg)
|
||||
|
||||
if(payload.error_msg == 'max_user_connections') {
|
||||
if(payload.error_code == 'max_user_connections') {
|
||||
context.JK.Banner.showAlert("Too Many Connections", "You have too many connections to the server. If you believe this is in error, please contact support.")
|
||||
}
|
||||
else if(payload.error_code == 'invalid_login' || payload.error_code == 'empty_login') {
|
||||
logger.debug(payload.error_code + ": no longer reconnecting")
|
||||
server.noReconnect = true; // stop trying to log in!!
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
|
@ -330,6 +337,23 @@
|
|||
return {};
|
||||
}
|
||||
|
||||
function renderLoginRequired() {
|
||||
var $inSituContent = $(context._.template($templateNoLogin.html(), buildOptions(), { variable: 'data' }));
|
||||
$inSituContent.find('a.disconnected-login').click(function() {
|
||||
var redirectPath= '?redirect-to=' + encodeURIComponent(context.JK.locationPath());
|
||||
if(gon.isNativeClient) {
|
||||
window.location.href = '/signin' + redirectPath;
|
||||
}
|
||||
else {
|
||||
window.location.href = '/' + redirectPath;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
$messageContents.empty();
|
||||
$messageContents.append($inSituContent);
|
||||
$inSituBannerHolder.addClass('active');
|
||||
return $inSituBannerHolder;
|
||||
}
|
||||
function renderDisconnected() {
|
||||
|
||||
var content = null;
|
||||
|
|
@ -523,13 +547,22 @@
|
|||
connectDeferred = new $.Deferred();
|
||||
channelId = context.JK.generateUUID(); // create a new channel ID for every websocket connection
|
||||
|
||||
var rememberToken = $.cookie("remember_token");
|
||||
|
||||
if(isClientMode() && !rememberToken) {
|
||||
server.noReconnect = true;
|
||||
logger.debug("no login info; shutting down websocket");
|
||||
renderLoginRequired();
|
||||
connectDeferred.reject();
|
||||
return connectDeferred;
|
||||
}
|
||||
// we will log in one of 3 ways:
|
||||
// browser: use session cookie, and auth with token
|
||||
// native: use session cookie, and use the token
|
||||
// latency_tester: ask for client ID from backend; no token (trusted)
|
||||
var params = {
|
||||
channel_id: channelId,
|
||||
token: $.cookie("remember_token"),
|
||||
token: rememberToken,
|
||||
client_type: isClientMode() ? context.JK.clientType() : 'latency_tester',
|
||||
client_id: isClientMode() ? (gon.global.env == "development" ? $.cookie('client_id') : null): context.jamClient.clientID,
|
||||
os: context.JK.GetOSAsString(),
|
||||
|
|
@ -725,6 +758,7 @@
|
|||
$messageContents = $inSituBannerHolder.find('.message-contents');
|
||||
$dialog = $('#banner');
|
||||
$templateServerConnection = $('#template-server-connection');
|
||||
$templateNoLogin = $('#template-no-login');
|
||||
$templateDisconnected = $('#template-disconnected');
|
||||
|
||||
if ($inSituBanner.length != 1) {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.reconnect-progress-msg {
|
||||
.reconnect-progress-msg, .login-back-in-msg {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,4 +9,9 @@
|
|||
%div.reconnect-progress-msg
|
||||
%span.reconnect-before= 'Reconnecting automatically in '
|
||||
%span.reconnect-countdown= '{{data.countdown}}'
|
||||
%a.disconnected-reconnect.reconnect-enabled{href:'#'} RECONNECT NOW
|
||||
%a.disconnected-reconnect.reconnect-enabled{href:'#'} RECONNECT NOW
|
||||
%script{type: 'text/template', id: 'template-no-login'}
|
||||
%div
|
||||
%div.login-back-in-msg
|
||||
%span= 'You will need to log back in'
|
||||
%a.disconnected-login{href:'#'} GO TO SIGN IN
|
||||
|
|
@ -120,7 +120,7 @@
|
|||
console.log("websocket connected")
|
||||
})
|
||||
.fail(function() {
|
||||
console.log("websocket failed to connect")
|
||||
//console.log("websocket failed to connect")
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@
|
|||
<% if Rails.env == "development" %>
|
||||
ga('create', '<%= Rails.application.config.ga_ua %>', { 'cookieDomain': 'none' });
|
||||
<% else %>
|
||||
ga('create', '<%= Rails.application.config.ga_ua %>', 'jamkazam.com');
|
||||
ga('create', '<%= Rails.application.config.ga_ua %>', 'jamkazam.com');
|
||||
<% end %>
|
||||
|
||||
ga('require', 'displayfeatures');
|
||||
ga('send', 'pageview', {
|
||||
dimension1: '<%= ga_user_level %>',
|
||||
dimension2: '<%= ga_user_type %>'
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ SampleApp::Application.configure do
|
|||
OmniAuth.config.test_mode = true
|
||||
|
||||
config.websocket_gateway_enable = false
|
||||
config.websocket_gateway_port = 6769
|
||||
config.websocket_gateway_port = 6759
|
||||
config.websocket_gateway_uri = "ws://localhost:#{config.websocket_gateway_port}/websocket"
|
||||
|
||||
config.websocket_gateway_connect_time_stale_client = 4
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ Thread.new do
|
|||
require 'jam_websockets'
|
||||
begin
|
||||
JamWebsockets::Server.new.run(
|
||||
:port => 6769,
|
||||
:port => 6759,
|
||||
:emwebsocket_debug => false,
|
||||
:connect_time_stale_client => 4,
|
||||
:connect_time_expire_client => 6,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ development:
|
|||
<<: *defaults
|
||||
|
||||
test:
|
||||
port: 6769
|
||||
port: 6759
|
||||
verbose: true
|
||||
rabbitmq_host: localhost
|
||||
rabbitmq_port: 5672
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ module JamWebsockets
|
|||
@log.info "ending client session deliberately due to malformed client behavior. reason=#{e}"
|
||||
begin
|
||||
# wrap the message up and send it down
|
||||
error_msg = @message_factory.server_rejection_error(e.to_s)
|
||||
error_msg = @message_factory.server_rejection_error(e.to_s, e.error_code)
|
||||
send_to_client(client, error_msg)
|
||||
ensure
|
||||
cleanup_client(client)
|
||||
|
|
@ -277,6 +277,7 @@ module JamWebsockets
|
|||
client.trusted = is_trusted
|
||||
|
||||
client.onopen { |handshake|
|
||||
|
||||
# a unique ID for this TCP connection, to aid in debugging
|
||||
client.channel_id = handshake.query["channel_id"]
|
||||
|
||||
|
|
@ -291,7 +292,7 @@ module JamWebsockets
|
|||
end
|
||||
|
||||
websocket_comm(client, nil) do
|
||||
handle_login(client, handshake.query)
|
||||
handle_login(client, handshake.query, handshake.headers["X-Forwarded-For"])
|
||||
end
|
||||
}
|
||||
|
||||
|
|
@ -472,10 +473,10 @@ module JamWebsockets
|
|||
context
|
||||
end
|
||||
|
||||
def handle_latency_tester_login(client_id, client_type, client)
|
||||
def handle_latency_tester_login(client_id, client_type, client, override_ip)
|
||||
|
||||
# respond with LOGIN_ACK to let client know it was successful
|
||||
remote_ip = extract_ip(client)
|
||||
remote_ip = extract_ip(client, override_ip)
|
||||
heartbeat_interval, connection_stale_time, connection_expire_time = determine_connection_times(nil, client_type)
|
||||
latency_tester = LatencyTester.connect({
|
||||
client_id: client_id,
|
||||
|
|
@ -511,7 +512,7 @@ module JamWebsockets
|
|||
end
|
||||
end
|
||||
|
||||
def handle_login(client, options)
|
||||
def handle_login(client, options, override_ip = nil)
|
||||
username = options["username"]
|
||||
password = options["password"]
|
||||
token = options["token"]
|
||||
|
|
@ -524,7 +525,7 @@ module JamWebsockets
|
|||
@log.info("handle_login: client_type=#{client_type} token=#{token} client_id=#{client_id} channel_id=#{client.channel_id} udp_reachable=#{udp_reachable}")
|
||||
|
||||
if client_type == Connection::TYPE_LATENCY_TESTER
|
||||
handle_latency_tester_login(client_id, client_type, client)
|
||||
handle_latency_tester_login(client_id, client_type, client, override_ip)
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -541,7 +542,7 @@ module JamWebsockets
|
|||
# protect against this user swamping the server
|
||||
if user && Connection.where(user_id: user.id).count >= @max_connections_per_user
|
||||
@log.warn "user #{user.id}/#{user.email} unable to connect due to max_connections_per_user #{@max_connections_per_user}"
|
||||
raise SessionError, 'max_user_connections'
|
||||
raise SessionError, 'max_user_connections', 'max_user_connections'
|
||||
end
|
||||
|
||||
# XXX This logic needs to instead be handled by a broadcast out to all websockets indicating dup
|
||||
|
|
@ -569,7 +570,7 @@ module JamWebsockets
|
|||
|
||||
client.client_id = client_id
|
||||
client.user_id = user.id if user
|
||||
remote_ip = extract_ip(client)
|
||||
remote_ip = extract_ip(client, override_ip)
|
||||
|
||||
if user
|
||||
|
||||
|
|
@ -650,7 +651,7 @@ module JamWebsockets
|
|||
send_to_client(client, login_ack)
|
||||
end
|
||||
else
|
||||
raise SessionError, 'invalid login'
|
||||
raise SessionError.new('invalid login', 'invalid_login')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -766,7 +767,7 @@ module JamWebsockets
|
|||
return nil
|
||||
end
|
||||
else
|
||||
raise SessionError, 'no login data was found in Login message'
|
||||
raise SessionError.new('no login data was found in Login message', 'empty_login')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -882,8 +883,8 @@ module JamWebsockets
|
|||
end
|
||||
end
|
||||
|
||||
def extract_ip(client)
|
||||
Socket.unpack_sockaddr_in(client.get_peername)[1]
|
||||
def extract_ip(client, override_ip)
|
||||
override_ip || Socket.unpack_sockaddr_in(client.get_peername)[1]
|
||||
end
|
||||
|
||||
def periodical_flag_connections
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ module JamWebsockets
|
|||
calling_thread = options[:calling_thread]
|
||||
trust_check = TrustCheck.new(trust_port, options[:cidr])
|
||||
|
||||
@log.info "starting server #{host}:#{port} staleness_time=#{connect_time_stale_client}; reconnect time = #{connect_time_expire_client}, rabbitmq=#{rabbitmq_host}:#{rabbitmq_port}"
|
||||
@log.info "starting server #{host}:#{port} staleness_time=#{connect_time_stale_client}; reconnect time = #{connect_time_expire_client}, rabbitmq=#{rabbitmq_host}:#{rabbitmq_port} gateway_name=#{gateway_name}"
|
||||
|
||||
EventMachine.error_handler{|e|
|
||||
@log.error "unhandled error #{e}"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
class SessionError < Exception
|
||||
class SessionError < StandardError
|
||||
|
||||
attr_accessor :error_code
|
||||
|
||||
def initialize(msg, error_code = nil)
|
||||
super(msg)
|
||||
@error_code = error_code
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ main()
|
|||
# and bundle won't run because it thinks it has the wrong versions of gems
|
||||
rm -f Gemfile.lock
|
||||
|
||||
JAM_INSTANCE=$JAM_INSTANCE BUILD_NUMBER=$BUILD_NUMBER JAMENV=production exec bundle exec ruby -Ilib bin/websocket_gateway
|
||||
GATEWAY_NAME="$GATEWAY_NAME" JAM_INSTANCE=$JAM_INSTANCE BUILD_NUMBER=$BUILD_NUMBER JAMENV=production exec bundle exec ruby -Ilib bin/websocket_gateway
|
||||
}
|
||||
|
||||
[ "$#" -ne 1 ] && ( usage && exit 1 ) || main
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ def login(router, user, password, client_id, token, client_type)
|
|||
args[0].should == client
|
||||
args[1].is_a?(Jampb::ClientMessage).should be_true
|
||||
end
|
||||
router.should_receive(:extract_ip).at_least(:once).with(client).and_return("127.0.0.1")
|
||||
router.should_receive(:extract_ip).at_least(:once).with(client, nil).and_return("127.0.0.1")
|
||||
client.should_receive(:onclose)
|
||||
client.should_receive(:onerror)
|
||||
|
||||
|
|
@ -61,6 +61,7 @@ def login(router, user, password, client_id, token, client_type)
|
|||
@router.new_client(client, false)
|
||||
handshake = double("handshake")
|
||||
handshake.should_receive(:query).exactly(3).times.and_return({ "pb" => "true", "channel_id" => SecureRandom.uuid, "client_id" => client_id, "token" => token, "client_type" => client_type })
|
||||
handshake.should_receive(:headers).at_least(:once).and_return({})
|
||||
client.onopenblock.call handshake
|
||||
|
||||
client
|
||||
|
|
@ -84,7 +85,7 @@ def login_latency_tester(router, latency_tester, client_id)
|
|||
args[0].should == client
|
||||
args[1].is_a?(Jampb::ClientMessage).should be_true
|
||||
end
|
||||
router.should_receive(:extract_ip).at_least(:once).with(client).and_return("127.0.0.1")
|
||||
router.should_receive(:extract_ip).at_least(:once).with(client, nil).and_return("127.0.0.1")
|
||||
client.should_receive(:onclose)
|
||||
client.should_receive(:onerror)
|
||||
|
||||
|
|
@ -93,6 +94,7 @@ def login_latency_tester(router, latency_tester, client_id)
|
|||
@router.new_client(client, true)
|
||||
handshake = double("handshake")
|
||||
handshake.should_receive(:query).exactly(3).times.and_return({ "pb" => "true", "channel_id" => SecureRandom.uuid, "client_type" => "latency_tester", "client_id" => client_id })
|
||||
handshake.should_receive(:headers).at_least(:once).and_return({})
|
||||
client.onopenblock.call handshake
|
||||
|
||||
client
|
||||
|
|
@ -240,7 +242,7 @@ describe Router do
|
|||
|
||||
client = TestClient.new
|
||||
|
||||
error_msg = message_factory.server_rejection_error("invalid login")
|
||||
error_msg = message_factory.server_rejection_error("invalid login", "invalid_login")
|
||||
|
||||
@router.should_receive(:send_to_client).with(client, error_msg)
|
||||
client.should_receive(:close_websocket)
|
||||
|
|
|
|||
Loading…
Reference in New Issue