aspnet / SignalR

[Archived] Incredibly simple real-time web for ASP.NET Core. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
2.38k stars 446 forks source link

MessagePackHubProtocol error in Angular #2736

Closed andreatosato closed 6 years ago

andreatosato commented 6 years ago

Angular error:

Uncaught ReferenceError: global is not defined
    at Object../node_modules/buffer/index.js (index.js:43)
    at __webpack_require__ (bootstrap:76)
    at Object../node_modules/@aspnet/signalr-protocol-msgpack/dist/esm/MessagePackHubProtocol.js (vendor.js:61966)
    at __webpack_require__ (bootstrap:76)
    at Object../node_modules/@aspnet/signalr-protocol-msgpack/dist/esm/index.js (vendor.js:62173)
    at __webpack_require__ (bootstrap:76)
    at Object../src/app/services/chatHub.service.ts (chat.service.ts:10)
    at __webpack_require__ (bootstrap:76)
    at Object../src/app/home/home.component.ts (main.js:595)
    at __webpack_require__ (bootstrap:76)

Client Side

private connection: HubConnection;
...
this.connection = new HubConnectionBuilder()
      .withUrl(environment.baseHubs + '/chat', {
            accessTokenFactory: () => token,
            logger: LogLevel.Trace
      })
      .withHubProtocol(new MessagePackHubProtocol())
      .build();

Server Side

 services.AddSignalR(config => config.EnableDetailedErrors = true)
              .AddMessagePackProtocol()
              .AddAzureSignalR();
...
 app.UseAzureSignalR(map =>
        {
                map.MapHub<ChatHub>("/chat");
        });

When I change protocol to Json all work fine: Client Side

this.connection = new HubConnectionBuilder()
      .withUrl(environment.baseHubs + '/chat', {
            accessTokenFactory: () => token,
            logger: LogLevel.Trace
      })
      .withHubProtocol(new JsonHubProtocol())
      .build();

Server Side

 services.AddSignalR(config => config.EnableDetailedErrors = true)
              .AddJsonProtocol(config => config.PayloadSerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver())
              .AddAzureSignalR();
...
 app.UseAzureSignalR(map =>
        {
                map.MapHub<ChatHub>("/chat");
        });
analogrelay commented 6 years ago

Can you provide your webpack configuration? When using SignalR as a node module (via something like WebPack) it expects to be in a Node environment (where things like global are defined). WebPack is supposed to automatically shim those things though.

andreatosato commented 6 years ago

this is my project: https://github.com/andreatosato/RealTime/tree/master/ChatPWA/chat-app Project is for conference sessions. I tried to add in polyfills.ts:

(window as any).global = window;

The introduction of the line of code indicates a new error with messagepack.

This is my experiments: 1 experiment

(window as any).global = window;

2 experiment

(window as any).process = {
    env: { DEBUG: undefined },
};

Ref project

BrennanConroy commented 6 years ago

Could you give step-by-step instructions on how to run the app and hit the issue?

andreatosato commented 6 years ago

With last commit, I migrate from Json to MessagePack protocol. I insert polyfills rules with (window as any).global = window;

Step to reproduce error:

  1. Run client Angular App with angular-cli running powershell command: ng serve
  2. Run server ASP .NET Core app
BrennanConroy commented 6 years ago

Yeah, I figured out those steps, but how do you actually hit the issue? It ran fine, but there is no SignalR code running in the browser.

andreatosato commented 6 years ago

excuse me for the misunderstanding. I encounter the problem at runtime when running the following line of code:

this.connection = new HubConnectionBuilder()
      .withUrl(environment.baseHubs + '/chat', {
            accessTokenFactory: () => token,
            logger: LogLevel.Trace
      })
      .withHubProtocol(new MessagePackHubProtocol())
      .build();

The strange thing is that code breaks before running start() method. It looks like a Typescript/Javascript problem in the package: @aspnet/signalr-protocol-msgpack

BrennanConroy commented 6 years ago

Got it running by adding more polyfill bits. Just had to follow stackoverflow for a couple more things

(window as any).global = window;

(window as any).process = {
    env: { DEBUG: undefined },
    version: "1",
};
global.Buffer = global.Buffer || require('buffer').Buffer;

https://stackoverflow.com/questions/50371593/angular-6-uncaught-referenceerror-buffer-is-not-defined

andreatosato commented 6 years ago

Wow, great! Thanks a lot! @BrennanConroy

Complete resolution: index.html

<head>
 <script>
    var global = global || window;
    var Buffer = Buffer || [];
    var process = process || {
      env: { DEBUG: undefined },
      version: []
    };
  </script>
</head>

polyfills.ts

(window as any).global = window;
(window as any).process = {
    env: { DEBUG: undefined },
    version: '1',
};