如何在Angular 2应用程序中使用Phoenix Channels/Sockets?

Ole*_*ann 3 javascript brunch typescript phoenix-framework angular

我有一个用Elixir/Phoenix构建的后端和一个用Angular 2构建的前端(Typescript,Brunch,io用于构建,ES6).我现在想要使用Phoenix Channels.而且我有点绝望在我的前端尝试使用Phoenix Javascript Client.

当我安装https://www.npmjs.com/package/phoenix-js通过npm install phoenix-js,然后尝试将其注入到这样的角度服务:

import { Socket } from "phoenix-js";
Run Code Online (Sandbox Code Playgroud)

我总是Cannot find module phoenix-js在编译期间得到错误.

我有点卡住,每一个如何让这个工作的提示将不胜感激.

谢谢

Ole*_*ann 8

编辑:我将在下面留下旧答案 - 即使它有点尴尬.让一切工作并使用最新版本的带有Angular 2的Phoenix JS客户端比我想象的更容易,我只是非常困惑.

Phoenix JS客户端已经被提取为npm包,可以在这里找到.安装它npm install --save phoenix.然后将其作为附加依赖项加载.在我使用SystemJS的设置中,只需添加必要的配置:

import { join } from 'path';
import { SeedConfig } from './seed.config';
import { InjectableDependency } from './seed.config.interfaces';

export class ProjectConfig extends SeedConfig {
  PROJECT_TASKS_DIR = join(process.cwd(), this.TOOLS_DIR, 'tasks', 'project');

  constructor() {
    super();
    // this.APP_TITLE = 'Put name of your app here';
    let additional_deps: InjectableDependency[] = [
      // {src: 'jquery/dist/jquery.min.js', inject: 'libs'},
      // {src: 'lodash/lodash.min.js', inject: 'libs'},
      {src: 'phoenix/priv/static/phoenix.js', inject: 'libs'}
    ];

    const seedDependencies = this.NPM_DEPENDENCIES;

    this.NPM_DEPENDENCIES = seedDependencies.concat(additional_deps);
  }
}
Run Code Online (Sandbox Code Playgroud)

现在我们将它放在全局范围内,只需要declare var在我们想要使用的Angular 2服务打字稿文件中使用它.这是我犯了一个关键错误的地方.我试图Socket直接访问,因此使用declare var Socket: any.这总是导致错误Socket is undefined.但是这个问题让我朝着正确的方向前进:如果你使用转换后的ES5版本(而不是ES6)你必须使用Phoenix.Socket(因为我猜的是命名空间).

这就是我的服务现在的样子:

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

declare var Phoenix: any;

@Injectable()
export class PhoenixChannelService {

  socket: any;

  constructor() {
    this.socket = new Phoenix.Socket("ws://localhost:4000/socket", {
      logger: ((kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }),
      transport: WebSocket
    });
    this.socket.connect();
  }
}
Run Code Online (Sandbox Code Playgroud)

现在一切都像魅力一样.

如果您不想通过npm安装客户端,有一种更基本的方法:从GitHub 获取最新版本的JS Client /priv/static,将其存储在保存静态资产的文件夹中,并将其直接包含在您的index.html:

<script src="/path/to/static/js/phoenix.js"></script>
Run Code Online (Sandbox Code Playgroud)

其余的保持不变.

注意:如果你想将它与typescript类型定义一起使用,这个 npm包可能是一个很好的起点 - 即使它有点旧.


老而尴尬的答案:所以我想我弄明白了.编写我自己的定义文件不是一种选择.由于所有关于如何使用凤凰客户端的文档代码都在ES6中,我在我的index.html中直接包含已编译的ES5版本.但第一条线索是这篇文章.

然后我在GitHub上发现了这个问题,即提取Phoenix Client.通过这个我然后发现这个npm包,这有点过时,但似乎工作.我安装它,npm insall --save phoenix-js然后在我的项目中加载依赖项.由于我的Angular App基于这个种子,它会进入我的项目定义(并确保加载凤凰客户端的Globals版本:

import { join } from 'path';
import { SeedConfig } from './seed.config';
import { InjectableDependency } from './seed.config.interfaces';

export class ProjectConfig extends SeedConfig {
  PROJECT_TASKS_DIR = join(process.cwd(), this.TOOLS_DIR, 'tasks', 'project');

  constructor() {
    super();
    // this.APP_TITLE = 'Put name of your app here';
    let additional_deps: InjectableDependency[] = [
      // {src: 'jquery/dist/jquery.min.js', inject: 'libs'},
      // {src: 'lodash/lodash.min.js', inject: 'libs'},
      {src: 'phoenix-js/dist/glob/main.js', inject: 'libs'}
    ];

    const seedDependencies = this.NPM_DEPENDENCIES;

    this.NPM_DEPENDENCIES = seedDependencies.concat(additional_deps);
  }
}
Run Code Online (Sandbox Code Playgroud)

现在我可以在我的角度2服务中使用它:

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

declare var Socket: any;
declare var Channel: any;

@Injectable()
export class PhoenixChannelService {

  socket: any;
  channel: any;

  constructor() {

    this.socket = new Socket("/socket", {
      logger: ((kind, msg, data) => { console.log(`${kind}: ${msg}`, data) })
    });
    this.socket.connect({user_id: "123"});

  }

}
Run Code Online (Sandbox Code Playgroud)

根据您的构建过程(我使用gulp)和其他因素,您可能需要调整.但我希望这能为其他坚持这个问题的人提供一些帮助.

编辑:是Phoenix正式提取的JS客户端.但是我没有让它在我的设置中工作,可能是因为Typescript.