Introduction
The SignalR automatically creates the JavaScript proxy script, which helps us to create the SignalR client in JavaScript, but sometimes we don't want to use the proxy script or we are not able to use the proxy script.
Example
- When the client is not running at the same Server, we want to write the proxy script by itself.
- For security reasons, the SignalR Server is configured not to generate the proxy script.
- You want to customize your SignalR client and want full control over your implementation etc.
Hence, I am going to explain how you can create the JavaScript SignalR client on your own without using the generated proxy.
I am going to create a weather app. It will be the same as my previous implementation of weather app, but instead of using the generated proxy script, I will write my own.
If you have not checked my previous article about – Creating a weather app, using SignalR, check it out at the link, given below.
You should have a basic knowledge of the following
- C#
- ASP.NET
- JavaScript
- jQuery
- Socket Communication (Not necessary)
Let’s start.
Create a new project
Create a new Web project with the name WeatherAppDemo with .NET framewrok version 4.5. I am using .NET 4.5, because this will let us use the latest SignalR 2.x version.
Please do not change the name because I am going to use this namespace throughout the article.

Adding signalr Library
- Open NuGet Package Manager.

- Search SignalR in NuGet search and click on First Search Result.

It will install all the libraries needed to create SignalR Application. It will add both the Server library and JavaScript client library.
You will notice there are many results of SignaR search, so the question will be- what will happen, if you click on others.
Actually they are separate libraries of SignalR for different purposes but we need the complete package because we are going to create SignalR Server as well as client.
- Add new folder in the project with name SignalR.

I am doing this because I want to keep the code related to SignalR to a different folder.
Configuring signalr
- Creating hub class
Add a new class in the SignalR folder with the name ChatHub and paste the code, given below.
WHAT WE ARE DOING HERE- using Microsoft.AspNet.SignalR;
- using Microsoft.AspNet.SignalR.Hubs;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- namespace WeatherAppDemo.SignalR {
- public class ChatHub: Hub {
- [HubMethodName("change_weather")]
- public void ChangeWeather(int temperature) {
- //Clients is ConnectionContext, it holds the information about all the connection.
- //Others in 'Clients.Others' is holding the list of all connected user except the caller user
- //(the user which has called this method).
- //NotifyUser is a function on the clientside, you will understand it later.
- Clients.Others.NotifyUser(temperature);
- }
- }
- }
The class ChatHub is inhereting a hub class, that means we are making the ChatHub class act like hub of the communication.
We have defined a ChangeWeather function, which is taking a parameter temperature and it is calling NotifyUser of the client side with the parameter temperature.
- Mapping hubs to the SignalR pipeline
Add a new class in the SignalR folder with the name StartUp and paste the code, given below, in the StartUp.cs.
WHAT WE ARE DOING HERE.- using Microsoft.Owin;
- using Owin;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- [assembly: OwinStartup(typeof(WeatherAppDemo.SignalR.StartUp))]
- namespace WeatherAppDemo.SignalR {
- public class StartUp {
- public void Configuration(IAppBuilder app) {
- app.MapSignalR();
- }
- }
- }
- We are calling owinstartup with the parameter WeatherAppDemo.SignalR.StartUp, which will initialize our StartUp class.
- In the StartUp class, we are using app.MapSignalR() – it will map SignalR hubs to the app builder pipeline. Simply, what it does is that it will add the hubs to the SignalR pipeline, so that you can access it with URL. The URL of the SignalR is in the form of- /SignalR.
e.g abc.com/signalr
Basically, we are doing two things -- we are first starting the StartUp class and adding the hubs to the SignalR pipeline.
Now, compile the code and append this “/SignalR/hubs” at the URL. You will have some JavaScript code.
If you are able to see JavaScript code, then you have successfully configured a SignalR Server.

Creating Client
Hence, we need to create two clients, which are-
- First, who will change the weather?
- Second, who will receive the notification?
STEP TO CREATE A BASIC JAVASCRIPT CLIENT
- Create a HTML page.
- Include jquery.js library into HTML page. (You will find jQuery into the script folder).
- Include signalr.js library into HTML page.(You will find SignalR into the script folder).
Add a script with the src=”/signalr/hubs”. (It is a JavaScript proxy generated by SignalR Server).We are going to write our own code to create the proxy.- Write some JS code to talk with Signalr Server (I am going to write this code in the next paragraph).
CREATE CHANGEWEATHER CLIENT
Follow the steps to create a basic JavaScript client and in the last step paste the code, given below, in the script tag.
- var SignalrConnection;
- var ChatProxy;
- function Connect() {
- ChatServerUrl = "http://localhost:58416/";
- var ChatUrl = ChatServerUrl + "signalr";
- //This will hold the connection to the signalr hub
- SignalrConnection = $.hubConnection(ChatUrl, {
- useDefaultPath: false
- });
- ChatProxy = SignalrConnection.createHubProxy('ChatHub');
- //connecting the client to the signalr hub
- SignalrConnection.start().done(function() {
- alert("Connected to Signalr Server");
- })
- .fail(function() {
- alert("failed in connecting to the signalr server");
- })
- }
- function ChangeWeather() {
- //get the temperature from a textfield with id txtTemprature
- var Temperature = document.getElementById('txtTemperature').value;
- //calling the ChangeWeather function on the signalr server
- ChatProxy.invoke('change_weather', Temperature);
- }
It’s time for our HTML page design; just copy the code, given below.
- <body onload="Connect();">
- <div style="text-align:center;">
- <input type="text" id="txtTemperature" />
- <button id="btnChange" onclick="ChangeWeather();">Change Weather</button>
- </div>
- </body>
CREATE RECIEVEWEATHERNOTIFICATION CLIENT
Follow the steps to create a basic JavaScript client and in the last step, paste the code, given below in the script tag.
- var SignalrConnection;
- var ChatProxy;
- function Connect() {
- ChatServerUrl = "http://localhost:58416/";
- var ChatUrl = ChatServerUrl + "signalr";
- //This will hold the connection to the signalr hub
- SignalrConnection = $.hubConnection(ChatUrl, {
- useDefaultPath: false
- });
- ChatProxy = SignalrConnection.createHubProxy('ChatHub');
- //This will be called by signalr
- ChatProxy.on("NotifyUser",function (temperature) {
- $('span').text(temperature);
- });
- //connecting the client to the signalr hub
- SignalrConnection.start().done(function() {
- alert("Connected to Signalr Server");
- })
- .fail(function() {
- alert("failed in connecting to the signalr server");
- })
- }
Html page design is very simple, check the code, given below.
- <div style="text-align:center;">
- Temperature : <span></span> ℃
- </div>
- Compile the code.
- Open the ChangeWeather.html.
- Open RecieveWeatherNotification in the other tabs (open in multiple tab or multiple Browser).
- Change the weather in ChangeWeather.html and observe the temperature in the RecieveWeatherNotification.html.
Notice, when you will open RecieveWeatherNotification.html for the first time, there is no temperature, which is not good – I mean there should be some initial temperature. Now, what do we need to do?
- We need to keep the temperature in a static variable, so that it will be the same for all the objects of ChatHub.
- When the RecieveWeatherNotification.html will be connected to SignalR Server, it will call the SignalR Server to get the current temperature.
- We will have to create a function (HubMethod) in Chathub, which will be called by RecieveWeatherNotification.html to get the currenttemperature. The function will call NotifyUser of the client side to set the temperature.
Adding Extra Feature(Making more real)
I have described above, what I am going to do, so just copy the code, given below and update the ChatHub class.
- using Microsoft.AspNet.SignalR;
- using Microsoft.AspNet.SignalR.Hubs;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- namespace WeatherAppDemo.SignalR {
- public class ChatHub: Hub {
- //keeping temperature variable static will make the value temperature
- //to be stored in memory permanently and will be equal to all the
- //object of chathub.
- static int Temperature;
- [HubMethodName("change_weather")]
- public void ChangeWeather(int temperature) {
- //change the temperature
- Temperature = temperature;
- //Clients is ConnectionContext, it holds the information about all
- //the connection.
- //Others in 'Clients.Others' is holding the list of all connected
- //user except the caller user (the user which has called this method)
- //NotifyUser is a function on the clientside, you will understand it
- //later.
- Clients.Others.NotifyUser(temperature);
- }
- [HubMethodName("get_weather")]
- public void GetWeather()
- {
- //pushing the data only to the user which has called this method.
- Clients.Caller.NotifyUser(Temperature);
- }
- }
- }
To update RecieveWeatherNotification.html, copy the code, given below and update with previous code.
- var SignalrConnection;
- var ChatProxy;
- function Connect() {
- ChatServerUrl = "http://localhost:58416/";
- var ChatUrl = ChatServerUrl + "signalr";
- //This will hold the connection to the signalr hub
- SignalrConnection = $.hubConnection(ChatUrl, {
- useDefaultPath: false
- });
- ChatProxy = SignalrConnection.createHubProxy('ChatHub');
- //This will be called by signalr
- ChatProxy.on("NotifyUser",function (temperature) {
- $('span').text(temperature);
- });
- //connecting the client to the signalr hub
- SignalrConnection.start().done(function() {
- GetWeather();
- alert("Connected to Signalr Server");
- })
- .fail(function() {
- alert("failed in connecting to the signalr server");
- })
- }
- function GetWeather() {
- //calling the GetWeather function on the signalr server
- ChatProxy.invoke('get_weather');
- }
- I have created a method GetWeather, which will call the ChatHubmethod “get_weather”
- I am calling the GetWeather, when the client is connected to the SignalR.
Hence, compile the code and check out everything.
References
- https://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client

Sachin SinghPosted Nov 24, 2019, 6:32 AM
I have created a html file which runs fine and hub get connected to signalr. however, I want to add to gitlab and run in pipeline, but there isn't any tool avaialble which run - html+js, so can I run this by only writing javascript?
Sameer ParabPosted May 20, 2019, 3:25 AM
Nice Article ! How can I add custom headers to signalR output ?
Malik AmlodiPosted May 3, 2018, 1:15 AM
Hi Ujjwal. It's me again. I tried this one. This time i'm getting this error -> Failed to load http://localhost:22222/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%5D&_=1525327952531: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:55466' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute. Before I was having similar issues with my existing apis so I added the <add name="Access-Control-Allow-Origin" value="*" /> in my web.config but this seems to be conflicting with the signalr call.
Ravi KPosted Apr 16, 2018, 7:20 AM
Hi Ujjwal.. what would be the deployment settings for this especially on production server .. for ChatServerUrl = "http://localhost:58416/";
pham tuanPosted Aug 14, 2017, 7:21 AM
Hello, I have tried to do same as your code but I have got this error No 'Access-Control-Allow-Origin' header is present on the requested even my server code is enbale cross site all 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(Microsoft.Owin.Cors.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. hubConfiguration.EnableDetailedErrors = true; map.RunSignalR(hubConfiguration); var idProvider = new PrincipalUserIdProvider(); GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => idProvider); });
Prasanna MuraliPosted Oct 22, 2016, 12:06 PM
Nice post..
RajaPosted Oct 21, 2016, 8:31 AM
Good one...
Sandeep Singh ShekhawatPosted Oct 19, 2016, 9:37 PM
Good! You are still using JavaScript proxy script to create client where is manual process?