Reputation: 157
I have this script code to connect to a signalr Hub its Works fine.
<script src="http://localhost:34322/Scripts/jquery.signalR-2.1.2.min.js"></script>
<script src="http://localhost:34322/signalr/hubs"></script>
<link href="http://localhost:34322/css/quizyClientSide.css" rel="stylesheet" />
<script>
var chave = "c146a0de-f6ad-4b0b-b366-f0f93b16bf12";
$("body").append("<div id='discussion'><div id='topoChat'><div id='textoTopChat'>Precisa de ajuda?</div></div><div id='areaChat'></div><div id='divInputMessage'><input type='text' placeholder='digite sua mensagem' id='message'></div></div>");
var chat = $.connection.chatHub;
var dominio = "http://localhost:34322";
$.connection.hub.url = dominio + "/signalr";
$.connection.hub.qs = { 'chave': chave, 'nomeCliente': "cliente" };
$.connection.hub.start().done(function () {
alert("conectou");
});
</script>
So, no i want to move this code to a separate js file to include in the page instead.
I moved the code to a js file and loading signalr and the generated proxy using this function
loadJS = function (src) {
var jsLink = $("<script type='text/javascript' src='" + src + "'>");
$("head").append(jsLink);
};
The js file should be something like this:
var chave = "c146a0de-f6ad-4b0b-b366-f0f93b16bf12";
$("body").append("<div id='discussion'><div id='topoChat'><div id='textoTopChat'>Precisa de ajuda?</div></div><div id='areaChat'></div><div id='divInputMessage'><input type='text' placeholder='digite sua mensagem' id='message'></div></div>");
var dominio = "http://localhost:34322";
loadJS(dominio + "/Scripts/jquery.signalR-2.1.2.min.js");
loadJS(dominio + "/signalr/hubs");
var chat = $.connection.chatHub;
$.connection.hub.url = dominio + "/signalr";
$.connection.hub.qs = { 'chave': chave, 'nomeCliente': "cliente" };
$.connection.hub.start().done(function () {
alert("conectou");
});
Using this aproach, to include a js file works in same domain connection but not if cross domain.
In cross domain chatHub(var chat = $.connection.chatHub;) is Always undefined.
Any suggestion?
Upvotes: 1
Views: 855
Reputation: 15234
Dynamically loading JS into your page isn't that simple. Often times, when you want to move code into a separate JS file, you just assume that whoever is including your JS file has appropriately loaded all your dependencies. After all, your JS file is already relying on jQuery being loaded for your loadJS
function to even work, so why not rely on SignalR being loaded as well?
<script src="http://myotherdomain/Scripts/jquery-2.1.1.min.js"></script>
<script src="http://myotherdomain/Scripts/jquery.signalR-2.1.2.min.js"></script>
<script src="http://myotherdomain/signalr/hubs"></script>
<script src="http://myotherdomain/Scripts/myScript.js"></script>
If you do this, myScript.js will be run after SignalR has loaded so $.connection.chatHub
will be defined even though the scripts are loaded from another domain.
The problem with what you have is there is no guarantee that your scripts have actually finished loading after loadJS
is called. It seems that you are just lucky that the scripts happen to be loaded by the time your script executes when you are loading script from the same domain.
There are DOM events that you can listen to that will fire when the script actually loads, but this can be somewhat tricky. Since you already have a dependency on jQuery before you load additional scripts using your loadJS
function, you could just use $.getScript instead which already supports an asynchronous success handler.
You have to be aware that you cannot load /signalr/hubs until /Scripts/jquery.signalR-2.1.2.min.js has finished loading. If you used $.getScript
your code might look something like this:
var dominio = "http://localhost:34322";
$.getScript(dominio + "/Scripts/jquery.signalR-2.1.2.min.js").done(function() {
$.getScript(dominio + "/signalr/hubs").done(function() {
var chat = $.connection.chatHub;
// ...
}).fail(function( jqxhr, settings, exception ) { /* handle error */ });
}).fail(function( jqxhr, settings, exception ) { /* handle error */ });
You could even use something like require.js to load SignalR. However, I suggest going with my first approach which is to not load scripts from JS if you can avoid it.
Upvotes: 1