Giter Site home page Giter Site logo

ng2-signalr's Introduction

npm version live demo Coverage Status Build Status

ng2-signalr

An angular typescript library that allows you to connect to Asp.Net SignalR

Features:

  1. 100% typescript
  2. use rxjs to observe server events
  3. write unit tests easy using the provided SignalrConnectionMockManager & ActivatedRouteMock

ng2-signalr source: ng2 signalr demo
demo : demo (can take longer to load. Sorry, azure free tier :-))
ng cli example: ng cli example

Installation

npm install ng2-signalr jquery signalr --save

v5 is first version developed against angular v5. angular v4 users should use v2.2.1.

Setup

inside app.module.ts

import { SignalRModule } from 'ng2-signalr';
import { SignalRConfiguration } from 'ng2-signalr';

// >= v2.0.0
export function createConfig(): SignalRConfiguration {
  const c = new SignalRConfiguration();
  c.hubName = 'Ng2SignalRHub';
  c.qs = { user: 'donald' };
  c.url = 'http://ng2-signalr-backend.azurewebsites.net/';
  c.logging = true;
  
  // >= v5.0.0
  c.executeEventsInZone = true; // optional, default is true
  c.executeErrorsInZone = false; // optional, default is false
  c.executeStatusChangeInZone = true; // optional, default is true
  return c;
}


@NgModule({
  imports: [ 
    SignalRModule.forRoot(createConfig)
  ]
})

// v1.0.9
const config = new SignalRConfiguration();
config.hubName = 'Ng2SignalRHub';
config.qs = { user: 'donald' };
config.url = 'http://ng2-signalr-backend.azurewebsites.net/';

@NgModule({
  imports: [ 
    SignalRModule.configure(config)
  ]
})

setup ngcli

inside angular-cli.json

"scripts": [
          "../node_modules/jquery/dist/jquery.min.js",
          "../node_modules/signalr/jquery.signalR.js"
],

Create connection

There exist 2 ways to create a connection:

1. inject connection

This approach is preferable. You can easily rely on the default router navigation events (NavigationStart/End) to keep your user busy while the connection establishment is ongoing. Secondly you can inject the connection directly, facilitating easier unit testing. Setup involves 3 steps.

// 1. if you want your component code to be testable, it is best to use a route resolver and make the connection there
import { Resolve } from '@angular/router';
import { SignalR, SignalRConnection } from 'ng2-signalr';
import { Injectable } from '@angular/core';

@Injectable()
export class ConnectionResolver implements Resolve<SignalRConnection> {

    constructor(private _signalR: SignalR)  { }

    resolve() {
        console.log('ConnectionResolver. Resolving...');
        return this._signalR.connect();
    }
}

// 2. use the resolver to resolve 'connection' when navigation to the your page/component
import { Route } from '@angular/router';
import { DocumentationComponent } from './index';
import { ConnectionResolver } from './documentation.route.resolver';

export const DocumentationRoutes: Route[] = [
	{
		path: 'documentation',
    component: DocumentationComponent,
     resolve: { connection: ConnectionResolver }
	}
];

// 3. then inside your component
 export class ChatComponent {
  private _connection: SignalRConnection;

  constructor(route: ActivatedRoute) {    
  }
  
  ngOnInit() {
      this.connection = this.route.snapshot.data['connection'];
  }
  
}    

2. inject signalr

Creating a client-server connection can be done by calling the connect method on the Signalr instance.

// inside your component.
constructor(private _signalR: SignalR)  {
}

someFunction() {
    this._signalR.connect().then((c) => {
      //do stuff
    });
    
    
    
}

This approach has several drawbacks: WaitTime:

  • Take into account, it can take several second to establish connection with the server and thus for the promise to resolve. This is especially true when a websocket-transport connection is not possible and signalr tries to fallback to other transports like serverSentEevents and long polling. Is it adviceable to keep your end user aware by showing some form of progress.
    More difficult to unit test:
  • If you want to write unit tests against the connection, you need to mock Signalr instance first.

listen to connectionstatus changes during connect (>= v2.0.6)

From version 2.0.6 onwards you can subscribe to connectionstatus changes upon connecting to the server. Forst you ask signalr to create a connection. Then on the connection object you can subscribe to the status observable before calling the start method.

FYI: connect() is now shorthand for createConnection().start(), meaning without subscribing to status changes

let conx = this._signalR.createConnection();
conx.status.subscribe((s) => console.warn(s.name));
conx.start().then((c) => {
...
});

Configuration

You can configure Singalr on 2 different levels:

1. Module level:

The module level, is where you typically provide the default configuration. This is were you pass in the default hubname, serverurl, qs (query string parameters), and transport. When, somewhere in your application, Singalr.connect() method is invoked without parameters, it will use this default configuration.

import { SignalRModule } from 'ng2-signalr';
import { SignalRConfiguration, ConnectionTransport } from 'ng2-signalr';

// <= v1.0.9
const config = new SignalRConfiguration();
config.hubName = 'Ng2SignalRHub';  //default
config.qs = { user: 'donald' };
config.url = 'http://ng2-signalr-backend.azurewebsites.net/';
// Specify one Transport: config.transport = ConnectionTransports.longPolling; or fallback options with order like below. Defaults to best avaliable connection.
config.transport = [ConnectionTransports.webSockets, ConnectionTransports.longPolling];

@NgModule({
  imports: [ 
    SignalRModule.configure(config)
  ]
})
...

Signalr.connect(); //HERE: module level configuration is used when trying to connect

2. Connection level:

You can always configure signalr on a per connection level. For this, you need to invoke Singalr.connect(options) method, passing in an options parameter, of type ConnectionOptions. Behind the scenes, Signalr connect method will merge the provided options parameter, with the default (module) configuration, into a new configuration object, and pass that to signalr backend.

import { SignalRModule } from 'ng2-signalr';
import { IConnectionOptions, SignalR } from 'ng2-signalr';

let options: IConnectionOptions = { hubName: 'MyHub' };
Signalr.connect(options);

How to listen for server side events

// 1.create a listener object
let onMessageSent$ = new BroadcastEventListener<ChatMessage>('ON_MESSAGE_SENT');
 
// 2.register the listener
this.connection.listen(onMessageSent$);
 
// 3.subscribe for incoming messages
onMessageSent$.subscribe((chatMessage: ChatMessage) => {
       this.chatMessages.push(chatMessage);
});

listenFor shorthand:

When using listenFor method, you can skip the first step in the approach above. Here the listen method returns you the BroadvastEventListener, that you can then subscribe to.

let onMessageSent$  = this.connection.listenFor('ON_MESSAGE_SENT');
onMessageSent$.subscribe( ...

listenForRaw:

When using listenForRaw method, you can cast original data form signalr client callback. Here the listen method returns you the any[] of BroadvastEventListener, that you can then subscribe to.

let onMessageSent$  = this.connection.listenForRaw('ON_MESSAGE_SENT');
onMessageSent$.subscribe((data: any[]) => ....);

How to invoke a server method

// invoke a server side method
this.connection.invoke('GetNgBeSpeakers').then((data: string[]) => {
     this.speakers = data;
});

// invoke a server side method, with parameters
this.connection.invoke('ServerMethodName', new Parameters()).then((data: string[]) => {
     this.members = data;
});

How to listen for connection status

this.connection.status.subscribe((status: ConnectionStatus) => {
     this.statuses.push(status);
});

Also supported

// start/stop the connection
this.connection.start();
this.connection.stop();
 
// listen for connection errors
this.connection.errors.subscribe((error: any) => {
     this.errors.push(error);
});

Unit testing

Ng2-signalr comes with a component, specifically built, for making your unit tests easy to write and with few lines of code: SignarlMockManager. The 'SignarlMockManager', can be asked a mocked implementation of your signalr client connection, be using its mock property. The mock connection it's interface is identical to any real signalr connection, that you get back from the Signarl.connect() method. You can use the mock to spy on certain method calls, and verify invocations in your tests. Also, on the mockmanager itself, you will find methods to trigger 'server' like behavior. Both errors$ and status$ properties, can be used for this, and simulate server errors or connectionstatus changes. For more information about, the signarl connection lifecycle, I refer to the official documentation, section Transport disconnection scenarios. Also, the listeners property on the MockManager, holds a collection of all client-server method observers, returned as rxjs subjects. These subject can then be used to simulate a server message being sent over the wire.

 it('I want to simulate an error or status event, in my unit test',
    inject([ChatComponent], (component: ChatComponent) => {

      connectionMockManager.errors$.next('An error occured');  //triggers the connection.error.subscribe(() => {});
      connectionMockManager.status$.next(ConnectionStatuses.slowConnection); //triggers the connection.status.subscribe(() => {});
      ....

}));

it('I want to simulate several ChatMessages received, in my unit test',
    inject([ChatComponent], (component: ChatComponent) => {

      let publisher = connectionMockManager.listeners['OnMessageSent'];

      publisher.next(new ChatMessage('Hannes', 'a message')); //triggers the BroadcastEventListener.subscribe(() => {});
      publisher.next(new ChatMessage('Hannes', 'a second message')); // ''

      expect(component.chatMessages).toEqual([
            new ChatMessage('Hannes', 'a message'),
            new ChatMessage('Hannes', 'a second message')
          ]);
}));

For more info, certainly check out the live demo, unit testing section.

Breaking changes

v2.0.6 going from <2.0.6 to 2.0.6 ConnectionStatus refactoring

  1. removed ConnectionStatus.starting
  2. removed ConnectionStatus.received
  3. removed ConnectionStatus.connectionSlow
  4. removed ConnectionStatus.reconnected
  5. removed ConnectionStatus.stateChanged

v2.0.0 going from 1.0.X to 2.0.0 there will be some breaking changes.

type renames:

  1. ConnectionOptions to IConnectionOptions
  2. ListenerCollection to IListenerCollection
  3. SignalRConnectionBase to ISignalRConnection

configuration:
4. SignalRModule.configure(c: SingalRConfiguration) to SignalR.forRoot(() => SingalRConfiguration);

Detailed webpack install

npm install jquery signalr expose-loader --save

//inside vendor.ts
import 'expose-loader?jQuery!jquery';
import '../node_modules/signalr/jquery.signalR.js';

Detailed systemjs install (starting from v2.0.0)

 {
   'ng2-signalr' : 'node_modules/ng2-signalr/bundles/ng2-singalr.umd.(?min).js'
 }

af93c8777fb64c74f74a875e5da60a168f410e06

Issue Reporting

If you have found a bug or if you have a feature request, please report them at this repository issues section.

Contributing

Pull requests are welcome!

Building

Use npm build to compile and build. A /dist folder is generated.

Publish

Navigate to dist/ng2-signalr and run npm publish.

##TODO: Code coverage

Use npm test cmd to compile and run all tests.

Unit testing

Use npm test cmd to compile and run all tests. Test runner is configured with autowatching and 'progress' as test reporter.

ng2-signalr's People

Contributors

alan-agius4 avatar aleguardiola avatar davemonag avatar davidgabrichidze avatar deondupreez avatar hneukermans avatar italojs avatar jpalmowski avatar leifjones avatar perfectlynormal avatar plchampigny avatar pruttned avatar saaka avatar shaulbehr avatar thduttonuk avatar wizgob avatar yurlovm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ng2-signalr's Issues

Connection status never returns "connected"

I've noticed that when running
this.connection.status.subscribe(status => console.log(status));
You only seem to get back "stateChanged", "disconnected" and "recieved", but never "connected" when the connection is established. Is this expected behavior? If so, how am I supposed to base something off the knowledge that it is connected? For example, I just want an icon in the top left that shows green when SignalR is connected to a hub, and red when not connected. Is this possible?

ng2-signalr can't be compiled

Hi,

E:\opensource-project\temp-aspnet\angularcli\d3-ng2-demo-master>ng serve
** NG Live Development Server is running on http://localhost:4200 **
Hash: fb506f72cd9ce73e44ce
Time: 35399ms
chunk {0} main.bundle.js, main.bundle.js.map (main) 51.7 kB {2} [initial] [rendered]
chunk {1} styles.bundle.js, styles.bundle.js.map (styles) 129 kB {3} [initial] [rendered]
chunk {2} vendor.bundle.js, vendor.bundle.js.map (vendor) 3.07 MB [initial] [rendered]
chunk {3} inline.bundle.js, inline.bundle.js.map (inline) 0 bytes [entry] [rendered]

ERROR in E:/opensource-project/temp-aspnet/angularcli/d3-ng2-demo-master/node_modules/ng2-signalr/lib/testing/helpers/activated.route.mock.d.ts (4,22)
: Class 'ActivatedRouteMock' incorrectly implements interface 'ActivatedRoute'.
Property 'paramMap' is missing in type 'ActivatedRouteMock'.
webpack: Failed to compile.

E:\opensource-project\temp-aspnet\angularcli\d3-ng2-demo-master>npm ls ng2-signalr
[email protected] E:\opensource-project\temp-aspnet\angularcli\d3-ng2-demo-master
+-- UNMET PEER DEPENDENCY @angular/[email protected] -> E:\opensource-project\temp-aspnet\angularcli\d3-ng2-demo-master\node_modules.4.0.0@@angular\core
`-- [email protected] -> E:\opensource-project\temp-aspnet\angularcli\d3-ng2-demo-master\node_modules.1.0.9@ng2-signalr

Thank you!

Slow communication

Hi @HNeukermans ,

I am not sure is it happening in everywhere.

But I am finding it in

http://signalr-example.azurewebsites.net/chat

And

http://ng2-signalr-webui.azurewebsites.net/dashboard/chat

And in my localhost.

The issue is, the signalR client is running so much slow.

That is, if I make a request to the server, it needs some time (2-5 s) while SignalR works in real time.

So, if we use this library, we are getting a latency time.

As far as I have found, it is because of creating connections each time when client tries to send a data in the server (not sure) while there is already a persistent connection of signalR.

Please verify that and let us know.

Thanks

Newbie help please

Hi,
I'm trying to integrate ng2-signalr into my ng2 project.
The sample code given on the home page does not compile. (this.connection does not exist).
Do you have some working sample code that demonstrates usage?
Thanks!

Request to add a cpmplete demo with ASP.Net MVC with signalR

Hi,
This example is great-
http://ng2-signalr-webui.azurewebsites.net/dashboard/element

But, it will be even better if you add an example with ASP.Net Core/MVC, Angular2 and ng2-signalR and share the code with us (in Github) so that we can run and test that.

That will make this repo more useful because currently, we are facing some difficulties in connecting signalR.

So, if you make an example, that would be great and a great help for developers ๐Ÿ‘ and that will make this repo a great repo because Angular2 has not a complete SignalR library like this ๐Ÿฅ‡

Think you get me @HNeukermans ๐Ÿ’ฏ

angular-cli example

Could you provide a basic "hello world" example by using angular-cli?
Anyway, thank you!

Multiple messages not supported

If Iam listening to an event eg. "MessageReceived", then it returns just the first argument of the message.
At casted = <T> args[0]; its smarter to assign the whole array: casted = args;.
I tried it and for me it works perfectly.
Now we can receive a message with a tuple as array.

[Enhancement] Get SignalRConnection without actually starting it

Hi there,

at first thanks for this well structured library.
In SignalR it is common usage to directly call back client methods in the OnConnected server hub event.
As your SignalR.connect() method instantly starts the connection, one can only attach listeners after connection is established. This way the cllient has no chance to get notified during connect.
So it would be nice to have the possibility to attach listeners before the connection is started.

Thanks and regards
Hannes

Signalr.connect should allow configuration override

Current there is only 1 place configure singalr. = during module configuration.
This makes dynamic configuration impossible.

Solution:
Signalr.connect() (without parameter) should start a connection using the default configuration found in the module.
Overriding default configuration should be supported using the Signalr.connect(config SignalRConfiguration), passing in all default configuration overrides.

I propose to make all properties of SignalRConfiguration optional.

Calling function 'SignalRModule', function calls are not supported.

I'm using the Angular-cli to make a very basic "Hello world" app with SignalR using your module, and I keep getting this:

ERROR in Error encountered resolving symbol values statically. Calling function 'SignalRModule', function calls are not supported. Consider replacing the function
or lambda with a reference to an exported function, resolving symbol AppModule in C:/code/Ang2SR/src/app/app.module.ts, resolving symbol AppModule in C:/code/Ang2S
R/src/app/app.module.ts
webpack: Failed to compile.

My app.module:


import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { EchoComponent } from './echo/echo.component';
import { signalrConfiguration } from './app.config';
import { SignalRModule, SignalRConnection, ConnectionStatus, BroadcastEventListener } from 'ng2-signalr';

@NgModule({
  declarations: [
    AppComponent,
    EchoComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    SignalRModule.configure(signalrConfiguration)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.config.ts:


import { SignalRConfiguration } from 'ng2-signalr';

const signalrConfig = new SignalRConfiguration();
signalrConfig.hubName = 'echoHub';
signalrConfig.qs = { user: 'Hannes' };
signalrConfig.url = 'http://localhost:44369/signalr/hubs';


export const signalrConfiguration = signalrConfig;

Has this got something to do with publishing metadata/AoT?
Any ideas?

Build warning with 2.0.3

I got the following warning building with Angular CLI:

Warning: Can't resolve all parameters for SignalR in C:/work/redacted/node_modules/ng2-signalr/src/services/signalr.d.ts: ([object Object], [object Object], ?). This will become an error in Angular v5.x

Everything is working fine, just flagging this if you are not aware ๐Ÿ˜ƒ

I am using Angular 4.0.1, Angular CLI is 1.0.0, and ng2-signalr is 2.0.3 โœจ .

Error with Angular Cli build using AOT option

I haven't added much after generating a angular project using Angular Cli, except for a few components. One using SignalR.

This warning bellow makes it impossible to compile with --prod or --aot options in Angular Cli...

Warning: Can't resolve all parameters for SignalR in C:/front-end/beskr
.../node_modules/ng2-signalr/src/services/signalr.d.ts: ([object Object], [object Object], ?). This will become an error in Angular v5.x

package.json

{
  "name": "beskrivelse-frontend",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.0.0",
    "@angular/forms": "^4.0.0",
    "@angular/http": "^4.0.0",
    "@angular/platform-browser": "^4.0.0",
    "@angular/platform-browser-dynamic": "^4.0.0",
    "@angular/router": "^4.0.0",
    "@biesbjerg/ngx-translate-po-http-loader": "^1.0.1",
    "@ngrx/core": "^1.2.0",
    "@ngrx/store": "^2.2.2",
    "@ngrx/store-devtools": "^3.2.4",
    "@ngx-translate/core": "^6.0.1",
    "angular2-jwt": "^0.2.3",
    "core-js": "^2.4.1",
    "devextreme": "^16.2.6",
    "devextreme-angular": "^16.2.6",
    "ng2-cookies": "^1.0.12",
    "ng2-signalr": "^2.0.3",
    "rxjs": "^5.1.0",
    "signalr": "^2.2.1",
    "ts-md5": "^1.2.0",
    "zone.js": "^0.8.4"
  },
  "devDependencies": {
    "@angular/cli": "1.0.0",
    "@angular/compiler-cli": "^4.0.0",
    "@types/jasmine": "2.5.38",
    "@types/node": "~6.0.60",
    "codelyzer": "~2.0.0",
    "jasmine-core": "~2.5.2",
    "jasmine-spec-reporter": "~3.2.0",
    "karma": "~1.4.1",
    "karma-chrome-launcher": "~2.0.0",
    "karma-cli": "~1.0.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "karma-coverage-istanbul-reporter": "^0.2.0",
    "protractor": "~5.1.0",
    "ts-node": "~2.0.0",
    "tslint": "~4.5.0",
    "typescript": "~2.2.0"
  }
}

app.module


// signalR setup
export function createConfig(): SignalRConfiguration {
  const signalRConfig = new SignalRConfiguration();

  signalRConfig.hubName = 'Ng2SignalRHub';
  signalRConfig.qs = {
    user: 'test user'
  };
  signalRConfig.url = 'http://ng2-signalr-backend.azurewebsites.net/';
  signalRConfig.logging = true;

  return signalRConfig;
}

(...)
  imports: [
    SignalRModule.forRoot(createConfig),


Make signalr code run inside ngZone() configurable behavior

Currently all signalr code is run inside a ngzone. This means every signalr callback received triggers a
angular change detection.

To allow developer the choice of having it automatically run inside zone.run or to hve more control over when change detection is run we should make this behavior configurable.

something like:
configuration.executeEventsInZone
configuration.executeErrorsInZone
configuration.executeStatusChangeInZone

connect() causing change detection every two seconds

I've noticed that angular is running change detection about every 2 seconds once I call connect. Is this a known issue? Is there a way around it? I've connected with websockets.

`

    public constructor(private signalR: SignalR) { }
public Connect() {
	const config: IConnectionOptions = {};
	config.hubName = "ClientHub";
	config.qs = token;
	config.url = url;

            // causes change detection to run continuously, even without a subscription.
	this.signalR.connect(config);
}`

How to set Authorization Header ?

I am using ng2-signalrin ionic 2. Issue is that i don't know how to set authorization header. I have search but didn't find any example.

My code for connecting to server hub.

   let options: IConnectionOptions = { qs:{userId:1}, url: "http://192.168.0.211:44337"};
                
		console.log("Stage 1");
			//Header for 'this.singalR.connect'
        this.signalR.connect(options)
            .then((connection) => {                      
        
                console.log("Client Id: " + connection.id);                     
             }, (err) => {
                console.log("SignalR Error: " + JSON.stringify(err));
            });

How to set below header ?

  var headers = new Headers({
            'Content-Type': "application/json",
            "Authorization": 'Bearer ' + accessToken  //accessToken contain bearer value.
        });

Note: Before implementing Authorization same code working fine as i don't need to set authorization header.

Need to send "Origin" header when connecting from JavaScript to avoid CORS problems

Hi,
My SignalR host is an Azure App Service. The CORS behavior seems to be different from other hosts, in that if you don't explicitly send an "Origin" header in the connection request, it does not respond with an "Access-Control-Allow-Origin" header, and the browser spits out a CORS error.
Is there some way to do this in the current release, or is that a new feature?

Update to Angular 4

Would it be possible to update the application to the latest version of Angular and TypeScript? I am willing to create a branch and do the work if given permission. The application may also need a renaming from ng2-signalr to a more generic ng-signalr.

Thanks!

dynamic url config at module level

Hey,
As I see we need to supply function that returns SignalRConfiguration object,
my case contain read signalr url from json file(which I prefer doing in APP_INITIALIZER),
so it necessary to override 'this':
SignalRModule.forRoot(createConfig.bind(this)),
or call some service(which inject http service),
or maybe you can think about an alternative way?

'jquery.js' is missing.

Signalr failed to initialize. Script 'jquery.js' is missing. Please make sure to include jquery script.
at getJquery (signalr-module.js:31)

this._signalR.connect is not a function

I'm using https://github.com/aspnet/JavaScriptServices as starting point. Following all the instructions provided in readme i still got an error.

Firstly I had this error:

EXCEPTION: Signalr failed to initialize. Script 'jquery.js' is missing. Please make sure to include jquery script.

then I have tried to do different way and I do have this error now:

this._signalR.connect is not a function

my setup:

app.module.ts

import { NgModule } from "@angular/core";
import { RouterModule } from "@angular/router";
import { UniversalModule } from "angular2-universal";
import { AppComponent } from "./components/app/app.component";
import { SignalRModule } from "ng2-signalr";

@NgModule({
    bootstrap: [ AppComponent ],
    declarations: [
        AppComponent
    ],
    imports: [
        UniversalModule, // Must be first import. This automatically imports BrowserModule, HttpModule, and JsonpModule too.
        RouterModule.forRoot([
            { path: '', redirectTo: 'home', pathMatch: 'full' },
            { path: '**', redirectTo: 'home' }
        ]),
        SignalRModule
    ]
})

export class AppModule {
}

app.component.ts

import { Component, OnInit } from '@angular/core';
import { SignalR, IConnectionOptions } from 'ng2-signalr';
@Component({
    selector: 'app',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    config: IConnectionOptions = {
        hubName: 'MyHub', url: "http://localhost:60733/"
    };

    ngOnInit() {
        this._signalR.connect(this.config).then((c) => {
            let onMessageSent = c.listenFor('BroadcastMessage');
            onMessageSent.subscribe(message => {
                console.log(message);
            });
        });
    }
    // inside your component.
    constructor(private _signalR: SignalR) {

    }
}

Possibility to provide headers

Hi,

It would be extremely useful to be able to supply headers for connection, f.e. for authorization purposes.
Is there a chance this would be added?

Can't subscribe to event with no arguments

With an event like this in server side:

Clients.All.hello();

This event will never raise on the client:

const hello = new BroadcastEventListener('hello');
this.connection.listen(hello);
hello.subscribe(() => {
    alert("Hello");
});

ConnectionStatus observable should only publish events related to connection state changes

Currently the connectionstatus observable publishes events unrelated to connection state changes.
This is due to subscribing to too many callback methods on the connection object and publishing them all under the same observable.

private wireUpStatusEventsAsObservable(): Observable<ConnectionStatus> {
        let sStatus = new Subject<ConnectionStatus>();
        let connStatusNames = ['starting', 'received', 'connectionSlow', 'reconnecting', 'reconnected', 'stateChanged', 'disconnected'];
        // aggregate all signalr connection status handlers into 1 observable.
        connStatusNames.forEach((statusName) => {
            // handler wire up, for signalr connection status callback.
            this._jConnection[statusName]((...args: any[]) => {
                this._zone.run(() => {
                    sStatus.next(new ConnectionStatus(statusName));
                });
            });
        });
        return sStatus;
    }

Solution:
subscribing only to the jConnection stateChanged(function(){ }) callback method will give the desired result.

version 1.0.2: TypeError: Cannot read property 'toLowerCase' of undefined

using version 1.0.2, I get an error:

Promise rejection: Cannot read property 'toLowerCase' of undefined ; Zone: angular ; Task: Promise.then ; Value: TypeError: Cannot read property 'toLowerCase' of undefined
at t.fn.init.t.fn.createHubProxy (jquery.signalR.min.js?1486454279358:9)
at eval (signalr.js:27)
at new ZoneAwarePromise (zone.js?1486454279345:467)
at SignalR.connect (signalr.js:21)
at ConnectionResolver.resolve (documentation.route.resolver.ts:12)
at eval (router.umd.js:2883)
at eval (router.umd.js:111)
at forEach (router.umd.js:94)
....

Support listening to messages sent directly to the client

It should be possible to listen for messages sent directly to the client.

I did this on the server side, and confirmed in the Chrome debugger network trace the data was getting sent to one client only. However, I did not find any way of listening for this in the library.

  1. On the server side I am calling: Clients.Client(ConnectionId).sendMessage(someData);
  2. In the Chrome debugger, I can inspect the frames of the websocket, and see the data is passed to the intended client only
  3. In jQuery one would do $.connection.myHub.client.sendMessage = function(someData) {...}
  4. BroadcastEventListener<SomeDataDto>("sendMessage") is not firing for Clients.Client(ConnectionId), but if swapped with Clients.Group(GroupName) it works fine, but then everyone is getting the data

Am I missing something or is this not supported?

An example: http://stackoverflow.com/a/35447025/634065

ERROR Error: Uncaught (in promise): Error: No provider for Function!

cannot get this to run. maybe I'm missing something.

Can you help?

Here is the component:

import { Component } from '@angular/core';
import { SignalR, SignalRConfiguration } from 'ng2-signalr';

@Component({
  template: '<span>{{title}}</span>',
  providers: [SignalR, SignalRConfiguration]
})
export class SignalrTestComponent {
  title = 'signalR works!';
  
  constructor(private _signalR: SignalR){

  }

  ngOnInit(){
      console.log(this._signalR);
  }
}

Here is the error:

ERROR Error: Uncaught (in promise): Error: No provider for Function!
Error
    at injectionError (core.es5.js:1231) [angular]
    at noProviderError (core.es5.js:1269) [angular]
    at ReflectiveInjector_._throwOrNull (core.es5.js:2770) [angular]
    at ReflectiveInjector_._getByKeyDefault (core.es5.js:2809) [angular]
    at ReflectiveInjector_._getByKey (core.es5.js:2741) [angular]
    at ReflectiveInjector_.get (core.es5.js:2610) [angular]
    at AppModuleInjector.NgModuleInjector.get (core.es5.js:3557) [angular]
    at resolveDep (core.es5.js:10930) [angular]
    at createClass (core.es5.js:10794) [angular]
    at _createProviderInstance (core.es5.js:10758) [angular]
    at createProviderInstance (core.es5.js:10600) [angular]
    at createViewNodes (core.es5.js:11967) [angular]
    at createRootView (core.es5.js:11882) [angular]
    at callWithDebugContext (core.es5.js:13013) [angular]
    at injectionError (core.es5.js:1231) [angular]
    at noProviderError (core.es5.js:1269) [angular]
    at ReflectiveInjector_._throwOrNull (core.es5.js:2770) [angular]
    at ReflectiveInjector_._getByKeyDefault (core.es5.js:2809) [angular]
    at ReflectiveInjector_._getByKey (core.es5.js:2741) [angular]
    at ReflectiveInjector_.get (core.es5.js:2610) [angular]
    at AppModuleInjector.NgModuleInjector.get (core.es5.js:3557) [angular]
    at resolveDep (core.es5.js:10930) [angular]
    at createClass (core.es5.js:10794) [angular]
    at _createProviderInstance (core.es5.js:10758) [angular]
    at createProviderInstance (core.es5.js:10600) [angular]
    at createViewNodes (core.es5.js:11967) [angular]
    at createRootView (core.es5.js:11882) [angular]
    at callWithDebugContext (core.es5.js:13013) [angular]
    at resolvePromise (zone.js:712) [angular]
    at resolvePromise (zone.js:683) [angular]
    at :4200/polyfills.bundle.js:3583:17 [angular]
    at Object.onInvokeTask (core.es5.js:4116) [angular]
    at ZoneDelegate.invokeTask (zone.js:397) [angular]
    at Zone.runTask (zone.js:165) [<root> => angular]
    at drainMicroTaskQueue (zone.js:593) [<root>]
    at HTMLButtonElement.ZoneTask.invoke (zone.js:464) [<root>]
defaultErrorLogger @ core.es5.js:1084
ErrorHandler.handleError @ core.es5.js:1144
next @ core.es5.js:4754
schedulerFn @ core.es5.js:3828
SafeSubscriber.__tryOrUnsub @ Subscriber.js:234
SafeSubscriber.next @ Subscriber.js:183
Subscriber._next @ Subscriber.js:125
Subscriber.next @ Subscriber.js:89
Subject.next @ Subject.js:55
EventEmitter.emit @ core.es5.js:3814
NgZone.triggerError @ core.es5.js:4185
onHandleError @ core.es5.js:4146
ZoneDelegate.handleError @ zone.js:369
Zone.runGuarded @ zone.js:141
_loop_1 @ zone.js:604
drainMicroTaskQueue @ zone.js:613
ZoneTask.invoke @ zone.js:464

AoT compilation

Hi,

This library works great, but I can't get it working with AoT compilation.

If it helps, my current work-around is to create my own SignalRModule, which looks like this:
(Please not I have no idea whether this is the correct solution!)

import { NgModule, ModuleWithProviders, NgZone, OpaqueToken } from '@angular/core';
import { SignalR, SignalRConfiguration } from 'ng2-signalr';

const SIGNALR_CONFIGURATION = new OpaqueToken('SIGNALR_CONFIGURATION');

export function signalrFactory(zone: NgZone, configuration: SignalRConfiguration): any {
    return new SignalR(configuration, zone);
}

@NgModule({
    providers: [{
        provide: SignalR,
        useValue: SignalR
    }]
})
export class SignalRModule {

    public static configure(configuration: SignalRConfiguration): ModuleWithProviders {
        return {
            ngModule: SignalRModule,
            providers: [
                { provide: SIGNALR_CONFIGURATION, useValue: configuration },
                {
                    provide: SignalR,
                    useFactory: signalrFactory,
                    deps: [NgZone, SIGNALR_CONFIGURATION]
                },
            ],
        };
    }
}

Error in latest version

I just installed the latest version

Here are the version in my package json
"expose-loader": "^0.7.3",
"jquery": "^3.2.1",
"signalr": "^2.2.1",
"ng2-signalr": "^2.0.3",

I'm trying to configure inside a module:

import { SignalRModule, SignalRConfiguration } from 'ng2-signalr';

const config = new SignalRConfiguration();
config.hubName = 'Ng2SignalRHub';
config.qs = { user: 'donald' };
config.url = 'http://ng2-signalr-backend.azurewebsites.net/';

@NgModule({
  imports: [
     ...
    SignalRModule.configure(config)
  ],

ERROR in ..../src/app/apps/apps.module.ts (63,19): Property 'configure' does not exist on type 'typeof SignalRModule'

this is my d.ts

import { ModuleWithProviders, NgZone } from '@angular/core';
import { SignalR } from '../services/signalr';
import { SignalRConfiguration } from '../services/signalr.configuration';
export declare function createSignalr(configuration: SignalRConfiguration, zone: NgZone): SignalR;
export declare class SignalRModule {
    static forRoot(getSignalRConfiguration: Function): ModuleWithProviders;
    static forChild(): ModuleWithProviders;
}

in signalr-module.js

SignalRModule.forChild = function () {
        throw new Error("forChild method not implemented");
    };

So I cannot use that too.

I tried to import also at the root level but I don't really need it there.
Anything I'm doing wrong?

Usage in a service

I'd like my components to get their data from a service, and be ignorant where that data comes from. My service exposes a BehaviorSubject that these components listen to. This makes it possible to send out updates through multiple mediums; like http and signalr. What's through me off is the second recommended way of working with this library (injection with activated routes), since this will be in a service.

Maybe I'm overthinking this, but what would be your recommend approach?

There's a big error in your package

big error
๐Ÿ’” Classs 'ActivatedRouteMock' incorrectly implements interface 'ActivatedRoute', Because property 'paramMap : Observable' and 'queryParamMap : Observable' are missing in 'ActivatedRouteMock'. ๐Ÿ’”
Please fix this bug, thanks.

Possibility to modify qs after connection is started

Hi,

I've implemented authorization by passing access token through the query string param. But I also need a possibility to replace that token once it gets updated.
For now I'm able to achieve that by doing something veeery horrible:
(<any>this.connection)._jConnection.qs["access_token"] = token;
It would be nice to be able to do it in typescript-ish way :)

@angular/core has no exported member 'Version' and 'NgProbeToken'

Hi Team,

I'm using ng2-signalr in my project, able to get the below errors when I import the import { SignalRModule, SignalRConfiguration } from 'ng2-signalr'; in app.module.ts file.

Error:
node_modules/@angular/core/index"' has no exported member 'Version'.
node_modules/@angular/core/index"' has no exported member 'NgProbeToken'.

Please let me know how to resolve those typing issues in my project.

FYI.. I'm using below dependencies and dev dependencies using in my package.json

"dependencies": {
"@angular/common": "2.2.1",
"@angular/compiler": "2.2.1",
"@angular/compiler-cli": "2.2.1",
"@angular/core": "2.2.1",
"@angular/forms": "2.2.1",
"@angular/http": "2.2.1",
"@angular/platform-browser": "2.2.1",
"@angular/platform-browser-dynamic": "2.2.1",
"@angular/platform-server": "2.2.1",
"@angular/router": "^3.4.8",
"@ionic/storage": "1.1.6",
"@ngrx/store": "^2.0.1",
"ionic-angular": "2.0.0-rc.4",
"ionic-native": "2.2.11",
"ionicons": "3.0.0",
"moment": "^2.17.0",
"ng2-signalr": "^1.0.6",
"rxjs": "5.0.0-beta.12",
"zone.js": "0.6.26"
},
"devDependencies": {
"@ionic/app-scripts": "^1.0.1",
"@types/jasmine": "^2.5.38",
"@types/node": "^6.0.49",
"angular-cli": "^1.0.0-beta.22-1",
"awesome-typescript-loader": "^3.0.0-beta.9",
"codelyzer": "^2.0.0-beta.1",
"gulp": "^3.9.1",
"gulp-concat": "^2.6.1",
"istanbul-instrumenter-loader": "^0.2.0",
"jasmine-core": "^2.5.2",
"jasmine-spec-reporter": "^2.7.0",
"json-loader": "^0.5.4",
"karma": "^1.3.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-coverage": "^1.1.1",
"karma-jasmine": "^1.0.2",
"karma-mocha-reporter": "^2.2.1",
"karma-phantomjs-launcher": "^1.0.2",
"karma-remap-coverage": "^0.1.3",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.8.0",
"phantomjs-prebuilt": "^2.1.13",
"raw-loader": "^0.5.1",
"source-map-loader": "^0.1.5",
"ts-helpers": "^1.1.2",
"ts-node": "^1.7.0",
"tslint": "^4.0.2",
"tslint-loader": "^3.3.0",
"typescript": "^2.0.9",
"webpack": "~2.1.0-beta.25",
"xml2js": "^0.4.17"
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.