Open srjovanovic opened 6 years ago
Please see: https://stomp-js.github.io/ng2-stompjs/additional-documentation/sock-js.html
A sample at: https://github.com/stomp-js/ng4-stompjs-demo/tree/sockjs (branch sockjs)
Thank you very much.
Has this been confirmed to work with Angular 6? When following the documentation example I get a runtime error whilst connecting to the SockJS endpoint:
browser-crypto.js:3 Uncaught ReferenceError: global is not defined
at Object../node_modules/sockjs-client/lib/utils/browser-crypto.js (browser-crypto.js:3)
at __webpack_require__ (bootstrap:81)
at Object../node_modules/sockjs-client/lib/utils/random.js (random.js:4)
at __webpack_require__ (bootstrap:81)
at Object../node_modules/sockjs-client/lib/utils/event.js (event.js:3)
at __webpack_require__ (bootstrap:81)
at Object../node_modules/sockjs-client/lib/transport/websocket.js (websocket.js:3)
at __webpack_require__ (bootstrap:81)
at Object../node_modules/sockjs-client/lib/transport-list.js (transport-list.js:5)
at __webpack_require__ (bootstrap:81)
The Angular 6 version of this library has only been released yesterday, so, I am doubtful if anyone has used in production at all.
I can be reasonably sure that no one would have used it with SockJS and Angular 6 by now ð
Before I dig deeper, are you using 6.0.0 of this library (released yesterday)?
Yes, I am! I am trying to use it for a prototype application where I have no control over how the backend works, but it seems it's not functioning with Angular 6 sadly.
If it's too much work I'll just downgrade to Angular 5, but it'd be nice to use all the new features from 6 while building something new.
I can confirm that I am able to reproduce the issue. It seems to be reported here: https://github.com/sockjs/sockjs-client/issues/401
Not sure it would be an easy solution till the underlying thing gets fixed.
@wsloth if your underlying broker supports Websockets (which in all likelihood it should), you can use that instead of going through the SockJS emulation layer. Any particular reason you need SockJS?
I see, it doesn't seem like an easy fix. I'm working on something of a code exercise where I have full control over the frontend, but none over the backend, so that is a bit of a shame.
I'll see if I can downgrade to Angular 5, or for the sake of making something beautiful ditch the SockJS protocol.
Just curious what advantage are you getting with SockJS in comparison to standard WebSocket?
Nothing really, it's just that the backend has already been made and SockJS was decided for the messaging protocol. If it were up to me, I'd be using standard WebSockets ð
I am always getting surprised people choosing SockJS instead of WebSockets which would internally use WebSockets anyway. Using SockJS does limit some of the functionality of this library as well.
So far most number of tickets on this project relate to SockJS issues ð
I can confirm that ng2-stompjs over SockJS is working with Angular 6. But I'm having problems with subscribe, after reconnecting subscription doubles.
Not sure if that would work - in your index.html file, in the header try adding the following:
<script type="application/javascript">
var global = window;
</script>
I am unable to test it myself though
@srjovanovic your issue may be linked to something else. Will you be able to share a sample repository that shows StompJS working with Angular6 and also your issue.
@kum-deepak I've made more test with Angular 5, and I can confirm that my issue has nothing with Angular 6. So ng2-stompjs and SockJS are working for me on Angular 6.
After upgrade angular and ng2-stompjs I have the same error:
Uncaught ReferenceError: global is not defined at Object../node_modules/sockjs-client/lib/utils/browser-crypto.js (browser-crypto.js:3) at webpack_require__ (bootstrap:81) at Object../node_modules/sockjs-client/lib/utils/random.js (random.js:4) at webpack_require (bootstrap:81) at Object../node_modules/sockjs-client/lib/utils/event.js (event.js:3) at __webpack_require (bootstrap:81) at Object../node_modules/sockjs-client/lib/transport/websocket.js (websocket.js:3) at webpack_require__ (bootstrap:81) at Object../node_modules/sockjs-client/lib/transport-list.js (transport-list.js:5) at webpack_require__ (bootstrap:81)
And following your link https://stomp-js.github.io/ng2-stompjs/additional-documentation/sock-js.html I see a old library sockjs-client...
@srjovanovic Can you show me an example of stompjs working with angular 6? or maybe your code?
@lippomano
Service: ` import {Injectable} from "@angular/core"; import {ENV} from "@app/environments"; import {StompConfig, StompRService, StompState} from "@stomp/ng2-stompjs"; import {Message} from "@stomp/stompjs"; import {Platform} from "ionic-angular"; import {Observable, Subscription} from "rxjs/Rx"; import * as SockJS from "sockjs-client"; import {Auth0Service} from "../auth-service/auth0-service"; import {NotificationsProvider} from "../notifications-service/notifications-service";
@Injectable()
export class SocketStompProvider {
public stompConfig: StompConfig;
public stompEndpoint: string = "endpointName";
public stompStatus: string;
public stompStatusId: number;
public messages: Observable
constructor(private stompService: StompRService,
private notificationsService: NotificationsProvider,
private oAuthService: OAuthService,
private platform: Platform) {
this.debugService = (ENV.LOG_LEVEL !== "0");
if (this.debugService) {
this.stateStompService();
}
this.stompStatus = "STARTING";
this.reconnectTimeout = 15000;
this.reconnectEnabled = false;
this.showStompStatusId = this.debugService;
}
public reinitializeServiceSocketConnection() {
this.initServiceSocketConnection(this.stompEndpoint);
}
public socketProvider(serverUrl) {
return new SockJS(serverUrl);
}
public unsubscribeStompTopic() {
if (this.subscription) {
this.subscription.unsubscribe();
this.subscription = null;
this.messages = null;
}
}
public disconnectSocketFromService() {
if (this.stompStatus === "CONNECTED") {
this.reconnectEnabled = false;
this.unsubscribeStompTopic();
this.stompService.disconnect();
}
}
public setStompServiceConfiguration() {
this.stompConfig = {
debug: this.debugService,
headers: {},
heartbeat_in: 30000,
heartbeat_out: 30000,
reconnect_delay: this.reconnectTimeout,
url: this.serverSocket,
};
}
public getEndpointAuthorizationHeader(): string {
let authorizeEndpoint = null;
this.loadAuthTokensFromStorage();
if (this.accountToken) {
authorizeEndpoint = "?" +
"Authorization=" + this.bearerToken +
"&Account-Info=" + this.accountToken;
}
return authorizeEndpoint;
}
public stateStompService() {
this.stompService.state
.map((state: number) => StompState[state])
.subscribe((status: string) => {
this.stompStatus = status;
if (this.reconnectEnabled && this.stompStatus === "CLOSED" &&
this.notificationsService.notificationsEnabled) {
this.oAuthService.getNewAccessTokenNotification();
this.reinitializeServiceSocketConnection();
}
if (this.showStompStatusId) {
switch (status) {
case "CLOSED": {
this.stompStatusId = 0;
break;
}
case "TRYING": {
this.stompStatusId = 1;
break;
}
case "CONNECTED": {
this.stompStatusId = 2;
break;
}
case "DISCONNECTING": {
this.stompStatusId = 3;
break;
}
}
}
});
}
public onSendMessage(messageText) {
this.stompService.publish(this.topic, messageText);
}
private initServiceSocketConnection(stompEndpoint: string) {
if (this.notificationsService.notificationsEnabled) {
const authorizationHeader = this.getEndpointAuthorizationHeader();
if (authorizationHeader) {
this.serverSocket = this.socketProvider(ENV.URL + stompEndpoint + authorizationHeader);
this.setStompServiceConfiguration();
if (!this.subscription) {
this.subscribeStompTopic();
}
if (this.stompStatus !== "CONNECTED" && this.stompStatus !== "TRYING") {
this.connectSocketToService();
}
this.notificationsService.getNotificationsHistory();
}
}
}
private subscribeStompTopic() {
if (!this.subscription) {
this.messages = this.stompService.subscribe(this.topic);
this.subscription = this.messages.subscribe(this.onNewMessage);
}
}
private onNewMessage = (message: Message) => {
this.notificationsService.processMessage(JSON.parse(message.body));
};
private loadAuthTokensFromStorage() {
this.loggedProfileDetails = JSON.parse(localStorage.getItem("profile-cm"));
if (this.loggedProfileDetails) {
this.accountToken = this.loggedProfileDetails.accountInfoToken;
}
this.bearerToken = "Bearer " + localStorage.getItem("access_token");
}
private connectSocketToService() {
this.stompService.config = this.stompConfig;
this.stompService.initAndConnect();
this.reconnectEnabled = true;
}
}`
Relevant package versions: angular/common: 6.0.2 angular/compiler: 6.0.2 angular/compiler-cli: 6.0.2 angular/core: 6.0.2 angular/forms: 6.0.2 angular/http: 6.0.2 angular/platform-browser: 6.0.2 angular/platform-browser-dynamic: 6.0.2 stomp/ng2-stompjs: 4.0.0 rxjs: 6.1.0 rxjs-compat: 6.1.0 sockjs-client: 1.1.4 tsickle: 0.28.0 typescript: 2.7.2 webpack: 4.8.3 zone.js: 0.8.26
@srjovanovic I have a configuration like you but if I use new SockJS(sockUrl);
in config for the stomp url I have the errors posted in the previous comment.
Any idea why I have these errors?
P.s. If I use for example an url like ws://127.0.0.1:15674/ws
without initializing a new SockJS it seems working but I need to initialize sockJS with an url like http:...
As you can see from my code, I'm using newSockJS(serverUrl), for dev env I use serverUrl=https://localhost:9000/
@srjovanovic @kum-deepak just tried with the example in angular 6 ng6-example and I follow this way with sockJS And I still have the same error, I can't understand how you don't have error
It is definitely not working for me ð. Copying from my earlier comments:
The underlying issue is in SockJS and the way Angular 6 is trying to bundle the code. It is reported here: sockjs/sockjs-client#401. Not sure it would be an easy solution till the underlying thing gets fixed.
Not sure if it would work. In your index.html file, in the header try adding the following:
<script type="application/javascript">
var global = window;
</script>
Be warned ð, test your application, this may have unintended side effects.
A better solution, if you can, switch to standard Websockets.
@kum-deepak thanks for your feedback, what type of side effects?
Generally global
is used by NodeJS, it is not used by browsers. SockJS code is expecting global
to have certain methods, in case of browsers those methods are attached to window
. So, the above snippet is likely to provide a workaround.
Now the risk part, global
might be used by some other libraries conditionally. Whatever I can imagine, it should not have negative impacts. Only way to be sure would be to test your application with this added (I mean the entire application).
It's working, but I have to test it more accurately.
Getting the below error in browser after updating to angular 6 browser-crypto.js:3 Uncaught ReferenceError: global is not defined at Object../node_modules/sockjs-client/lib/utils/browser-crypto.js (browser-crypto.js:3) at webpack_require__ (bootstrap:76) at Object../node_modules/sockjs-client/lib/utils/random.js (random.js:4) at webpack_require (bootstrap:76) at Object../node_modules/sockjs-client/lib/utils/event.js (event.js:3) at __webpack_require (bootstrap:76) at Object../node_modules/sockjs-client/lib/transport/websocket.js (websocket.js:3) at webpack_require__ (bootstrap:76) at Object../node_modules/sockjs-client/lib/transport-list.js (transport-list.js:5) at webpack_require__ (bootstrap:76)
@kum-deepak thanks for your feedback, It does the workaround for me. Is there anything with the compatible dependency for angular 6 to fix it ?
@satyendra-123 unfortunately the issue can only be fixed either by Angular team or by SockJS team.
I fixed it for with adding this line:
(window as any).global = window;
to angular-clis polyfill.ts
file. right now couldn't see any sideeffects
@kum-deepak Your workaround-fix works for me for raw SockJS connection:
I will next try using the stomp protocol over it, and will update you soon.
FYI: [vagrant@london-node-230 ~]$ ng --version
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ â³ \ | ' \ / | | | | |/ _
| '| | | | | | |
/ _ | | | | (| | || | | (| | | | || |_ | |
// __| ||_, |_,||_,|| __|__||
|/
Angular CLI: 6.0.7 Node: 8.11.2 OS: linux x64 Angular: ...
@angular-devkit/architect 0.6.7 @angular-devkit/core 0.6.7 @angular-devkit/schematics 0.6.7 @schematics/angular 0.6.7 @schematics/update 0.6.7 rxjs 6.2.0 typescript 2.7.2
[vagrant@london-node-230 ~]$
@kum-deepak Your workaround-fix works.
I am getting undefined here. Why is that?
Typically the CONNECTED frame (in response to CONNECT frame from the client) from broker returns a server
header. If a broker does not return this header it will show undefined as above.
Which broker are you using?
This is not an error, this value is not used other than reporting it in log. It should not impact your usage.
@kum-deepak Hi Deepak,
Is there any way now to convert the protocol to http instead of wss. I am getting "global is not defined"
If the URL supported by your broker starts with ws:
or wss:
, it supports WebSockets
. In that case you do not need SockJS.
You can not interchange wss:
and http:
- both are different protocols.
If the broker only supports http, then follow https://github.com/stomp-js/ng2-stompjs/issues/70#issuecomment-388056250 as a workaround for "global is not defined"
Getting the below error in browser in angular 9 browser-crypto.js:3 Uncaught ReferenceError: global is not defined at Object../node_modules/sockjs-client/lib/utils/browser-crypto.js (browser-crypto.js:3) at webpack_require (bootstrap:76) at Object../node_modules/sockjs-client/lib/utils/random.js (random.js:4) at webpack_require (bootstrap:76) at Object../node_modules/sockjs-client/lib/utils/event.js (event.js:3) at webpack_require (bootstrap:76) at Object../node_modules/sockjs-client/lib/transport/websocket.js (websocket.js:3) at webpack_require (bootstrap:76) at Object../node_modules/sockjs-client/lib/transport-list.js (transport-list.js:5) at webpack_require (bootstrap:76)
@kum-deepak seems like still the error is not fixed by angular or sockJS team , is there any better solution without using this (window as any).global = window;
@goldy12103, this is not fixable by the Angular team. It would need fixing by the SockJS team.
@kum-deepak
Is there any better solution without using this (window as any).global = window; ???
Please scan this thread. There are other solutions, however, all of those lead to the same thing.
Thanks Anyway !!
Based on your setup, you might get error similar to following:
The actual issue can be solved by SockJs team, see: https://github.com/stomp-js/ng2-stompjs/issues/70#issuecomment-388056250.
Please see https://github.com/stomp-js/ng2-stompjs/issues/70#issuecomment-388061761 and https://github.com/stomp-js/ng2-stompjs/issues/70#issuecomment-397231994 for possible workarounds.