Use SignalR for notification from wcf to JS

I want to use SignalR to recognize the SignalR client on the WCF service and send messages to it even without a request. (That is, after the first request that the client sends to the service, the service can recognize it and send him messages).

I don't know if this is the best for this, but all I could find. (Except WebSocket, which are only supported in VS 2012).

I added the following function to the Global file in the Service:

 protected void Application_Start(object sender, EventArgs e) { RouteTable.Routes.MapHubs(); } 

I created Chat.cs:

 public class Chat : Hub { public void Send(string message) { // Call the addMessage method on all clients Clients.All.addMessage(message); } } 

In the JS project, I added JS SignalR files:

 <script src="../JavaScript/jquery.signalR-1.1.2.min.js" type="text/javascript"></script> <script src="/signalr/hubs" type="text/javascript"></script> 

The function that uses it:

 function Chat() { $(function () { // Proxy created on the fly var chat = $.connection.chat; // Declare a function on the chat hub so the server can invoke it chat.client.addMessage = function (message) { alert(message); }; // Start the connection $.connection.hub.start().done(function () { // Call the chat method on the server chat.server.send('aa'); }); }); } 

This is something new for me so sorry if the question is stupid, but how should SignalR JS know the Service, where should I define it? (This requires a cross-domain)

(The variable $.connection.chat is Undefined)

I'm sure I missed a few things, especially the main thing is that it connect the service and JS through SignalR ?

+2
source share
2 answers

What I was missing was using SignalR with cross-domain .

In the global file, I changed the code:

 protected void Application_Start(object sender, EventArgs e) { RouteTable.Routes.MapHubs(new HubConfiguration() { EnableCrossDomain = true }); } 

It is important to note that since I use a cross-domain, I have a code in the Application_BeginRequest function that should cancel it when SignalR done SignalR request otherwise it does not work . So I canceled it like this:

  protected void Application_BeginRequest(object sender, EventArgs e) { //Here is testing whether this request SignalR, if not I do the following code if (HttpContext.Current.Request.Path.IndexOf("signalr") == -1) { HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache); HttpContext.Current.Response.Cache.SetNoStore(); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); if (HttpContext.Current.Request.HttpMethod == "OPTIONS") { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, x-requested-with"); HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); HttpContext.Current.Response.End(); } } } 

On the client:

I added SignalR and SignalR scripts, and I deleted this script:

<script src="/signalr/hubs" type="text/javascript"></script>

Because cross-domain calls are not needed.

The connection is in the following function:

 var connection; var contosoChatHubProxy; function RegisterToServiceMessege() { connection = $.hubConnection(); connection.url = 'http://localhost:xxx/signalr'; contosoChatHubProxy = connection.createHubProxy('ChatHub'); //This part happens when function broadcastMessage is activated(from the server) contosoChatHubProxy.on('broadcastMessage', function (userName, message) { alert('You have a messege:\n' + userName + ' ' + message); }); connection.start() .done(function () { console.log('Now connected, connection ID=' + connection.id); }) .fail(function () { console.log('Could not connect'); }); } 

Chat.cs on the server:

  [HubName("ChatHub")] public class Chat : Hub { [HubMethodName("Send")] public void Send(string name, string message) { // Call the broadcastMessage method to update clients. Clients.All.broadcastMessage(name, message); } } 

Calling the Send function from one of the clients:

 function SendMessege() { contosoChatHubProxy.invoke('Send', 'aaa', 'bbb').done(function () { console.log('Invocation of NewContosoChatMessage succeeded'); }).fail(function (error) { console.log('Invocation of NewContosoChatMessage failed. Error: ' + error); }); } 

All customers receive a sent message.

(You can verify this by running multiple browsers at the same time.)

+2
source

Starting with SignalR version 2.0, you can no longer use Cors with this code:

  protected void Application_Start (object sender, EventArgs e)
     {
        RouteTable.Routes.MapHubs (new HubConfiguration () {EnableCrossDomain = true}); 
     }

Instead, you should add these two lines to your Startup class initialization method:

 public void Configuration(IAppBuilder app) { app.UseCors(CorsOptions.AllowAll); app.MapSignalR(); } 

And, which may not be obvious to everyone, if you do not want to host SignalR using your own hosting library, be sure to change your project to WebApplication. In my case, I tried to add Signalr to WCFProject. And the runtime will not even go to this Startup configuration Method, thereby causing persistent errors prohibiting access to signalr resources

+1
source

Source: https://habr.com/ru/post/1489095/


All Articles