Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add SockJS into Angular 2 project?

I use angular-cli to generate a new project. Now I want to add socketJs to the project, but keep getting errors in browser console:

GET http://localhost:4200/url-parse 404 (Not Found)
GET http://localhost:4200/inherits 404 (Not Found)
Unhandled Promise rejection: Error: XHR error (404 Not Found) loading http://localhost:4200/url-parse
        at XMLHttpRequest.wrapFn [as _onreadystatechange] (http://localhost:4200/vendor/zone.js/dist/zone.js:769:30)
        at ZoneDelegate.invokeTask (http://localhost:4200/vendor/zone.js/dist/zone.js:356:38)
        at Zone.runTask (http://localhost:4200/vendor/zone.js/dist/zone.js:256:48)
        at XMLHttpRequest.ZoneTask.invoke (http://localhost:4200/vendor/zone.js/dist/zone.js:423:34)
    Error loading http://localhost:4200/url-parse as "url-parse" from http://localhost:4200/vendor/sockjs-client/lib/main.js ; Zone: <root> ; Task: Promise.then ; Value: Error: Error: XHR error (404 Not Found) loading http://localhost:4200/url-parse(…)
Error: Uncaught (in promise): Error: Error: XHR error (404 Not Found) loading http://localhost:4200/url-parse(…)
GET http://localhost:4200/json3 404 (Not Found)
GET http://localhost:4200/debug 404 (Not Found)
GET http://localhost:4200/events 404 (Not Found)
GET http://localhost:4200/eventsource 404 (Not Found)
GET http://localhost:4200/crypto 404 (Not Found)
GET http://localhost:4200/json3 404 (Not Found)
GET http://localhost:4200/url-parse 404 (Not Found)
GET http://localhost:4200/debug 404 (Not Found)
GET http://localhost:4200/inherits 404 (Not Found)
Assertion failed: loading or loaded
GET http://localhost:4200/events 404 (Not Found)
Assertion failed: loading or loaded
GET http://localhost:4200/faye-websocket 404 (Not Found)
Assertion failed: loading or loaded
GET http://localhost:4200/eventsource 404 (Not Found)
Assertion failed: loading or loaded
GET http://localhost:4200/http 404 (Not Found)
GET http://localhost:4200/https 404 (Not Found)

This is my steps and configuration:

typings install sockjs-client --save --ambient

angular-cli-build.js

var Angular2App = require('angular-cli/lib/broccoli/angular2-app');

module.exports = function(defaults) {
  return new Angular2App(defaults, {
    vendorNpmFiles: [
      'systemjs/dist/system-polyfills.js',
      'systemjs/dist/system.src.js',
      'zone.js/dist/**/*.+(js|js.map)',
      'es6-shim/es6-shim.js',
      'reflect-metadata/**/*.+(ts|js|js.map)',
      'rxjs/**/*.+(js|js.map)',
      '@angular/**/*.+(js|js.map)',
      'sockjs-client/**/*.+(js)'
    ]
  });
};

system-config.ts

/** Map relative paths to URLs. */
const map: any = {
  'sockjs-client': 'vendor/sockjs-client/lib/entry.js'
};

/** User packages configuration. */
const packages: any = {
  'vendor/sockjs-client/lib': {
    'format': 'cjs',
    'defaultExtension': 'js'
  }
};

My custom service class:

import { Injectable } from '@angular/core';

import * as SockJS from 'sockjs-client';
import BaseEvent = __SockJSClient.BaseEvent;
import SockJSClass = __SockJSClient.SockJSClass;

@Injectable()
export class WebsocketService {

  private sockJs: SockJSClass;

  constructor() {
    console.log('constuctor');
    this.sockJs = new SockJS('/hello');
  }
}

Please let me know how to fix it, thanks a lot!

I can, however, eliminate some error by including the missing lib by adding them one by one in system-config.ts. But I doubt this is the right approach.

const map: any = {
  'sockjs-client': 'vendor/sockjs-client/lib/entry.js',
  'json3': 'vendor/sockjs-client/node_modules/json3/lib/json3.js',
  'url-parse': 'vendor/sockjs-client/node_modules/url-parse/index.js',
  'inherits': 'vendor/sockjs-client/node_modules/inherits/inherits.js',
  'debug': 'vendor/sockjs-client/node_modules/debug/debug.js',
  ...
};
like image 654
janetsmith Avatar asked Jul 09 '16 05:07

janetsmith


People also ask

What is SockJS in angular?

SockJS is a layer on top of WebSockets that allows you to fall back on polling if a web browser doesn't support WebSockets. It also comes with a client library that we're about to use. This is similar to what Socket.io does, but Spring is compliant with SockJS, so we'll use that one. STOMP.

What is SockJS node?

SockJS is a JavaScript library (for browsers) that provides a WebSocket-like object. SockJS gives you a coherent, cross-browser, Javascript API which creates a low latency, full duplex, cross-domain communication channel between the browser and the web server, with WebSockets or without.


3 Answers

In new version of angular2 CLI https://cli.angular.io/ it is simple to add library.

If you want to add only sockjs_client

1) npm i --save sockjs-client

2) In typings.d.ts add this declaration declare module 'sockjs-client';

But I would recommend to use STOMP-Over-WebSocket Service for angular 2

Install this npm packages

npm i --save stompjs
npm i --save sockjs-client
npm i --save ng2-stomp-service

In typings.d.ts

Add stompjs and sockjs-client module declaration

declare module 'stompjs';
declare module 'sockjs-client';

In app.module.ts

import { StompService } from 'ng2-stomp-service';

@NgModule({
  ...
  providers: [StompService]
})

In app.components.ts

import { StompService } from 'ng2-stomp-service';

private wsConf = {
  host:'test.com'
}

constructor(stomp: StompService) {

  stomp.configure(this.wsConf);

  stomp.startConnect().then(() => {
    console.log('connected');
  });


}

source https://github.com/devsullo/ng2-STOMP-Over-WebSocket

like image 116
Devsullo Avatar answered Nov 07 '22 06:11

Devsullo


I found a solution to this problem.

The issue is that: npm install sockjs-client downloads sockjs-node instead of client. I hope they will fix it soon.

In your project you're pointing to vendor/sockjs-client/lib/entry.js instead you should download this file http://cdn.jsdelivr.net/sockjs/1/sockjs.min.js put it in your project and point to it in system-config.ts.

like image 29
Daniel Stradowski Avatar answered Nov 07 '22 04:11

Daniel Stradowski


In Angular2, the easiest way to import sockjs is to use:

import 'your_path/sockjs-1.1.1.js'

but before you import, please modify part of the code in first line of 'sockjs-1.1.1.js'.

if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.SockJS=e()}

replace the code above to:

window.SockJS = e()

after then SockJS could be access from anywhere because now it's a property of window in browser.Also you need to tell typescript SockJS is an ambient variable by adding:

declare let SockJS: any
like image 26
elixiao Avatar answered Nov 07 '22 06:11

elixiao