2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Mojolicious::1対1のビデオ通話

Posted at

はじめに

WebRTCを利用した1対1のビデオ通話サンプル」をMojolicious::Liteに移植しました。

環境

TLSサポートにはIO::Socket::SSLが要求されます。
IO::Socket::SSLはNet::SSLeayに依存しています。
Net::SSLeayのインストールには

  • DebianとUbuntuでは、libssl-devとzlib1g-dev
  • Red Hat Enterprise LinuxとFedoraでは、openssl-develとzlib-devel

が必要になります。

インストール

webrtc_server.pl
public
  + index.html
  + webrtc.js

Ubuntu

sudo apt install libssl-dev
sudo apt install zlib1g-dev

CentOS(CentOS6.4上でMojolicious+WebSocket+SSL環境構築

sudo yum install openssl-devel
sudo yum install zlib-devel

IO::Socket::SSLとMojoliciousをインストールします。

cpanm IO::Socket::SSL
cpanm Mojolicious

開発サーバーを起動します。

morbo -l https://*:8443 webrtc_server.pl

サーバー

webrtc_server.jsの移植はリアルタイムチャット (Mojolicious::Lite)を参考にしました。
サーバーから3分ごと、クライアントから30秒ごと接続確認をしていましたが、3時間に延命してますのでお兄さん許して。

webrtc_server.pl
use strict;
use warnings;

use Mojo::JSON 'encode_json';
use Mojolicious::Lite;

# 接続リスト
my @connections = ();

# WebSocket処理
websocket '/' => sub {
  my $self = shift;

  $self->inactivity_timeout(10800);

  my $log = $self->log;

  # Receive message
  $self->on('json' => sub {
    my ($self, $json) = @_;
    if ($json->{open}) {
      $log->info('open: '
          . $self->{tx}->remote_address
          . ': local='
          . $json->{open}{local}
          . ', remote='
          . $json->{open}{remote});

      # 同一IDが存在するときは古い方を削除
      @connections = grep {
        !(   $_->{local} eq $json->{open}{local}
          && $_->{remote} eq $json->{open}{remote})
      } @connections;

      # 接続情報を保存
      push(
        @connections,
        {
          local  => $json->{open}{local},
          remote => $json->{open}{remote},
          ws     => $self
        }
      );
      foreach my $data (@connections) {
        if ($data->{local} eq $json->{open}{remote}) {

          # 両方が接続済の場合にstartを通知
          $data->{ws}->send(encode_json({start => 'answer'}));
          $self->send(encode_json({start => 'offer'}));
          last;
        }
      }
      return;
    }

    # 対向の接続を検索
    foreach my $data (@connections) {
      if ($data->{local} eq $json->{remote}) {

        # シグナリングメッセージの転送
        $data->{ws}->send(encode_json($json));
        last;
      }
    }
  });
  
  # Finish
  $self->on('finish' => sub {
    @connections = grep {
      if ($_->{ws} != $self) { 1; }
      else {
        foreach my $remoteData (@connections) {
          if ($remoteData->{local} eq $_->{remote}) {

            # 対向に切断を通知
            $remoteData->{ws}->send(encode_json({close => 1}));
            last;
          }
        }
      }
    } @connections;
    $log->info('close: ' . $self->{tx}->remote_address);
  });
};

# 静的ファイル処理
get '/' => sub {
  my $self = shift;
  $self->reply->static('index.html');
};

app->start;

クライアント

index.htmlとwebrtc.jsは省略します。
(startVideoは一度しか呼ばれず、その前にwindow.streamは設定されないので、「既存のストリームを破棄」する必要はないのでは?と思います)

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?