LoginSignup
11
5

More than 3 years have passed since last update.

AngularからMattermostにWebSocketで接続して投稿内容を取得する

Last updated at Posted at 2019-08-15

タイトルのことがやりたかっただけなんですけど。
Mattermostに投稿があった時に、Angularでもその内容をリアルタイムで表示したくてですね。APIに定期的にアクセスしてもいいんですけど、せっかくなのでWebSocketで接続したい。
というわけで、"Angular WebSocket"あたりで検索してみたところ、Socket.IOを使うだのObserverやら使うだの、かなり難度の高い方法ばかりでてくるんですが……
最終的に、下記のコードだけで実現できました。

app.component.ts
import { Component, OnInit } from '@angular/core';
import { webSocket } from "rxjs/webSocket";
const subject = webSocket('wss://mattermost-server/api/v4/websocket');

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  constructor() { }

  ngOnInit() {
    subject.subscribe(
      (message: any) => {
        if(message.event == 'posted') console.log(JSON.parse(message.data.post).message);
      },
      err => console.log(err),
      () => console.log('complete')
    );
  }
}

んもー、すごく簡単じゃないですか。いやー、RxJS便利。
ここにたどり着くまでにあれこれ遠回りしましたよ。

ちなみに、素のJavaScriptだとこんな感じ。

const socket = new WebSocket("wss://mattermost-server/api/v4/websocket");
socket.addEventListener("message", event => {
  let message = JSON.parse(event.data);
  if(message.event == 'posted') console.log(JSON.parse(message.data.post).message);
});

そう、こんな風にシンプルに書きたかったんですよ。んもー。


追記。サービス化するとこんな感じ。

websocket.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { webSocket } from "rxjs/webSocket";
const subject = webSocket('wss://mattermost-server/api/v4/websocket');

@Injectable({
  providedIn: 'root'
})
export class WebsocketService {

  data = new Subject<any>();
  data$= this.data.asObservable();

  constructor() {
    subject.subscribe(
      (message: any) => {
        this.data.next(message);
      },
      err => console.log(err),
      () => console.log('complete')
    );
  }
}
app.component.ts
import { Component, OnInit } from '@angular/core';
import { WebsocketService } from './websocket.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  constructor(
    private websocket: WebsocketService,
  ) {}

  ngOnInit() {
    this.websocket.data$.subscribe(
      (message: any) => {
        if(message.event == 'posted') console.log(JSON.parse(message.data.post).message);
      }
    );
  }
}

サービス側で、イベント種別毎だとかチャンネル毎だとかで分けてnextに流すと便利なんだろうな……
気が向いたら実装してみよう。

11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5