Making signalr generated proxy hubs url dynamic - javascript

I have a solution which need to connect using CORS to a signalr exposed service.
The address where the signalr service will be hosted could change in time, so it's not
suitable to have the classic script tag
<script src="http://server:8888/signalr/hubs" type="text/javascript"></script>
but it would be fantastic if there's a way to reference the above url dynamically by javascript without the static script tag.
Suggestions would be great!

Do the following in your JS file:
$.getScript('http://server:8888/signalr/hubs', function () {
//Set the hubs URL for the connection
$.connection.hub.url = 'http://server:8888/signalr';
var hub = $.connection.yourHub; //yourHub is name of hub on the server side
//wire up SignalR
//start hub
$.connection.hub.start().done(function () {
//once we're done with SignalR init we can wire up our other stuff
});
});

You could put your settings in a config file:
config.json:
{
"signalr_url": "http://server:8888/signalr"
}
Then load the config:
$.getJSON('config.json', function(config) {
$.getScript(config.signalr_url, function() {
// when the script has loaded
});
});
Edit:
After looking at the SignalR documentation, I think the following would be more suitable.
First include the needed scripts:
<script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR.min.js" type="text/javascript"></script>
Now you can just call $.connection(...); with any url. So applying the above it could look like this:
$.getJSON('config.json', function(config) {
$.connection(config.signalr_url);
});

I have this same scenario and after some researchs we've decided to put the generated proxy as a physical script like bellow:
How to create a physical file for the SignalR generated proxy
As an alternative to the dynamically generated proxy, you can create a
physical file that has the proxy code and reference that file. You
might want to do that for control over caching or bundling behavior,
or to get IntelliSense when you are coding calls to server methods.
To create a proxy file, perform the following steps:
Install the Microsoft.AspNet.SignalR.Utils NuGet package.
Open a command prompt and browse to the tools folder that contains the
SignalR.exe file. The tools folder is at the following location:
[your solution
folder]\packages\Microsoft.AspNet.SignalR.Utils.2.1.0\tools
Enter the following command:
signalr ghp /path:[path to the .dll that contains your Hub class]
The path to your .dll is typically the bin folder in your project
folder.
This command creates a file named server.js in the same folder as
signalr.exe.
Put the server.js file in an appropriate folder in your project,
rename it as appropriate for your application, and add a reference to
it in place of the "signalr/hubs" reference.
link: How to create a physical file for the SignalR generated proxy
As long we have proxy then you can just refer to the Hub url like this:
$.connection.hub.url = "http://your-url/signalr;
//open connection
$.connection.hub.start()
.done(function () {
//do your stuff
})
.fail(function () { alert('unable to connect'); });

Related

Browser-sync not injecting CSS for remote site

I need to do CSS styling of a remote site. I can't host the site locally for development, so I'd rather tweak the CSS locally and see the changes without having to wait for it to upload and then refresh the browser.
Seems like Browser-sync should be able to do this.
I set up a file bs.js:
var browserSync = require('browser-sync');
browserSync({
proxy: {target:'http://mysite.ca/'},
files: "css/*.css",
serveStatic: ['css']
});
and run "node bs.js". It opens a browser window with URL http://localhost:3000/ displaying my remote site. So far so good, and if I make a change to my local custom.css (which is also on the remote site, with the same directory structure) it displays "[Browsersync] File event [change]: css\custom.CSS"
However, nothing changes in the browser window. If I use chrome inspector, the contents of css\custom.CSS have not changed, though the file name has changed to custom.css?browsersync=1606353064487
Why won't it inject the changed CSS file?
Edit: Also, I can see that browser-sync has injected
<script id="__bs_script__">//<![CDATA[
document.write("<script async src='/browser-sync/browser-sync-client.js?v=2.26.13'><\/script>".replace("HOST", location.hostname));
//]]></script>
into the remote site so that is not the problem.
Figured it out. You need staticStatic set to the directory you are serving your local files from. Use rewrite rule if your local directory structure isn't the same as the remote site. match parameter should be the path to the CSS file on the remote site. The return parameter is the name of your local CSS file you will be serving. Seems like it is relative to the serveStatic path, so you don't put the full file path here.
var browserSync = require('browser-sync');
browserSync({
proxy: 'https://mysite.dev/',
files: "./themes/bootstrap_sass/css/*.css",
serveStatic: ['./themes/bootstrap_sass/css'],
rewriteRules: [
{
match: new RegExp('sites/mysite.dev/themes/bootstrap_sass/css/style.css'),
fn: function() {
return 'style.css';
}
}
]
});

Access a local directory to retrieve files from localhost and write back

I currently have an Angular app (MEAN Stack) that I am running locally on my Windows machine. Being new to Node/Express, I would like to be able to access a local directory from http://localhost:3006 that I have setup within my main app directory, called /myfiles which I am unsure how to do.
What I am unsure is, how do I create an endpoint to access and read these files from localhost within the /myfiles directory and display them within an Angular Material dialog?
Just not sure what I need to do as part of Express side (setting up the route) and then the Angular side (using HttpClient) to display.
Further to the above, I will also need to write back to the /myfiles directory, where I will need to perform a copy command based on a file selection within Angular.
You'll want to create an endpoint in Express that your Angular app can call to be served the files.
I'll assume the files you want to read and send are JSON files. Here's a really simple example of an endpoint that you can visit that will return the file to your frontend.
In your Angular code you will make a get call to /myfile
var fs = require("fs");
app.get('/myFile', (req, res) => {
var filepath = __dirname + '/myfiles/thefile.json';
var file = fs.readFileSync(filepath, encoding);
res.json(JSON.parse(file));
});
Then in Angular, you'll have something like
http.get('/myfile').subscribe( (data) => { console.log("The data is: ", data) });
ADDED
The example I provided above was just the basics to answer your question. Ideally, in production for file paths, you should the Node path library which 'knows' how to behave in different environments and file systems.

Signalr hosting client scripts for javascript client in server

I have SingnalR (OWIN self-hosted) server hub working with .net client. Now i'm preparing to write web client. I see that hub scripts are served http://localhost:10102/signalr/hubs but cannot see Scripts/jquery-.min.js and Scripts/jquery.signalR-.min.js.
I assume those scripts are not served from server hub (but by default included by nuget to solution) - am i right or missing something?
Is there a way to reference those scripts directly form server (not to copy and host them on javascript client side)?
General:
https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client:
A JavaScript client requires references to jQuery and the SignalR core
JavaScript file. The jQuery version must be 1.6.4 or major later
versions, such as 1.7.2, 1.8.2, or 1.9.1. If you decide to use the
generated proxy, you also need a reference to the SignalR generated
proxy JavaScript file. The following example shows what the references
might look like in an HTML page that uses the generated proxy.
You have only to add the following scripts to your index.html (take care about the versions):
<script src="Scripts/jquery-1.10.2.min.js"></script>
<script src="Scripts/jquery.signalR-2.1.0.min.js"></script>
<script src="signalr/hubs"></script>
Serve these files from server:
Create directory in server project where you place these JS Files
Configure your server that he serves theses files. For that add app.UseFileServer(); to you Configure(...) method in Startup class. (See details about service files: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files)
Add the required scripts in client. There is an example (change adresses and script file to your files and you server adress:
<script type="text/javascript" src="http://localhost:10310/scripts/signalr-clientES5-1.0.0-alpha2-final.js></script>
Actually, you don't need to have scripts to implement SygnalR service (backend part). To make a connection between client index.html and your service, you need to have some kind of client lib that works with SygnalR to establish a connection.
Here's the EXACT solution I came into, based on answers inside this thread:
Static files (like additional javascript files) can be served within same host with configuration of below. Scripts will be available at http://{yourhost}/scripts/{scriptName} when placed inside \Scripts folder iniside solution ('copy if newer' has to be set for 'Copy To Output Directory' for each of the files).
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
// EnableJSONP = true
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
});
// Serving javascript libraries required for client as static content from Scripts folder
app.UseStaticFiles(new StaticFileOptions() {
RequestPath = new PathString("/scripts"),
FileSystem = new PhysicalFileSystem(#".\Scripts"),
});
}
}
IT Man

Generate one js file from all signalr js files

I had taken the code below form this tutorial initially: SignalR Getting Started Application that will create a chat room. I've cleaned the html code a little bit to get only the part that I am going to need. I verified chat is still working:
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.6.4.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/signalr/jquery.signalR-2.0.0.js"></script>
<script src="/signalr/hubs"></script>
<script type="text/javascript">
$(function () {
var chat = $.connection.chatHub;
chat.client.broadcastMessage = function (name, message) {
console.log('name is: ' + name);
console.log('message is: ' + message);
};
$.connection.hub.start().done(function () {
chat.server.send("khaled7", "message9");
});
});
</script>
As you can there are 3 javascripts files and 1 script block:
Now, I need to join all these scripts into one single file and send that to my remote mobile clients. I'm still at the web side, so I started joining the files/script top down. Joining the top 2 worked OK, but once trying to add the 3rd (/signalr/hubs), I get a 404 error in my chrome console:
http://localhost:52528/HubSample/signalr/negotiate?connectionData=%5B%7B%22name%22%3A%22chathub%22%7D%5D&clientProtocol=1.3&_=1464332439400
It is imperative for me to join them all. How can I go around this error!?
"/signalr/hubs" is not a physical file, it's a dynamically generated JavaScript code.
SignalR creates the JavaScript code for the proxy on the fly and
serves it to the client in response to the "/signalr/hubs" URL.
What you want to do is to create a physical file for the SignalR generated proxy that you can add to your single file:
Install the Microsoft.AspNet.SignalR.Utils NuGet package.
Open a command prompt and browse to the tools folder that contains the SignalR.exe file. The tools folder is at the following location:
[your solution folder]\packages\Microsoft.AspNet.SignalR.Utils.2.1.0\tools
Enter the following command:
signalr ghp /path:[path to the .dll that contains your Hub class]
The path to your .dll is
typically the bin folder in your project folder.
This command creates a file named server.js in the same folder as signalr.exe.
Put the server.js file in an appropriate folder in your project, rename it as appropriate for your application, and add a reference to
it in place of the "signalr/hubs" reference.
The problem is that you'll have to do this for every change in your hubs. Every. Single. time.

How to localhost a webapp with nodejs

I'm working through designing my first webapp, I've already written a significant portion of the frontend and now I want to make a very simple backend to begin implementing some of the functionality. I've spent the last few days learning as much as I can about effective backend development and other various things, but I've run into a huge problem. I fundamentally don't understand how to attach my front end and my backend (which I want to use nodejs for).
All I want is to use my browser to go to localhost:8080 and automatically see the html document with my frontend then within my frontend code have the app communicate with the server (to get json info or instruct the server to add things to a database or things like that).
Once you have installed node in your system.
Folder structure:
Keep your files in public folder inside app folder
Navigate to your application folder in Terminal or Command Prompt:
Then create a file as package.json and keep following code in it:
{
"name" : "YourAppName",
"version" : "0.0.1",
"description" : "App description",
"dependencies" : {
"mime" : "~1.2.7"
}
}
then come back to terminal and run npm install
Then create a file as server.js and keep following code in it:
var http = require("http");
var fs = require("fs");
var path = require("path");
var mime = require("mime");
var cache = {};
function send404(responce){
responce.writeHead(404,{"content-type":"text/plain"});
responce.write("Error 404: resourse not found");
responce.end()
}
function sendFile(responce,filePath,fileContents){
responce.writeHead(200,{"content-type": mime.lookup(path.basename(filePath))});
responce.end(fileContents);
}
function serveStatic(responce,cache,abspath){
if(cache[abspath]){
sendFile(responce,abspath,cache[abspath]);
}else{
fs.exists(abspath,function(exists){
if(exists){
fs.readFile(abspath,function(err,data){
if(err){
send404(responce);
}else{
cache[abspath] = data;
sendFile(responce,abspath,data);
}
})
}else{
send404(responce)
}
})
}
}
var server = http.createServer(function(request,responce){
var filePath = false;
if(request.url == '/'){
filePath = 'public/index.html';
}else{
filePath = 'public'+request.url;
}
var abspath = './'+filePath;
serveStatic(responce,cache,abspath);
})
server.listen(8080,function(){
console.log("server running on 3000");
})
** This code is to help you get started with node js, for better understanding go to node documentation. Read about the mime module too, it is being used here.
You can use free cloud services such as Parse.com. this js sdk
You can use Grunt and using Connect plugin, create a simple server, sufficient for developing pure JS web applications.
Using Grunt basically requires 2 files
package.json
Gruntfile.js
package.json defines the dependencies required by Grunt to run. In your case it would include
grunt
grunt-contrib-connect (The plugin for setting up a server)`
It may also include additional dependencies based on your requirements.
Gruntfile.js defines the configuration for dependencies. In your case how the server should be setup. If you use plugins other that grunt-contrib-connect you should configure them too.
Reference:
Grunt: The JavaScript Task Runner

Categories